-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Using constants at compile time to define vector lengths #3469
Comments
It's an incompleteness, a bug. We're intending to support integer constant expressions in that context eventually. I'd pull up the github issue associated with it but their search engine fell over yesterday and still doesn't have indices back online. Will check again next time around. |
It would also be swell to allow values like enum discriminants, which would allow things like
|
Regarding the enum trick, I'd prefer to have some way of getting the max discriminant of an enum. I do this trick of adding an extra value in C all the time but it's annoying because it foils exhaustiveness checks. |
So I have a patch that addresses this, problem is that it only half works. Simple constant expressions like |
It looks the astconv stuff might happen in the collect pass, which directly precedes the resolve pass which does record information about constants in def_map. |
So trying to avoid the const_eval in astconv by propagating
|
Thanks to some help from pcwalton, I have this working properly now. |
@pcwalton @graydon regarding the set of expressions that can be included in constants, I think there are issues around field projection and the like because we need to evaluate constants during the "collect" of type checking. That is, type checking first iterates over all struct declarations and converts them into types. It then descends into function bodies and expressions to check those. The tricky part here is that checking a function body / expression requires the types for the struct declarations and so forth. In particular, imagine we have to type check something like Basically this means that either the code that type checks expressions will have to be parameterized over what phase it is operating in (hard and annoying but not impossible), or else we will wind up having to duplicate the code that type checks constants so that when we are evaluating constants to compute the final types we don't require that type conversion has taken place. Thus far we have taken the duplication path. If you look in If we are duplicating, it makes sense from a practical perspective to duplicate as little as possible. Duplicating integer arithmetic and so on seems pretty straightforward. I am not sure though if there is a theoretical reason that we can't handle more complex expressions, but the logic involved is fairly complex (think autoderef etc). It is not really clear to me when it is necessary to have field projection ( Does this make sense? |
So this is a partial fix for #3469. Partial because it only works for simple constant expressions like `32/2` and `2+2` and not for any actual constants. For example: ``` const FOO: uint = 2+2; let v: [int * FOO]; ``` results in: ``` error: expected constant expr for vector length: Non-constant path in constant expr ``` This seems to be because at the point of error (`typeck::astconv`) the def_map doesn't contain the constant and thus it can't lookup the actual expression (`2+2` in this case). So, feedback on what I have so far and suggestions for how to address the constant issue?
The original issue as described was resolved by #5112. There appears to be some remaining questions of how expressive we should allow constant expressions to be, but I do not think this ticket is a good place for such discussion to continue; closing. |
Fix cargo fmt inconsistency
I'm trying to use a constant at compile time to define the length of some vectors:
(code from glfw3-rs)
I get this error:
Is this a bug or by design?
The text was updated successfully, but these errors were encountered: