Skip to content

my_unsigned_num.max(0) should warn #16555

@9999years

Description

@9999years

What it does

Code like this:

let dots = self.columns - prefix_width - hook_name.width() - suffix.width() - status_width;
let line = format!(
    "{prefix}{hook_name}{}{suffix}{status_line}",
    ".".repeat(dots.max(0)),
);

Can underflow: the computation for dots can go below 0, underflowing and causing a very large value of dots to be requested instead.

The authors knew about this, however, so they wrote ".".repeat(dots.max(0)). But dots is usize, so it can never be less than 0! Therefore dots.max(0) is a no-op and indicates a different bug (saturating subtraction wasn't used).

(This code is from prek but the issue is common across all languages.)

Note that the dots binding is not type-annotated, so it's easy to miss (as a casual reader, or in a code review interface) that it's an unsigned type.

Advantage

When the user is told that calling my_unsigned_num.max(0) is a no-op, they will realize that they need to accomplish their goal of preventing negative values some other way.

Drawbacks

None.

Example

let my_vec = vec!["a"];
let my_num = my_vec.len();
my_num.max(0)

Could be written as:

let my_vec = vec!["a"];
let my_num = my_vec.len();
my_num

Comparison with existing lints

No existing lints, as far as I can tell.

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions