-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Can't assign results of generic functions to const
variables
#57775
Comments
Well, what's intended here is that you're not allowed to use type parameters of an enclosing item in an inner item. |
Yep; @jonas-schievink is correct. Rust does not support what is referred to in Haskell as ScopedTypeVariables. Moreover, even if you could use the type parameter cc @estebank re. possible improvements to diagnostics. cc #57563. |
We need to stop suggesting adding a type argument when the requirement comes from a |
From #48427, the same behavior is seen for
|
Is there any news about this issue? Is it included in any roadmap? Can I do something to speed up its implementation? fn x<T: Default>() {
static a: T = T::default();
} Thanks. |
There has been no movement in supporting this at the lang level, and the diagnostic could do with some love to be clearer. |
I also ran into this issue when I tried to do some compile-time assertions based on generic parameters from outer function. fn foo<T>() {
// can't use generic parameters from outer function:
// const ASSERT: () = assert!(mem::size_of::<T>() == 8);
let _ = Assert::<T>::SIZE_EQ_8;
}
struct Assert<T> {
_marker: PhantomData<T>,
}
impl<T> Assert<T> {
const SIZE_EQ_8: () = assert!(mem::size_of::<T>() == 8);
} |
I can confirm that sometimes it leads to very strange compilation errors. This code compiles fine: use core::marker::PhantomData;
struct A<T>(PhantomData<T>);
impl<T> A<T> {
const EMPTY: Vec<T> = Vec::new();
fn f() -> [Vec<T>; 2] {
[Self::EMPTY; 2]
}
}
fn main() {
let empty = A::<u32>::f();
dbg!(empty);
} while this does not: fn f<U>() -> [Vec<U>; 2] {
const EMPTY: Vec<U> = Vec::new();
[EMPTY; 2]
}
fn main() {
let empty = f::<u32>();
dbg!(empty);
} |
@Ternvein, that is expected. While free constant items may not reference the generics of the outer item, associated constant items are allowed to reference the generics of their direct parent (i.e., trait, trait impl or impl). |
gives the following error (twice for some reason):
Changing let to
const
tolet
makes it compile just fine.Another, slightly different example:
Here, the type of the variable is non-generic now, and it's only a function that is. Results in the same error, but only once now:
P.s.: if this is the desired behavior, it is confusing, since 1) changing
const
tolet
should not result in type error, 2)rustc --explain E0401
doesn't mention anything close - all the examples are about definition of new functions/types inside the function body (and it's unclear how to adapt that knowledge to this particular use case).P.p.s.: the behavior is exactly the same on current stable (1.32.0)
The text was updated successfully, but these errors were encountered: