Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing some warnings about "literal out of range for its type" #14165

Closed
ghost opened this issue May 13, 2014 · 7 comments
Closed

Missing some warnings about "literal out of range for its type" #14165

ghost opened this issue May 13, 2014 · 7 comments
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut.

Comments

@ghost
Copy link

ghost commented May 13, 2014

The places I'd expect to get warnings are indicated by the comments in this example:

fn main() {
    let a: u8 = 1000;
    let b = 1000u8;
    let c = 1000 as u8; // NO WARNING !!!

    let one: u8 = 1;
    let d = (one * 1000) as u32;
    let e = (one *   -1) as u32; // NO WARNING !!!
    let f = (one * -255) as u32; // NO WARNING !!!
    let g = (one * -256) as u32;

    println!("{}, {}, {}, {}, {}, {}, {}", a, b, c, d, e, f, g);
}

Here's the compiler output:

warning: literal out of range for its type, #[warn(type_overflow)] on by default
let a: u8 = 1000;
            ^~~~
warning: literal out of range for its type, #[warn(type_overflow)] on by default
let b = 1000u8;
        ^~~~~~
warning: literal out of range for its type, #[warn(type_overflow)] on by default
let d = (one * 1000) as u32;
               ^~~~
warning: literal out of range for its type, #[warn(type_overflow)] on by default
let g = (one * -256) as u32;
                ^~~

And here's the program output:
232, 232, 232, 232, 255, 1, 0

@huonw huonw added the A-lint label May 13, 2014
@lilyball
Copy link
Contributor

-1u8 produces an unsigned_negate warning, not a type_overflow warning. Consequently, (one * -1) is correct in not producing a type_overflow warning.

This same logic applies to (one * -255) as well. 255 is in range for its type, so it doesn't get a type_overflow warning.

It is arguable as to whether these cases should produce an unsigned_negate warning.

@ghost
Copy link
Author

ghost commented May 20, 2014

But unsigned_negate warning reads as "warning: negation of unsigned int literal may be unintentional". But these following cases which I'm requesting a warning for, do not fall into that category:

let x: u8 = -1;
let y = -1 as u8;
let z = (42u8 * -1) as int;

An appropriate warning for those would be something like "warning: casting a negative literal to an unsigned type".

And this following case in my original post should clearly cause a type_overflow warning:

let c = 1000 as u8;

...given that the following does:

let b = 1000u8;

@lilyball
Copy link
Contributor

Saying ### as u8 should never produce a warning. That's an explicit cast, which means you're opting in to overflow behavior.

Which is to say, -12u is likely to be unintentional, and the warning calls it out. -12 as uint is very much intentional. And in fact, if you get an unsigned_negate warning, the easiest way to fix it if it was intentional is to convert it to an as cast.

Same thing with 1000 as u8. That right there is explicitly asking for the results of casting 1000 to a u8 type. The warning has a too-high probability of being a false positive.

@ghost
Copy link
Author

ghost commented May 21, 2014

I suppose let x: u8 = -1; is also considered an explicit cast then, and thus exempt from any warning?

But the following is clearly an implicit cast, and thus should warrant a warning:

1u8 * -1

And the warning shouldn't be the unsigned_negate one, because we're not negating an unsigned literal here but casting from a negative literal of an unspecified integral type to an unsigned type u8.

@lilyball
Copy link
Contributor

let x: u8 = -1 feels more like an oversight to me, but I suspect it's actually a deliberate omission because it ends up being the exact same thing as 1u8 * -1. In both cases, the -1 is an unsuffixed integer literal, which is subsequently constraint to the u8 type.

Of course, I can only speculate. I didn't implement the lint. But my feeling is that -1u8 is obviously weird and a lint on it is wholly unsurprising, but 1u8 * -1 is not so obviously weird, and flagging it with a lint may be more surprising (and have more false positives).

@hirschenberger
Copy link
Contributor

Hi, I wrote the lint for the unsigned negation and wanted to catch the obvious cases negating unsigned literals. A related issue to the case @tommit mentioned is #5477.
The question is where we should draw the line between intentional and unintentional behaviour being helpful without annoying users?

@huonw
Copy link
Member

huonw commented Jan 13, 2015

Duplicate of #5477.

@huonw huonw closed this as completed Jan 13, 2015
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 20, 2023
internal: Make CompletionItem more POD-like
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut.
Projects
None yet
Development

No branches or pull requests

3 participants