You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
structFoo<'a,T>(&'aT);impl<'a,T>Foo<'a,T>{constX:usize = 100;fnwhat(){let a = [0;Self::X];}}
I expected to see this happen: There should not be an error, the constant should have been evaluated as a literal. Using a literal does not raise the error.
Instead, this happened: Compile time error stating there is a lifetime issue. It requests a bound that shouldn't be neccessary. The error is misleading.
Meta
The bug occurs in my version and the latest stable.
Compiling playground v0.0.1 (/playground)
error[E0309]: the parameter type `T` may not live long enough
--> src/lib.rs:7:21
|
3 | impl<'a, T> Foo<'a, T> {
| -- the parameter type `T` must be valid for the lifetime `'a` as defined here...
...
7 | let a = [0; Self::X];
| ^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
3 | impl<'a, T: 'a> Foo<'a, T> {
| ++++
For more information about this error, try `rustc --explain E0309`.
error: could not compile `playground` (lib) due to 1 previous error
This is confusing but I don't think it is a bug, I am sure there is an open issue for it somewhere...
Maybe we could improve the diagnostics at least to explain "so that the type T will meet its required lifetime bounds" (what required lifetime bounds?).
Right, but that's immaterial. It's not super relevant if the implied bound stems from an inferred or explicit outlives-bound (check_inferred_predicates vs. check_explicit_predicates). With implied bounds from impl header I'm referring to the implicit T: 'a inferred from the impl self type Foo<'a, T>. inferred_outlives_of(`Foo`) will contain T: 'a no matter what (&'a T implies T: 'a and so does <T: 'a>).
OTOH, turning the implied bound into an explicit bound in the impl header (as opposed to updating Foo's definition) does make a difference for obvious reasons:
I'm not sure if that really makes sense usage wise, shouldn't a constant have a static lifetime anyway?
Nope, associated constants can have non-static lifetimes. Not the actual value/data I guess but you must still satisfy all lifetime outlives-bounds when referencing the associated item. I'm not entirely sure but I think that modifying the type system to allow lifetime-widening for Ty::<'a>::C from type &'a str to &'static str in fn f<'a>() { … } where impl<'a> Ty<'a> { const C: &'a str = ""; } can indirectly lead to unsoundness by allowing you to write a program that tricks rustc into accepting a general fn transmute<'a>(&'a str) -> &'static str via a series of intermediate stops (involving associated types and traits I assume). Then again, I could be totally wrong.
Activity
tgross35 commentedon Jul 18, 2024
Error
Playground https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=200ea30e9ca44266eca4d5aba898794f
tgross35 commentedon Jul 18, 2024
This is confusing but I don't think it is a bug, I am sure there is an open issue for it somewhere...
Maybe we could improve the diagnostics at least to explain "so that the type
Twill meet its required lifetime bounds" (what required lifetime bounds?).fmease commentedon Jul 18, 2024
Pretty sure the underlying bug is #105495 (implied bounds from impl header are not used when checking assoc items for well-formedness)
estebank commentedon Jul 23, 2024
Note that explicit bounds in the type are also not accounted for in the
impl.fmease commentedon Jul 23, 2024
Right, but that's immaterial. It's not super relevant if the implied bound stems from an inferred or explicit outlives-bound (
check_inferred_predicatesvs.check_explicit_predicates). With implied bounds from impl header I'm referring to the implicitT: 'ainferred from the impl self typeFoo<'a, T>.inferred_outlives_of(`Foo`)will containT: 'ano matter what (&'a TimpliesT: 'aand so does<T: 'a>).fmease commentedon Jul 23, 2024
OTOH, turning the implied bound into an explicit bound in the impl header (as opposed to updating
Foo's definition) does make a difference for obvious reasons:x4exr commentedon Jul 23, 2024
I'm not sure if that really makes sense usage wise, shouldn't a constant have a static lifetime anyway?
fmease commentedon Dec 29, 2024
Nope, associated constants can have non-static lifetimes. Not the actual value/data I guess but you must still satisfy all lifetime outlives-bounds when referencing the associated item. I'm not entirely sure but I think that modifying the type system to allow lifetime-widening for
Ty::<'a>::Cfrom type&'a strto&'static strinfn f<'a>() { … }whereimpl<'a> Ty<'a> { const C: &'a str = ""; }can indirectly lead to unsoundness by allowing you to write a program that tricks rustc into accepting a generalfn transmute<'a>(&'a str) -> &'static strvia a series of intermediate stops (involving associated types and traits I assume). Then again, I could be totally wrong.fmease commentedon Dec 29, 2024
Anyway, I found an older issue that reports the very same issue. Closing in favor of that.