From b62eeb2aac970a6728f6f2481ca704f0dae3b927 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 1 Sep 2023 07:23:14 +0000 Subject: [PATCH] Fall through when resolving elided assoc const lifetimes --- compiler/rustc_resolve/src/late.rs | 63 +++++++++---------- tests/ui/associated-consts/double-elided.rs | 12 ++++ .../ui/associated-consts/double-elided.stderr | 47 ++++++++++++++ 3 files changed, 88 insertions(+), 34 deletions(-) create mode 100644 tests/ui/associated-consts/double-elided.rs create mode 100644 tests/ui/associated-consts/double-elided.stderr diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index fa04a59455518..486d60eab2101 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -313,7 +313,7 @@ enum LifetimeRibKind { /// Resolves elided lifetimes to `'static`, but gives a warning that this behavior /// is a bug and will be reverted soon. - AnonymousWarnToStatic(NodeId), + AnonymousWarn(NodeId), /// Signal we cannot find which should be the anonymous lifetime. ElisionFailure, @@ -1154,7 +1154,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, } LifetimeRibKind::AnonymousCreateParameter { .. } | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::AnonymousWarnToStatic(_) + | LifetimeRibKind::AnonymousWarn(_) | LifetimeRibKind::Elided(_) | LifetimeRibKind::ElisionFailure | LifetimeRibKind::ConcreteAnonConst(_) @@ -1522,7 +1522,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // lifetime would be illegal. LifetimeRibKind::Item | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::AnonymousWarnToStatic(_) + | LifetimeRibKind::AnonymousWarn(_) | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many), // An anonymous lifetime is legal here, and bound to the right // place, go ahead. @@ -1585,7 +1585,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { | LifetimeRibKind::Generics { .. } | LifetimeRibKind::ElisionFailure | 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); return; } - LifetimeRibKind::AnonymousWarnToStatic(node_id) => { - self.record_lifetime_res(lifetime.id, LifetimeRes::Static, elision_candidate); + LifetimeRibKind::AnonymousWarn(node_id) => { let msg = if elided { "`&` without an explicit lifetime name cannot be used here" } else { @@ -1642,7 +1641,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { span: lifetime.ident.span, }, ); - return; } LifetimeRibKind::AnonymousReportError => { 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 // note lack of '_ // async fn foo(_: std::cell::Ref) { ... } LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. } - | LifetimeRibKind::AnonymousWarnToStatic(_) => { + | LifetimeRibKind::AnonymousWarn(_) => { let sess = self.r.tcx.sess; let mut err = rustc_errors::struct_span_err!( sess, @@ -2936,33 +2934,30 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { kind: LifetimeBinderKind::ConstItem, }, |this| { - this.with_lifetime_rib( - LifetimeRibKind::AnonymousWarnToStatic(item.id), - |this| { - // If this is a trait impl, ensure the const - // exists in trait - this.check_trait_item( - item.id, - item.ident, - &item.kind, - ValueNS, - item.span, - seen_trait_items, - |i, s, c| ConstNotMemberOfTrait(i, s, c), - ); + this.with_lifetime_rib(LifetimeRibKind::AnonymousWarn(item.id), |this| { + // If this is a trait impl, ensure the const + // exists in trait + this.check_trait_item( + item.id, + item.ident, + &item.kind, + ValueNS, + item.span, + seen_trait_items, + |i, s, c| ConstNotMemberOfTrait(i, s, c), + ); - this.visit_generics(generics); - this.visit_ty(ty); - if let Some(expr) = expr { - // We allow arbitrary const expressions inside of associated consts, - // even if they are potentially not const evaluatable. - // - // Type parameters can already be used and as associated consts are - // not used as part of the type system, this is far less surprising. - this.resolve_const_body(expr, None); - } - }, - ); + this.visit_generics(generics); + this.visit_ty(ty); + if let Some(expr) = expr { + // We allow arbitrary const expressions inside of associated consts, + // even if they are potentially not const evaluatable. + // + // Type parameters can already be used and as associated consts are + // not used as part of the type system, this is far less surprising. + this.resolve_const_body(expr, None); + } + }); }, ); } diff --git a/tests/ui/associated-consts/double-elided.rs b/tests/ui/associated-consts/double-elided.rs new file mode 100644 index 0000000000000..fd0317781bb15 --- /dev/null +++ b/tests/ui/associated-consts/double-elided.rs @@ -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() {} diff --git a/tests/ui/associated-consts/double-elided.stderr b/tests/ui/associated-consts/double-elided.stderr new file mode 100644 index 0000000000000..ba4e6a23e27e6 --- /dev/null +++ b/tests/ui/associated-consts/double-elided.stderr @@ -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 + = 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 +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`.