Fall through when resolving elided assoc const lifetimes
This commit is contained in:
parent
88d9b37a15
commit
b62eeb2aac
3 changed files with 88 additions and 34 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
12
tests/ui/associated-consts/double-elided.rs
Normal file
12
tests/ui/associated-consts/double-elided.rs
Normal 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() {}
|
47
tests/ui/associated-consts/double-elided.stderr
Normal file
47
tests/ui/associated-consts/double-elided.stderr
Normal 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`.
|
Loading…
Add table
Add a link
Reference in a new issue