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 variants aren't considered to be const during const-evaluation #23898

Closed
pnkfelix opened this issue Mar 31, 2015 · 6 comments · Fixed by #41408
Closed

enum variants aren't considered to be const during const-evaluation #23898

pnkfelix opened this issue Mar 31, 2015 · 6 comments · Fixed by #41408
Labels
A-type-system Area: Type system P-medium Medium priority

Comments

@pnkfelix
Copy link
Member

Spawned off of #5873

use self::Category::*;

enum Category {
    A,
    B,
    C,
    NumCategories,
}
const NUM_CATEGORIES: usize = NumCategories as usize;

fn main() {
    let the_categories: [Category; NUM_CATEGORIES] = [A, B, C];
    println!("{:?}", the_categories);
}

playpen

<anon>:9:31: 9:44 error: array length constant evaluation error: non-constant path in constant expr [E0250]
<anon>:9 const NUM_CATEGORIES: usize = NumCategories as usize;
                                       ^~~~~~~~~~~~~
<anon>:12:25: 12:51 note: for array length here
<anon>:12     let the_categories: [Category; NUM_CATEGORIES] = [A, B, C];
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
@pnkfelix
Copy link
Member Author

(copied labels from #5873.)

@pnkfelix
Copy link
Member Author

cc @doy @catamorphism @huonw @tikue @jdm @flaper87@nikomatsakis @jaredly @frewsxcv @tommit

(all of the above were commenters on the original ticket, and thus I assume they may be interested in following its progress here.)

andersk added a commit to andersk/enum_primitive-rs that referenced this issue Apr 8, 2015
rustc doesn’t yet realize that enum variants without explicit
discriminators are constant enough to be used as patterns in a match
statement (rust-lang/rust#23898).

This happens to be what #[derive(FromPrimitive)] does, anyway.

Signed-off-by: Anders Kaseorg <[email protected]>
@pmarcelll
Copy link
Contributor

This also seems to affect const fn.

@iirelu
Copy link
Contributor

iirelu commented Sep 30, 2016

Would like to throw in my pennies and say that this makes doing a 1:1 port of C code into Rust (an otherwise relatively easy process) slightly annoying when the C code in question uses this trick. I have to calculate the length of the enum, define that as a const of the same name, and update it every time to the enum changes.

@shepmaster
Copy link
Member

For what it's worth, this does "work" in Rust 1.14 if you give values to the variants:

use self::Category::*;

#[derive(Debug)]
enum Category {
    A = 0,
    B = 1,
    C = 2,
    NumCategories = 3,
}
const NUM_CATEGORIES: usize = NumCategories as usize;

fn main() {
    let the_categories: [Category; NUM_CATEGORIES] = [A, B, C];
    println!("{:?}", the_categories);
}

However, it continues to fail if you cross the crate boundary (an example is available in #38875)

@shepmaster
Copy link
Member

It does seem odd and less-than-intuitive that implicit values and explicit values are treated differently, and that intra-crate and inter-crate are treated differently.

bors added a commit that referenced this issue Apr 23, 2017
rustc: generalize monomorphic_const_eval to polymorphic constants.

With the addition of `Substs` to the query key, we can now evaluate *and cache* polymorphic constants.

Fixes #23898 by replacing the crippled explicit-discriminant-only local-crate-only `lookup_variant_by_id` with `ConstVal::Variant` which can describe variants irrespective of their discriminant.

Fixes #41394 by fixing #23898 (for the original testcase) and by not looping past the first discriminant.
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 P-medium Medium priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants