From e9327f19f3b642e148ac7552d5425580d94b5252 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 13 Jun 2024 20:44:15 -0400 Subject: [PATCH] Resolve const lifetimes to static in trait too --- compiler/rustc_resolve/src/late.rs | 56 +++++++++++-------- .../elided-lifetime.rs | 3 +- .../elided-lifetime.stderr | 8 +-- .../generic-associated-const.rs | 1 - .../generic-associated-const.stderr | 15 +---- ...ifetime-in-assoc-const-type.default.stderr | 56 ++++--------------- ...ssoc-const-type.generic_const_items.stderr | 46 ++++----------- .../missing-lifetime-in-assoc-const-type.rs | 8 +-- 8 files changed, 69 insertions(+), 124 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 20926366ba5e8..f3c27ca857f05 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -312,8 +312,8 @@ enum LifetimeRibKind { /// Resolves elided lifetimes to `'static` if there are no other lifetimes in scope, /// otherwise give a warning that the previous behavior of introducing a new early-bound - /// lifetime is a bug and will be removed. - StaticIfNoLifetimeInScope(NodeId), + /// lifetime is a bug and will be removed (if `emit_lint` is enabled). + StaticIfNoLifetimeInScope { lint_id: NodeId, emit_lint: bool }, /// Signal we cannot find which should be the anonymous lifetime. ElisionFailure, @@ -1213,7 +1213,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, } LifetimeRibKind::AnonymousCreateParameter { .. } | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::StaticIfNoLifetimeInScope(_) + | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } | LifetimeRibKind::Elided(_) | LifetimeRibKind::ElisionFailure | LifetimeRibKind::ConcreteAnonConst(_) @@ -1581,7 +1581,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // lifetime would be illegal. LifetimeRibKind::Item | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::StaticIfNoLifetimeInScope(_) + | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many), // An anonymous lifetime is legal here, and bound to the right // place, go ahead. @@ -1644,7 +1644,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { | LifetimeRibKind::Generics { .. } | LifetimeRibKind::ElisionFailure | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::StaticIfNoLifetimeInScope(_) => {} + | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => {} } } @@ -1678,7 +1678,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { self.record_lifetime_res(lifetime.id, res, elision_candidate); return; } - LifetimeRibKind::StaticIfNoLifetimeInScope(node_id) => { + LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => { let mut lifetimes_in_scope = vec![]; for rib in &self.lifetime_ribs[..i] { lifetimes_in_scope.extend(rib.bindings.iter().map(|(ident, _)| ident.span)); @@ -1696,7 +1696,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { elision_candidate, ); return; - } else { + } else if emit_lint { self.r.lint_buffer.buffer_lint( lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, node_id, @@ -1925,7 +1925,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::StaticIfNoLifetimeInScope(_) => { + | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => { let sess = self.r.tcx.sess; let subdiag = rustc_errors::elided_lifetime_in_path_suggestion( sess.source_map(), @@ -2859,19 +2859,27 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { kind: LifetimeBinderKind::ConstItem, }, |this| { - this.visit_generics(generics); - this.visit_ty(ty); - - // Only impose the restrictions of `ConstRibKind` for an - // actual constant expression in a provided default. - 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.with_lifetime_rib( + LifetimeRibKind::StaticIfNoLifetimeInScope { + lint_id: item.id, + emit_lint: false, + }, + |this| { + this.visit_generics(generics); + this.visit_ty(ty); + + // Only impose the restrictions of `ConstRibKind` for an + // actual constant expression in a provided default. + 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); + } + }, + ) }, ); } @@ -3052,7 +3060,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { }, |this| { this.with_lifetime_rib( - LifetimeRibKind::StaticIfNoLifetimeInScope(item.id), + LifetimeRibKind::StaticIfNoLifetimeInScope { + lint_id: item.id, + // In impls, it's not a hard error yet due to backcompat. + emit_lint: true, + }, |this| { // If this is a trait impl, ensure the const // exists in trait diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.rs b/tests/ui/consts/static-default-lifetime/elided-lifetime.rs index e1d9791625b34..95d59f9b894e4 100644 --- a/tests/ui/consts/static-default-lifetime/elided-lifetime.rs +++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.rs @@ -9,8 +9,7 @@ impl Foo<'_> { } trait Bar { - const STATIC: &'static str; - // TODO^ + const STATIC: &str; } impl Bar for Foo<'_> { diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr index 8be225e2a3ce9..d4fc171753894 100644 --- a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr +++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr @@ -22,7 +22,7 @@ LL | const STATIC: &'static str = ""; | +++++++ error: `&` without an explicit lifetime name cannot be used here - --> $DIR/elided-lifetime.rs:17:19 + --> $DIR/elided-lifetime.rs:16:19 | LL | const STATIC: &str = ""; | ^ @@ -30,7 +30,7 @@ LL | const STATIC: &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: cannot automatically infer `'static` because of other lifetimes in scope - --> $DIR/elided-lifetime.rs:16:18 + --> $DIR/elided-lifetime.rs:15:18 | LL | impl Bar for Foo<'_> { | ^^ @@ -40,7 +40,7 @@ LL | const STATIC: &'static str = ""; | +++++++ error[E0308]: const not compatible with trait - --> $DIR/elided-lifetime.rs:17:5 + --> $DIR/elided-lifetime.rs:16:5 | LL | const STATIC: &str = ""; | ^^^^^^^^^^^^^^^^^^ lifetime mismatch @@ -48,7 +48,7 @@ LL | const STATIC: &str = ""; = note: expected reference `&'static _` found reference `&_` note: the anonymous lifetime as defined here... - --> $DIR/elided-lifetime.rs:16:18 + --> $DIR/elided-lifetime.rs:15:18 | LL | impl Bar for Foo<'_> { | ^^ diff --git a/tests/ui/consts/static-default-lifetime/generic-associated-const.rs b/tests/ui/consts/static-default-lifetime/generic-associated-const.rs index 50eb9ab166955..721920bd810cb 100644 --- a/tests/ui/consts/static-default-lifetime/generic-associated-const.rs +++ b/tests/ui/consts/static-default-lifetime/generic-associated-const.rs @@ -12,7 +12,6 @@ impl A { trait Trait { const GAC_TYPE: &str = ""; - //~^ ERROR missing lifetime specifier const GAC_LIFETIME<'a>: &str = ""; //~^ ERROR missing lifetime specifier } diff --git a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr index d6e49c7ac5886..2ecab3442a96e 100644 --- a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr +++ b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr @@ -1,16 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/generic-associated-const.rs:14:24 - | -LL | const GAC_TYPE: &str = ""; - | ^ expected named lifetime parameter - | -help: consider introducing a named lifetime parameter - | -LL | const GAC_TYPE<'a, T>: &'a str = ""; - | +++ ++ - -error[E0106]: missing lifetime specifier - --> $DIR/generic-associated-const.rs:16:29 + --> $DIR/generic-associated-const.rs:15:29 | LL | const GAC_LIFETIME<'a>: &str = ""; | ^ expected named lifetime parameter @@ -52,6 +41,6 @@ help: use the `'static` lifetime LL | const GAC_LIFETIME<'a>: &'static str = ""; | +++++++ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.default.stderr b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.default.stderr index 24e2e0a0f7a25..71ac55bf04483 100644 --- a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.default.stderr +++ b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.default.stderr @@ -1,57 +1,25 @@ -error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-in-assoc-const-type.rs:6:14 - | -LL | const A: &str = ""; - | ^ expected named lifetime parameter - | -help: consider introducing a named lifetime parameter - | -LL ~ trait ZstAssert<'a>: Sized { -LL ~ const A: &'a str = ""; - | - -error[E0106]: missing lifetime specifier +error[E0726]: implicit elided lifetime not allowed here --> $DIR/missing-lifetime-in-assoc-const-type.rs:7:14 | LL | const B: S = S { s: &() }; - | ^ expected named lifetime parameter - | -help: consider introducing a named lifetime parameter - | -LL ~ trait ZstAssert<'a>: Sized { -LL | const A: &str = ""; -LL ~ const B: S<'a> = S { s: &() }; + | ^ expected lifetime parameter | - -error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-in-assoc-const-type.rs:8:15 - | -LL | const C: &'_ str = ""; - | ^^ expected named lifetime parameter - | -help: consider introducing a named lifetime parameter - | -LL ~ trait ZstAssert<'a>: Sized { -LL | const A: &str = ""; -LL | const B: S = S { s: &() }; -LL ~ const C: &'a str = ""; +help: indicate the anonymous lifetime | +LL | const B: S<'_> = S { s: &() }; + | ++++ -error[E0106]: missing lifetime specifiers +error[E0726]: implicit elided lifetime not allowed here --> $DIR/missing-lifetime-in-assoc-const-type.rs:9:14 | LL | const D: T = T { a: &(), b: &() }; - | ^ expected 2 lifetime parameters - | -help: consider introducing a named lifetime parameter + | ^ expected lifetime parameters | -LL ~ trait ZstAssert<'a>: Sized { -LL | const A: &str = ""; -LL | const B: S = S { s: &() }; -LL | const C: &'_ str = ""; -LL ~ const D: T<'a, 'a> = T { a: &(), b: &() }; +help: indicate the anonymous lifetimes | +LL | const D: T<'_, '_> = T { a: &(), b: &() }; + | ++++++++ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0106`. +For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.generic_const_items.stderr b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.generic_const_items.stderr index a97ffe7da79eb..71ac55bf04483 100644 --- a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.generic_const_items.stderr +++ b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.generic_const_items.stderr @@ -1,47 +1,25 @@ -error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-in-assoc-const-type.rs:6:14 - | -LL | const A: &str = ""; - | ^ expected named lifetime parameter - | -help: consider introducing a named lifetime parameter - | -LL | const A<'a>: &'a str = ""; - | ++++ ++ - -error[E0106]: missing lifetime specifier +error[E0726]: implicit elided lifetime not allowed here --> $DIR/missing-lifetime-in-assoc-const-type.rs:7:14 | LL | const B: S = S { s: &() }; - | ^ expected named lifetime parameter - | -help: consider introducing a named lifetime parameter - | -LL | const B<'a>: S<'a> = S { s: &() }; - | ++++ ++++ - -error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-in-assoc-const-type.rs:8:15 - | -LL | const C: &'_ str = ""; - | ^^ expected named lifetime parameter + | ^ expected lifetime parameter | -help: consider introducing a named lifetime parameter +help: indicate the anonymous lifetime | -LL | const C<'a>: &'a str = ""; - | ++++ ~~ +LL | const B: S<'_> = S { s: &() }; + | ++++ -error[E0106]: missing lifetime specifiers +error[E0726]: implicit elided lifetime not allowed here --> $DIR/missing-lifetime-in-assoc-const-type.rs:9:14 | LL | const D: T = T { a: &(), b: &() }; - | ^ expected 2 lifetime parameters + | ^ expected lifetime parameters | -help: consider introducing a named lifetime parameter +help: indicate the anonymous lifetimes | -LL | const D<'a>: T<'a, 'a> = T { a: &(), b: &() }; - | ++++ ++++++++ +LL | const D: T<'_, '_> = T { a: &(), b: &() }; + | ++++++++ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0106`. +For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs index f36a6567e423e..a60f0b94587f8 100644 --- a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs +++ b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs @@ -3,10 +3,10 @@ #![cfg_attr(generic_const_items, feature(generic_const_items), allow(incomplete_features))] trait ZstAssert: Sized { - const A: &str = ""; //~ ERROR missing lifetime specifier - const B: S = S { s: &() }; //~ ERROR missing lifetime specifier - const C: &'_ str = ""; //~ ERROR missing lifetime specifier - const D: T = T { a: &(), b: &() }; //~ ERROR missing lifetime specifier + const A: &str = ""; + const B: S = S { s: &() }; //~ ERROR implicit elided lifetime not allowed here + const C: &'_ str = ""; + const D: T = T { a: &(), b: &() }; //~ ERROR implicit elided lifetime not allowed here } struct S<'a> {