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

associated-constants can not be used in constant expressions #34344

Closed
MaikKlein opened this issue Jun 18, 2016 · 22 comments
Closed

associated-constants can not be used in constant expressions #34344

MaikKlein opened this issue Jun 18, 2016 · 22 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. C-bug Category: This is a bug.

Comments

@MaikKlein
Copy link
Contributor

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.

@steveklabnik steveklabnik added the A-associated-items Area: Associated items (types, constants & functions) label Jun 19, 2016
@Aatch
Copy link
Contributor

Aatch commented Jun 21, 2016

It should be allowed in the long run. It just requires some significant changes to how we handle both type-checking and constant evaluation.

@crumblingstatue
Copy link
Contributor

I think this should be resolved before associated consts get stabilized.
Ref #29646

@burdges
Copy link

burdges commented Oct 18, 2016

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

@nwin
Copy link
Contributor

nwin commented Oct 21, 2016

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

@raphaelcohn
Copy link

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.

@gnzlbg
Copy link
Contributor

gnzlbg commented Nov 10, 2016

I would like to fix this, would anybody be able to mentor me on it?

@przygienda
Copy link

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 (4ecc85b 2016-12-28)

it works if the mod is in same file?

https://is.gd/eKVLJR

@tforgione
Copy link

tforgione commented Feb 23, 2017

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.

@withoutboats
Copy link
Contributor

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.

@nwin
Copy link
Contributor

nwin commented Mar 31, 2017

Which is essential identical with my example which doesn’t compile as well, at least the error message changed. to

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

Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue May 13, 2017
…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).
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue May 14, 2017
…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).
@Mark-Simulacrum Mark-Simulacrum added the A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. label Jun 20, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 25, 2017
@RalfJung
Copy link
Member

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...

@steveklabnik
Copy link
Member

This now compiles, closing!

@vitalyd
Copy link

vitalyd commented Aug 29, 2017

@steveklabnik, what compiles? Associated consts in arrays still don't work.

@steveklabnik
Copy link
Member

The example in the OP.

@vitalyd
Copy link

vitalyd commented Aug 29, 2017

Ah I thought you were referring to @RalfJung example right above, along with similar ones in this issue, which doesn't compile.

@steveklabnik
Copy link
Member

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

@vitalyd
Copy link

vitalyd commented Aug 29, 2017

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.

@gnzlbg
Copy link
Contributor

gnzlbg commented Aug 30, 2017

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.

@RalfJung
Copy link
Member

RalfJung commented Sep 1, 2017

I opened a new issue for the incorrect error at #44243.

@U007D
Copy link

U007D commented Mar 8, 2018

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?

@gnzlbg
Copy link
Contributor

gnzlbg commented Mar 8, 2018

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

This is by design. Associated constants are not const generics.

@U007D
Copy link

U007D commented Mar 8, 2018

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests