Rust: associated-constants can not be used in constant expressions

Created on 18 Jun 2016  路  22Comments  路  Source: rust-lang/rust

https://doc.rust-lang.org/book/associated-constants.html

#![feature(associated_consts)]

trait Foo {
    const ID: usize;
}

impl Foo for i32 {
    const ID: usize = 1;
}
fn main() {
    let arr: [i32; i32::ID];
}

https://is.gd/L4Fg4k

array length constant evaluation error: non-constant path in constant expression

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.

A-associated-items A-const-fn C-bug

Most helpful comment

I think this should be resolved before associated consts get stabilized.
Ref https://github.com/rust-lang/rust/issues/29646

All 22 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.
Ref https://github.com/rust-lang/rust/issues/29646

I've run into this problem as well. It creates minor issues with working around the larger limits discussed in https://github.com/rust-lang/rfcs/issues/1772

Maybe related:

#![feature(associated_consts)]

pub trait ArrayTrait {
    const LENGTH: usize;
    fn get_array() -> [i32; Self::LENGTH];
}

https://is.gd/a1qsuL

unresolved path in constant expression

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
rustc 1.16.0-nightly (4ecc85beb 2016-12-28)

it works if the mod is in same file?

https://is.gd/eKVLJR

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.

$ rustc --version
rustc 1.17.0-nightly (956e2bcba 2017-02-12)

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鈥檛 compile as well, at least the error message changed. to

error[E0402]: cannot use an outer type parameter in this context

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 https://github.com/rust-lang/rust/issues/44243.

In doing some embedded work using traits, I ran into an issue with associated constants which do not seem to work as the N in [T; N]: https://play.rust-lang.org/?gist=c7f999d864cc995d36584aa595641dce&version=stable

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?

I ran into an issue with associated constants which do not seem to work

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.

Was this page helpful?
0 / 5 - 0 ratings