-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
associated-constants can not be used in constant expressions #34344
Comments
It should be allowed in the long run. It just requires some significant changes to how we handle both type-checking and constant evaluation. |
I think this should be resolved before associated consts get stabilized. |
I've run into this problem as well. It creates minor issues with working around the larger limits discussed in rust-lang/rfcs#1772 |
Maybe related: #![feature(associated_consts)]
pub trait ArrayTrait {
const LENGTH: usize;
fn get_array() -> [i32; Self::LENGTH];
}
|
It's actually very irritating, and make associated consts in traits of limited value. For example, I need to model 4 different fixed large arrays of data that represent hash distributions. These are modelled as a trait. A consumer function trying to then use the size in a derived constant can't. (in this case, to compute a bit pattern from a size). It also means that one can't scope constants correctly (eg @nwin) and so rely on fallbacks to global constants. Yuck. |
I would like to fix this, would anybody be able to mentor me on it? |
Another problem currently is that if e.g. an associated constant is implemented on an enum and the enum imported in another module, the constant is invisible (today's nightly) prz-mbp:mini_igp prz$ rustc --version it works if the mod is in same file? |
Furthermore, if you try to make generics with associated constants, it'll crash the compiler : #![feature(associated_consts)]
trait Size {
const size: usize;
}
struct One;
impl Size for One {
const size: usize = 1;
}
struct MyArray<T: Size> {
data: [i32; T::size],
}
fn main() { } crashes with this error.
Hope this can help. |
Status update: The example in the original post compiles today; as long as the type the associated const is associated with is a concrete type, this works. The example that @tforgione posted, in which the const is associated with a type parameter returns an error today. |
Which is essential identical with my example which doesn’t compile as well, at least the error message changed. to
|
…petrochenkov rustc_resolve: don't deny outer type parameters in embedded constants. This solves a problem noted at rust-lang#29646 (comment), where an associated const default in a trait couldn't refer to `Self` or type parameters, due to inaccuracies in lexical scoping. I've also allowed "embedded expressions" (`[T; expr]`, `[x; expr]`, `typeof expr`) to refer to type parameters in scope. *However*, the typesystem still doesn't handle rust-lang#34344. Fully resolving that issue requires breaking cycles more aggressively (e.g. lazy evaluation), *even* in when the expression doesn't depend on type parameters, to type-check it at all, and then also type-level "constant projections" (in the vein of `{expr}` from const generics).
…petrochenkov rustc_resolve: don't deny outer type parameters in embedded constants. This solves a problem noted at rust-lang#29646 (comment), where an associated const default in a trait couldn't refer to `Self` or type parameters, due to inaccuracies in lexical scoping. I've also allowed "embedded expressions" (`[T; expr]`, `[x; expr]`, `typeof expr`) to refer to type parameters in scope. *However*, the typesystem still doesn't handle rust-lang#34344. Fully resolving that issue requires breaking cycles more aggressively (e.g. lazy evaluation), *even* in when the expression doesn't depend on type parameters, to type-check it at all, and then also type-level "constant projections" (in the vein of `{expr}` from const generics).
In some cases the error message shown is pretty confusing and leaves the user in the air about what's going on: trait VecN {
const DIM: usize;
}
trait Mat {
type Row: VecN;
}
fn m<M: Mat>() {
let a = [3; M::Row::DIM]; //~ ERROR associated type `Row` not found for `M`
}
fn main() {
} The associated type actually exists. So I started at this a while, wondering whether I just stopped knowing how to read... |
This now compiles, closing! |
@steveklabnik, what compiles? Associated consts in arrays still don't work. |
The example in the OP. |
Ah I thought you were referring to @RalfJung example right above, along with similar ones in this issue, which doesn't compile. |
If this should be re-opened thanks to those ones, then yeah, let's re-open it. I just knew the OP's code compiled |
Well I've seen this issue linked in various places when pointing people at the problem. But if there's a more appropriate "master" issue then I don't see the point in keeping extra appendage ones open (as long as they link to the right one). Your call. |
I think we should fill a different issue to improve the error message that @RalfJung mentions. Associated consts work in constant expressions today, what doesn't work is using them from a type parameter in type position IIRC. Fixing this is not part of the original example, and we should track that in a separate issue as well. |
I opened a new issue for the incorrect error at #44243. |
In doing some embedded work using traits, I ran into an issue with associated constants which do not seem to work as the It looks like the problem may be because the trait does not define a value for the associated constant (this is by design), so I'm not sure if this falls under "associated constants cannot be used in constant expressions" or something else. Note this issue is distinct from the "incorrect error message" issue--I would like to see this compile as valid Rust. Does anyone know if this is already being tracked somewhere (I've not been able to find it), or should I open a new issue? |
This is by design. Associated constants are not const generics. |
@gnzlbg ah, I had not heard of const generics before. In reading through the RFC's solution I am reminded that my ideal solution is an associated solution rather than a generic solution or as defaulted const generics (which is not in the RFC). For others, who may come across this thread, it does look like this issue is being addressed here using generics. |
https://doc.rust-lang.org/book/associated-constants.html
https://is.gd/L4Fg4k
I had a quick look at the rfc but I couldn't find out if it should be legal to use associated-constants in constant expressions.
The text was updated successfully, but these errors were encountered: