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

enum discriminants have problems with const_eval and truncation #9837

Closed
jld opened this issue Oct 13, 2013 · 13 comments
Closed

enum discriminants have problems with const_eval and truncation #9837

jld opened this issue Oct 13, 2013 · 13 comments
Labels
A-type-system Area: Type system

Comments

@jld
Copy link
Contributor

jld commented Oct 13, 2013

static S: i16 = 0x12345678;
enum E { V = S }
fn main() { assert_eq!(S as u64, V as u64); }

Result:

task '<unnamed>' failed at 'assertion failed: `(left == right) && (right == left)` (left: `22136u64`, right: `305419896u64`)', testcase.rs:3`

Currently blocking #9613, because 32-bit std::int::min_value is 0xffffffff7fffffff (if you use all the bits of the const_eval result and not just the low 32) and so the discriminant is auto-sized to u64, meaning that 0x7fffffff does not match any of its variants.

I'm thinking that check_enum_variants needs to do whatever const_eval would do if the expression had an as u64 around it.

@jld
Copy link
Contributor Author

jld commented Oct 13, 2013

One possibility: if we can read out the type inferred by check_const_with_ty and truncate based on it, that might be helpful if we want to do something about #8761.

@steveklabnik
Copy link
Member

Visiting for triage, the above example no longer compiles:

hello.rs:4:14: 4:15 error: mismatched types: expected `int` but found `i16` (expected int but found i16)
hello.rs:4 enum E { V = S }
                        ^
error: aborting due to previous error

I'm not familiar enough with the details to be able to come up with a newer example.

@steveklabnik
Copy link
Member

Triage: wow, I used to be a noob :)

static S: isize = 0x12345678;

enum E { V = S }

fn main() { assert_eq!(S as u64, E::V as u64); }

This now error swith:

hello.rs:3:14: 3:15 error: expected constant: non-constant path in constant expr [E0080]
hello.rs:3 enum E { V = S }
                        ^

So it seems like this is still an issue?

@steveklabnik steveklabnik added the A-type-system Area: Type system label Jan 23, 2015
@steveklabnik
Copy link
Member

marking as 'typesystem' because it would seem like a const should be usable here.

@jld
Copy link
Contributor Author

jld commented Jan 26, 2015

I thought the enum stuff used const_eval, and that ought to work on consts/statics, so I'm not sure why that's failing — might be worth filing as its own bug?

@ftxqxd
Copy link
Contributor

ftxqxd commented Jan 26, 2015

@steveklabnik That example uses a static, which isn’t a valid constant expression. The following is the closest I could get to the original example:

const S: i16 = 0x12345678;

enum E { V = S as isize }

fn main() { assert_eq!(S as u64, E::V as u64); }

And it still panics with the error in the original post (so this is still an issue).

@pnkfelix
Copy link
Member

cc #23897

@eefriedman
Copy link
Contributor

This is fixed in nightly.

@eefriedman
Copy link
Contributor

Err, wait, nevermind, wrong bug; sorry about the noise.

@oli-obk
Copy link
Contributor

oli-obk commented Dec 18, 2015

note that this has a warning now:

<anon>:1:16: 1:26 warning: literal out of range for i16, #[warn(overflowing_literals)] on by default
<anon>:1 const S: i16 = 0x12345678;

@jld
Copy link
Contributor Author

jld commented Dec 21, 2015

The warning definitely helps, but here's an interesting variation:

const C1: i32 = 0x12345678;
const C2: isize = C1 as i16 as isize;
enum E { V = C2 }
fn main() { assert_eq!(C2 as u64, E::V as u64); }

No warnings on stable or nightly, but still panics.

@pmarcelll
Copy link
Contributor

I cannot reproduce the panic on nightly.

frewsxcv added a commit to frewsxcv/rust that referenced this issue Sep 18, 2016
@frewsxcv
Copy link
Member

Added a regression test in #36566.

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Sep 23, 2016
flip1995 pushed a commit to flip1995/rust that referenced this issue Nov 21, 2022
fix never_loop false positive

fixes rust-lang#9831

changelog: [`never_loop`]: fixed false positive on unconditional break in internal labeled block
flip1995 pushed a commit to flip1995/rust that referenced this issue Nov 21, 2022
`never_loop`: don't emit AlwaysBreaks if it targets a block

ref: rust-lang/rust-clippy#9837 (comment)

The previous fix (rust-lang#9837) was too simple and ignored all break commands inside a labelled block, regardless of whether their destination was a labelled block or a loop. This fix tracks all the labelled blocks in scope to ensure that only breaks targeting loops are considered.

changelog: [`never_loop`]: prevent false negatives from `breaks` nested in labelled blocks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system
Projects
None yet
Development

No branches or pull requests

8 participants