Description
Expand the interpretation of rust-lang/rfcs#1623 "static_lifetime_in_statics" to include associated consts in traits and trait impls when there are no other lifetimes in scope. This means the following code will compile:
struct MyType;
impl MyType {
// Warns today (elided_lifetimes_in_associated_constant) but won't after this FCP
const FOO: &i32 = &4;
}
trait Trait {
// Errors today (missing lifetime specifier) but won't after this FCP
const BAR: &i32;
// You will also be able to provide a default:
// const BAR: &i32 = &1;
}
impl Trait for MyType {
// Warns today (elided_lifetimes_in_associated_constant) but won't after this FCP
const BAR: &i32 = Self::FOO;
}
However, if there are any lifetime parameters on the item declaration or const, we will continue to require an explicit choice of lifetime. We may revisit this decision in the future. Examples are listed in the appendix below.
Rationale: There is a high level of churn suggested by the backreferences to #115010. The primary intention of this FCP is to reduce the churn associated with this change. The lang team discussed #124211 and thought it would be good to decide on what we want in the most obvious (and common) cases, which should also reduce the level of churn significantly.
Appendix: Examples with lifetimes
struct MyType<'a>(PhantomData<&'a ()>);
impl<'a> MyType<'a> {
// Continues to warn (elided_lifetimes_in_associated_constant), may be a hard error later
const FOO: &i32 = &4;
}
trait Trait<'a> {
// Continues to error:
//const BAR: &i32;
// (but this is fine)
const BAR: &'a i32;
}
impl Trait<'static> for i32 {
// Okay, because there are no lifetime parameters on this item.
// If the trait lifetime were not 'static, you would still get a
// "const not compatible with trait" error.
const BAR: &i32 = &42;
}
impl<'a> Trait<'static> for MyType<'a> {
// Continues to warn (elided_lifetimes_in_associated_constant), may be a hard error later
const BAR: &i32 = Self::FOO;
}
struct Thing;
impl Thing {
// Nightly-only feature, but would also error in this case because of
// the lifetime parameter on the const impl item:
const FOO<'a>: &i32 = &4;
}
fn foo<'a>(_: &'a ()) {
impl Thing {
// Okay; the lifetime of the function cannot be named here,
// so it does not affect whether there is a default.
const BAZ: &i32 = &5;
}
}