1
Fork 0

Fall through when resolving elided assoc const lifetimes

This commit is contained in:
Michael Goulet 2023-09-01 07:23:14 +00:00
parent 88d9b37a15
commit b62eeb2aac
3 changed files with 88 additions and 34 deletions

View file

@ -313,7 +313,7 @@ enum LifetimeRibKind {
/// Resolves elided lifetimes to `'static`, but gives a warning that this behavior /// Resolves elided lifetimes to `'static`, but gives a warning that this behavior
/// is a bug and will be reverted soon. /// is a bug and will be reverted soon.
AnonymousWarnToStatic(NodeId), AnonymousWarn(NodeId),
/// Signal we cannot find which should be the anonymous lifetime. /// Signal we cannot find which should be the anonymous lifetime.
ElisionFailure, ElisionFailure,
@ -1154,7 +1154,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
} }
LifetimeRibKind::AnonymousCreateParameter { .. } LifetimeRibKind::AnonymousCreateParameter { .. }
| LifetimeRibKind::AnonymousReportError | LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::AnonymousWarnToStatic(_) | LifetimeRibKind::AnonymousWarn(_)
| LifetimeRibKind::Elided(_) | LifetimeRibKind::Elided(_)
| LifetimeRibKind::ElisionFailure | LifetimeRibKind::ElisionFailure
| LifetimeRibKind::ConcreteAnonConst(_) | LifetimeRibKind::ConcreteAnonConst(_)
@ -1522,7 +1522,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// lifetime would be illegal. // lifetime would be illegal.
LifetimeRibKind::Item LifetimeRibKind::Item
| LifetimeRibKind::AnonymousReportError | LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::AnonymousWarnToStatic(_) | LifetimeRibKind::AnonymousWarn(_)
| LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many), | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),
// An anonymous lifetime is legal here, and bound to the right // An anonymous lifetime is legal here, and bound to the right
// place, go ahead. // place, go ahead.
@ -1585,7 +1585,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
| LifetimeRibKind::Generics { .. } | LifetimeRibKind::Generics { .. }
| LifetimeRibKind::ElisionFailure | LifetimeRibKind::ElisionFailure
| LifetimeRibKind::AnonymousReportError | LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::AnonymousWarnToStatic(_) => {} | LifetimeRibKind::AnonymousWarn(_) => {}
} }
} }
@ -1625,8 +1625,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
self.record_lifetime_res(lifetime.id, res, elision_candidate); self.record_lifetime_res(lifetime.id, res, elision_candidate);
return; return;
} }
LifetimeRibKind::AnonymousWarnToStatic(node_id) => { LifetimeRibKind::AnonymousWarn(node_id) => {
self.record_lifetime_res(lifetime.id, LifetimeRes::Static, elision_candidate);
let msg = if elided { let msg = if elided {
"`&` without an explicit lifetime name cannot be used here" "`&` without an explicit lifetime name cannot be used here"
} else { } else {
@ -1642,7 +1641,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
span: lifetime.ident.span, span: lifetime.ident.span,
}, },
); );
return;
} }
LifetimeRibKind::AnonymousReportError => { LifetimeRibKind::AnonymousReportError => {
let (msg, note) = if elided { let (msg, note) = if elided {
@ -1840,7 +1838,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// impl Foo for std::cell::Ref<u32> // note lack of '_ // impl Foo for std::cell::Ref<u32> // note lack of '_
// async fn foo(_: std::cell::Ref<u32>) { ... } // async fn foo(_: std::cell::Ref<u32>) { ... }
LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. } LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
| LifetimeRibKind::AnonymousWarnToStatic(_) => { | LifetimeRibKind::AnonymousWarn(_) => {
let sess = self.r.tcx.sess; let sess = self.r.tcx.sess;
let mut err = rustc_errors::struct_span_err!( let mut err = rustc_errors::struct_span_err!(
sess, sess,
@ -2936,33 +2934,30 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
kind: LifetimeBinderKind::ConstItem, kind: LifetimeBinderKind::ConstItem,
}, },
|this| { |this| {
this.with_lifetime_rib( this.with_lifetime_rib(LifetimeRibKind::AnonymousWarn(item.id), |this| {
LifetimeRibKind::AnonymousWarnToStatic(item.id), // If this is a trait impl, ensure the const
|this| { // exists in trait
// If this is a trait impl, ensure the const this.check_trait_item(
// exists in trait item.id,
this.check_trait_item( item.ident,
item.id, &item.kind,
item.ident, ValueNS,
&item.kind, item.span,
ValueNS, seen_trait_items,
item.span, |i, s, c| ConstNotMemberOfTrait(i, s, c),
seen_trait_items, );
|i, s, c| ConstNotMemberOfTrait(i, s, c),
);
this.visit_generics(generics); this.visit_generics(generics);
this.visit_ty(ty); this.visit_ty(ty);
if let Some(expr) = expr { if let Some(expr) = expr {
// We allow arbitrary const expressions inside of associated consts, // We allow arbitrary const expressions inside of associated consts,
// even if they are potentially not const evaluatable. // even if they are potentially not const evaluatable.
// //
// Type parameters can already be used and as associated consts are // Type parameters can already be used and as associated consts are
// not used as part of the type system, this is far less surprising. // not used as part of the type system, this is far less surprising.
this.resolve_const_body(expr, None); this.resolve_const_body(expr, None);
} }
}, });
);
}, },
); );
} }

View file

@ -0,0 +1,12 @@
struct S;
impl S {
const C: &&str = &"";
//~^ WARN `&` without an explicit lifetime name cannot be used here
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| WARN `&` without an explicit lifetime name cannot be used here
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| ERROR in type `&&str`, reference has a longer lifetime than the data it references
}
fn main() {}

View file

@ -0,0 +1,47 @@
warning: `&` without an explicit lifetime name cannot be used here
--> $DIR/double-elided.rs:4:14
|
LL | const C: &&str = &"";
| ^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
= note: `#[warn(elided_lifetimes_in_associated_constant)]` on by default
help: use the `'static` lifetime
|
LL | const C: &'static &str = &"";
| +++++++
warning: `&` without an explicit lifetime name cannot be used here
--> $DIR/double-elided.rs:4:15
|
LL | const C: &&str = &"";
| ^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
help: use the `'static` lifetime
|
LL | const C: &&'static str = &"";
| +++++++
error[E0491]: in type `&&str`, reference has a longer lifetime than the data it references
--> $DIR/double-elided.rs:4:5
|
LL | const C: &&str = &"";
| ^^^^^^^^^^^^^^^^^^^^^
|
note: the pointer is valid for the anonymous lifetime as defined here
--> $DIR/double-elided.rs:4:14
|
LL | const C: &&str = &"";
| ^
note: but the referenced data is only valid for the anonymous lifetime as defined here
--> $DIR/double-elided.rs:4:14
|
LL | const C: &&str = &"";
| ^
error: aborting due to previous error; 2 warnings emitted
For more information about this error, try `rustc --explain E0491`.