From c3257a591f9c1e22f2f5755e23d99032f6f7fb0d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 12 May 2026 16:12:53 +0200 Subject: [PATCH] Infer all anonymous lifetimes in (assoc) consts as `'static` Hard error on hidden elided lifetimes (`S` instead of `S<'_>`) in assoc consts --- compiler/rustc_lint_defs/src/builtin.rs | 43 ---- compiler/rustc_resolve/src/diagnostics.rs | 22 -- compiler/rustc_resolve/src/late.rs | 216 +++++++----------- .../ui/consts/assoc-const-elided-lifetime.rs | 6 +- .../consts/assoc-const-elided-lifetime.stderr | 44 ---- .../elided-lifetime.rs | 7 +- .../elided-lifetime.stderr | 53 ----- .../generic-associated-const.rs | 6 +- .../generic-associated-const.stderr | 37 --- .../static-trait-impl.rs | 7 +- .../static-trait-impl.stderr | 35 --- .../missing-lifetime-in-assoc-const-type.rs | 5 + 12 files changed, 89 insertions(+), 392 deletions(-) delete mode 100644 tests/ui/consts/assoc-const-elided-lifetime.stderr delete mode 100644 tests/ui/consts/static-default-lifetime/elided-lifetime.stderr delete mode 100644 tests/ui/consts/static-default-lifetime/generic-associated-const.stderr delete mode 100644 tests/ui/consts/static-default-lifetime/static-trait-impl.stderr diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index d38b1cf47bd6f..693737bd89bdd 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -44,7 +44,6 @@ pub mod hardwired { DEPRECATED_WHERE_CLAUSE_LOCATION, DUPLICATE_FEATURES, DUPLICATE_MACRO_ATTRIBUTES, - ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_BUILTIN_CFGS_IN_FLAGS, EXPORTED_PRIVATE_DEPENDENCIES, @@ -4762,48 +4761,6 @@ declare_lint! { "impl trait in impl method signature does not match trait method signature", } -declare_lint! { - /// The `elided_lifetimes_in_associated_constant` lint detects elided lifetimes - /// in associated constants when there are other lifetimes in scope. This was - /// accidentally supported, and this lint was later relaxed to allow eliding - /// lifetimes to `'static` when there are no lifetimes in scope. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(elided_lifetimes_in_associated_constant)] - /// - /// struct Foo<'a>(&'a ()); - /// - /// impl<'a> Foo<'a> { - /// const STR: &str = "hello, world"; - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Previous version of Rust - /// - /// Implicit static-in-const behavior was decided [against] for associated - /// constants because of ambiguity. This, however, regressed and the compiler - /// erroneously treats elided lifetimes in associated constants as lifetime - /// parameters on the impl. - /// - /// This is a [future-incompatible] lint to transition this to a - /// hard error in the future. - /// - /// [against]: https://github.com/rust-lang/rust/issues/38831 - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, - Deny, - "elided lifetimes cannot be used in associated constants in impls", - @future_incompatible = FutureIncompatibleInfo { - reason: fcw!(FutureReleaseError #115010), - }; -} - declare_lint! { /// The `private_macro_use` lint detects private macros that are imported /// with `#[macro_use]`. diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 2baf423e296d6..22cc6a581f19a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1661,28 +1661,6 @@ pub(crate) struct UnusedQualifications { pub removal_span: Span, } -#[derive(Diagnostic)] -#[diag( - "{$elided -> - [true] `&` without an explicit lifetime name cannot be used here - *[false] `'_` cannot be used here - }" -)] -pub(crate) struct AssociatedConstElidedLifetime { - #[suggestion( - "use the `'static` lifetime", - style = "verbose", - code = "{code}", - applicability = "machine-applicable" - )] - pub span: Span, - - pub code: &'static str, - pub elided: bool, - #[note("cannot automatically infer `'static` because of other lifetimes in scope")] - pub lifetimes_in_scope: MultiSpan, -} - #[derive(Diagnostic)] #[diag("lifetime parameter `{$ident}` only used once")] pub(crate) struct SingleUseLifetime { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index c94f2f3ffb85d..4ae56ac7c6f3d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -333,7 +333,11 @@ enum LifetimeRibKind { AnonymousCreateParameter { binder: NodeId, report_in_path: bool }, /// Replace all anonymous lifetimes by provided lifetime. - Elided(LifetimeRes), + Elided { + res: LifetimeRes, + /// Always report those lifetimes as an error if in a path + error_in_path: bool, + }, // -- Barrier ribs that stop lifetime lookup, or continue it but produce an error later. // @@ -342,11 +346,6 @@ enum LifetimeRibKind { /// error on default object bounds (e.g., `Box`). AnonymousReportError, - /// 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 (if `emit_lint` is enabled). - StaticIfNoLifetimeInScope { lint_id: NodeId, emit_lint: bool }, - /// Signal we cannot find which should be the anonymous lifetime. ElisionFailure, @@ -369,6 +368,12 @@ enum LifetimeRibKind { /// Lifetimes cannot be elided in `impl Trait` types without `#![feature(anonymous_lifetime_in_impl_trait)]`. ImplTrait, } +impl LifetimeRibKind { + /// Convenience function for creating non-erroring `Elided` variants. + fn elided(res: LifetimeRes) -> LifetimeRibKind { + LifetimeRibKind::Elided { res, error_in_path: false } + } +} #[derive(Copy, Clone, Debug)] enum LifetimeBinderKind { @@ -1162,7 +1167,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc this.last_block_rib = None; // Resolve the function body, potentially inside the body of an async closure this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Infer), + LifetimeRibKind::elided(LifetimeRes::Infer), |this| this.visit_block(body), ); @@ -1190,7 +1195,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc this.with_lifetime_rib( match binder { ClosureBinder::NotPresent => { - LifetimeRibKind::Elided(LifetimeRes::Infer) + LifetimeRibKind::elided(LifetimeRes::Infer) } ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError, }, @@ -1202,7 +1207,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc let previous_state = replace(&mut this.in_func_body, true); // Resolve the function body, potentially inside the body of an async closure this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Infer), + LifetimeRibKind::elided(LifetimeRes::Infer), |this| this.visit_expr(body), ); @@ -1380,9 +1385,8 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc } LifetimeRibKind::AnonymousCreateParameter { .. } | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } | LifetimeRibKind::ImplTrait - | LifetimeRibKind::Elided(_) + | LifetimeRibKind::Elided { .. } | LifetimeRibKind::ElisionFailure | LifetimeRibKind::ConcreteAnonConst(_) | LifetimeRibKind::ConstParamTy => {} @@ -1786,7 +1790,6 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // lifetime would be illegal. LifetimeRibKind::Item | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many), // An anonymous lifetime is legal here, and bound to the right // place, go ahead. @@ -1800,11 +1803,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }), // Only report if eliding the lifetime would have the same // semantics. - LifetimeRibKind::Elided(r) => Some(if res == r { - LifetimeUseSet::One { use_span: ident.span, use_ctxt } - } else { - LifetimeUseSet::Many - }), + LifetimeRibKind::Elided { res: r, error_in_path } => { + Some(if res == r && !error_in_path { + LifetimeUseSet::One { use_span: ident.span, use_ctxt } + } else { + LifetimeUseSet::Many + }) + } LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => None, LifetimeRibKind::ConcreteAnonConst(_) => { @@ -1845,12 +1850,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { return; } LifetimeRibKind::AnonymousCreateParameter { .. } - | LifetimeRibKind::Elided(_) + | LifetimeRibKind::Elided { .. } | LifetimeRibKind::Generics { .. } | LifetimeRibKind::ElisionFailure | LifetimeRibKind::AnonymousReportError - | LifetimeRibKind::ImplTrait - | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => {} + | LifetimeRibKind::ImplTrait => {} } } @@ -1889,48 +1893,6 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.record_lifetime_use(lifetime.id, res, elision_candidate); return; } - LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => { - let mut lifetimes_in_scope = vec![]; - for rib in self.lifetime_ribs[..i].iter().rev() { - lifetimes_in_scope.extend(rib.bindings.iter().map(|(ident, _)| ident.span)); - // Consider any anonymous lifetimes, too - if let LifetimeRibKind::AnonymousCreateParameter { binder, .. } = rib.kind - && let Some(extra) = self.r.extra_lifetime_params_map.get(&binder) - { - lifetimes_in_scope.extend(extra.iter().map(|(ident, _, _)| ident.span)); - } - if let LifetimeRibKind::Item = rib.kind { - break; - } - } - if lifetimes_in_scope.is_empty() { - self.record_lifetime_use( - lifetime.id, - LifetimeRes::Static, - elision_candidate, - ); - return; - } else if emit_lint { - let lt_span = if elided { - lifetime.ident.span.shrink_to_hi() - } else { - lifetime.ident.span - }; - let code = if elided { "'static " } else { "'static" }; - - self.r.lint_buffer.buffer_lint( - lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, - node_id, - lifetime.ident.span, - crate::diagnostics::AssociatedConstElidedLifetime { - elided, - code, - span: lt_span, - lifetimes_in_scope: lifetimes_in_scope.into(), - }, - ); - } - } LifetimeRibKind::AnonymousReportError => { let guar = if elided { let suggestion = if self.diag_metadata.in_assoc_ty_binding { @@ -2047,7 +2009,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.record_lifetime_err(lifetime.id, guar); return; } - LifetimeRibKind::Elided(res) => { + LifetimeRibKind::Elided { res, .. } => { self.record_lifetime_use(lifetime.id, res, elision_candidate); return; } @@ -2317,7 +2279,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, '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::Elided { error_in_path: true, .. } => { let sess = self.r.tcx.sess; let subdiag = elided_lifetime_in_path_suggestion( sess.source_map(), @@ -2353,7 +2315,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } break; } - LifetimeRibKind::Elided(res) => { + LifetimeRibKind::Elided { res, error_in_path: false } => { let mut candidate = LifetimeElisionCandidate::Missing(missing_lifetime); for id in node_ids { self.record_lifetime_use( @@ -2480,7 +2442,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if fn_id == this.r.current_owner.id { this.r.current_owner.lifetime_elision_allowed = true; } - LifetimeRibKind::Elided(*res) + LifetimeRibKind::elided(*res) } else { LifetimeRibKind::ElisionFailure }; @@ -2540,7 +2502,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())]; for (pat, _) in inputs.clone() { debug!("resolving bindings in pat = {pat:?}"); - self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { + self.with_lifetime_rib(LifetimeRibKind::elided(LifetimeRes::Infer), |this| { if let Some(pat) = pat { this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings); } @@ -2966,7 +2928,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ident, ty, expr, define_opaque, eii_impls, .. }) => { self.with_static_rib(def_kind, |this| { - this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| { + this.with_lifetime_rib(LifetimeRibKind::elided(LifetimeRes::Static), |this| { this.visit_ty(ty); }); if let Some(expr) = expr { @@ -3004,8 +2966,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.visit_generics(generics); this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Static), - |this| { + LifetimeRibKind::elided(LifetimeRes::Static), + |this: &mut LateResolutionVisitor<'a, 'ast, 'ra, 'tcx>| { if rhs_kind.is_type_const() && !this.r.features.generic_const_parameter_types() { @@ -3040,7 +3002,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { DUMMY_SP, |this| { this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Infer), + LifetimeRibKind::elided(LifetimeRes::Infer), |this| { this.with_constant_rib( IsRepeatExpr::No, @@ -3401,9 +3363,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { generics.span, |this| { this.with_lifetime_rib( - LifetimeRibKind::StaticIfNoLifetimeInScope { - lint_id: item.id, - emit_lint: false, + LifetimeRibKind::Elided { + res: LifetimeRes::Static, + error_in_path: true, }, |this| { this.visit_generics(generics); @@ -3620,67 +3582,47 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { generics.span, |this| { this.with_lifetime_rib( - // Until these are a hard error, we need to create them within the - // correct binder, Otherwise the lifetimes of this assoc const think - // they are lifetimes of the trait. - LifetimeRibKind::AnonymousCreateParameter { - binder: item.id, - report_in_path: true, + LifetimeRibKind::Elided { + res: LifetimeRes::Static, + error_in_path: true, }, |this| { - this.with_lifetime_rib( - 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 - this.check_trait_item( - item.id, - *ident, - *ident, - &item.kind, - ValueNS, - item.span, - seen_trait_items, - |i, s, c| ConstNotMemberOfTrait(i, s, c), - ); + // If this is a trait impl, ensure the const + // exists in trait + this.check_trait_item( + item.id, + *ident, + *ident, + &item.kind, + ValueNS, + item.span, + seen_trait_items, + |i, s, c| ConstNotMemberOfTrait(i, s, c), + ); - this.visit_generics(generics); - if rhs_kind.is_type_const() - && !this - .r - .tcx - .features() - .generic_const_parameter_types() - { - this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { - this.with_rib( - ValueNS, - RibKind::ConstParamTy, - |this| { - this.with_lifetime_rib( - LifetimeRibKind::ConstParamTy, - |this| this.visit_ty(ty), - ) - }, - ) - }); - } else { - this.visit_ty(ty); - } - // 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_item_rhs(rhs_kind, None); - }, - ) + this.visit_generics(generics); + if rhs_kind.is_type_const() + && !this.r.tcx.features().generic_const_parameter_types() + { + this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { + this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { + this.with_lifetime_rib( + LifetimeRibKind::ConstParamTy, + |this| this.visit_ty(ty), + ) + }) + }); + } else { + this.visit_ty(ty); + } + // 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_item_rhs(rhs_kind, None); }, - ); + ) }, ); self.resolve_define_opaques(define_opaque); @@ -3902,7 +3844,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } fn resolve_static_body(&mut self, expr: &'ast Expr, item: Option<(Ident, ConstantItemKind)>) { - self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { + self.with_lifetime_rib(LifetimeRibKind::elided(LifetimeRes::Infer), |this| { this.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, item, |this| { this.visit_expr(expr) }); @@ -3914,7 +3856,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { rhs_kind: &'ast ConstItemRhsKind, item: Option<(Ident, ConstantItemKind)>, ) { - self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| match rhs_kind { + self.with_lifetime_rib(LifetimeRibKind::elided(LifetimeRes::Infer), |this| match rhs_kind { ConstItemRhsKind::TypeConst { rhs: Some(anon_const) } => { this.resolve_anon_const(anon_const, AnonConstKind::ConstArg(IsRepeatExpr::No)); } @@ -3942,7 +3884,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Create lifetimes not with `LifetimeRibKind::Generics` but with `LifetimeRibKind::Elided`, // as we are not processing generic params but generic args in a future call (#156342, #156758). - self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { + self.with_lifetime_rib(LifetimeRibKind::elided(LifetimeRes::Infer), |this| { if let Some(qself) = &delegation.qself { this.visit_ty(&qself.ty); } @@ -3977,7 +3919,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { //As we lower target_expr_template body to a body of a function we need a label rib (#148889) this.with_label_rib(RibKind::FnOrCoroutine, |this| { - this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { + this.with_lifetime_rib(LifetimeRibKind::elided(LifetimeRes::Infer), |this| { this.visit_block(body); }); }); @@ -3986,7 +3928,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { fn resolve_params(&mut self, params: &'ast [Param]) { let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())]; - self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { + self.with_lifetime_rib(LifetimeRibKind::elided(LifetimeRes::Infer), |this| { for Param { pat, .. } in params { this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings); } @@ -5207,7 +5149,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }; self.with_constant_rib(is_repeat_expr, may_use_generics, None, |this| { - this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { + this.with_lifetime_rib(LifetimeRibKind::elided(LifetimeRes::Infer), |this| { resolve_expr(this); }); }); diff --git a/tests/ui/consts/assoc-const-elided-lifetime.rs b/tests/ui/consts/assoc-const-elided-lifetime.rs index 10cd33a8fed59..3fdd725d32a31 100644 --- a/tests/ui/consts/assoc-const-elided-lifetime.rs +++ b/tests/ui/consts/assoc-const-elided-lifetime.rs @@ -1,4 +1,4 @@ -#![deny(elided_lifetimes_in_associated_constant)] +//@ check-pass use std::marker::PhantomData; @@ -8,12 +8,8 @@ struct Foo<'a> { impl<'a> Foo<'a> { const FOO: Foo<'_> = Foo { x: PhantomData::<&()> }; - //~^ ERROR `'_` 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! const BAR: &() = &(); - //~^ ERROR `&` 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! } fn main() {} diff --git a/tests/ui/consts/assoc-const-elided-lifetime.stderr b/tests/ui/consts/assoc-const-elided-lifetime.stderr deleted file mode 100644 index 6277b079bdac7..0000000000000 --- a/tests/ui/consts/assoc-const-elided-lifetime.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error: `'_` cannot be used here - --> $DIR/assoc-const-elided-lifetime.rs:10:20 - | -LL | const FOO: Foo<'_> = Foo { x: PhantomData::<&()> }; - | ^^ - | -note: cannot automatically infer `'static` because of other lifetimes in scope - --> $DIR/assoc-const-elided-lifetime.rs:9:6 - | -LL | impl<'a> Foo<'a> { - | ^^ - = 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: the lint level is defined here - --> $DIR/assoc-const-elided-lifetime.rs:1:9 - | -LL | #![deny(elided_lifetimes_in_associated_constant)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: use the `'static` lifetime - | -LL - const FOO: Foo<'_> = Foo { x: PhantomData::<&()> }; -LL + const FOO: Foo<'static> = Foo { x: PhantomData::<&()> }; - | - -error: `&` without an explicit lifetime name cannot be used here - --> $DIR/assoc-const-elided-lifetime.rs:14:16 - | -LL | const BAR: &() = &(); - | ^ - | -note: cannot automatically infer `'static` because of other lifetimes in scope - --> $DIR/assoc-const-elided-lifetime.rs:9:6 - | -LL | impl<'a> Foo<'a> { - | ^^ - = 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 BAR: &'static () = &(); - | +++++++ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.rs b/tests/ui/consts/static-default-lifetime/elided-lifetime.rs index 989de389180a1..87ca5e082c032 100644 --- a/tests/ui/consts/static-default-lifetime/elided-lifetime.rs +++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.rs @@ -1,11 +1,9 @@ -#![deny(elided_lifetimes_in_associated_constant)] +//@check-pass struct Foo<'a>(&'a ()); impl Foo<'_> { const STATIC: &str = ""; - //~^ ERROR `&` without an explicit lifetime name cannot be used here - //~| WARN this was previously accepted by the compiler but is being phased out } trait Bar { @@ -14,9 +12,6 @@ trait Bar { impl Bar for Foo<'_> { const STATIC: &str = ""; - //~^ ERROR `&` without an explicit lifetime name cannot be used here - //~| WARN this was previously accepted by the compiler but is being phased out - //~| ERROR lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration } fn main() {} diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr deleted file mode 100644 index 370e6655d8607..0000000000000 --- a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr +++ /dev/null @@ -1,53 +0,0 @@ -error: `&` without an explicit lifetime name cannot be used here - --> $DIR/elided-lifetime.rs:6:19 - | -LL | const STATIC: &str = ""; - | ^ - | -note: cannot automatically infer `'static` because of other lifetimes in scope - --> $DIR/elided-lifetime.rs:5:10 - | -LL | impl Foo<'_> { - | ^^ - = 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: the lint level is defined here - --> $DIR/elided-lifetime.rs:1:9 - | -LL | #![deny(elided_lifetimes_in_associated_constant)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: use the `'static` lifetime - | -LL | const STATIC: &'static str = ""; - | +++++++ - -error: `&` without an explicit lifetime name cannot be used here - --> $DIR/elided-lifetime.rs:16:19 - | -LL | const STATIC: &str = ""; - | ^ - | -note: cannot automatically infer `'static` because of other lifetimes in scope - --> $DIR/elided-lifetime.rs:15:18 - | -LL | impl Bar for Foo<'_> { - | ^^ - = 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 STATIC: &'static str = ""; - | +++++++ - -error[E0195]: lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration - --> $DIR/elided-lifetime.rs:16:17 - | -LL | const STATIC: &str; - | - lifetimes in impl do not match this associated constant in trait -... -LL | const STATIC: &str = ""; - | ^ lifetimes do not match associated constant in trait - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0195`. 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 8fabaa43f5a27..04e7e3d5f7cec 100644 --- a/tests/ui/consts/static-default-lifetime/generic-associated-const.rs +++ b/tests/ui/consts/static-default-lifetime/generic-associated-const.rs @@ -1,18 +1,16 @@ -#![deny(elided_lifetimes_in_associated_constant)] +//@ check-pass + #![feature(generic_const_items)] struct A; impl A { const GAC_TYPE: &str = ""; const GAC_LIFETIME<'a>: &str = ""; - //~^ ERROR `&` without an explicit lifetime name cannot be used here - //~| WARN this was previously accepted by the compiler but is being phased out } trait Trait { const GAC_TYPE: &str = ""; const GAC_LIFETIME<'a>: &str = ""; - //~^ ERROR missing lifetime specifier } fn main() {} diff --git a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr deleted file mode 100644 index fe858d685f7fa..0000000000000 --- a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr +++ /dev/null @@ -1,37 +0,0 @@ -error[E0106]: missing lifetime specifier - --> $DIR/generic-associated-const.rs:14:29 - | -LL | const GAC_LIFETIME<'a>: &str = ""; - | ^ expected named lifetime parameter - | -help: consider using the `'a` lifetime - | -LL | const GAC_LIFETIME<'a>: &'a str = ""; - | ++ - -error: `&` without an explicit lifetime name cannot be used here - --> $DIR/generic-associated-const.rs:7:29 - | -LL | const GAC_LIFETIME<'a>: &str = ""; - | ^ - | -note: cannot automatically infer `'static` because of other lifetimes in scope - --> $DIR/generic-associated-const.rs:7:24 - | -LL | const GAC_LIFETIME<'a>: &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: the lint level is defined here - --> $DIR/generic-associated-const.rs:1:9 - | -LL | #![deny(elided_lifetimes_in_associated_constant)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: use the `'static` lifetime - | -LL | const GAC_LIFETIME<'a>: &'static str = ""; - | +++++++ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs index ecc163aecbf1a..d146034114b96 100644 --- a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs +++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs @@ -1,4 +1,4 @@ -#![deny(elided_lifetimes_in_associated_constant)] +//@ check-pass trait Bar<'a> { const STATIC: &'a str; @@ -7,9 +7,6 @@ trait Bar<'a> { struct A; impl Bar<'_> for A { const STATIC: &str = ""; - //~^ ERROR `&` without an explicit lifetime name cannot be used here - //~| WARN this was previously accepted by the compiler but is being phased out - //~| ERROR lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration } struct B; @@ -19,12 +16,10 @@ impl Bar<'static> for B { struct C; impl Bar<'_> for C { - // make ^^ not cause const STATIC: &'static str = { struct B; impl Bar<'static> for B { const STATIC: &str = ""; - // ^ to emit a future incompat warning } "" }; diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr deleted file mode 100644 index ab82515162014..0000000000000 --- a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error: `&` without an explicit lifetime name cannot be used here - --> $DIR/static-trait-impl.rs:9:19 - | -LL | const STATIC: &str = ""; - | ^ - | -note: cannot automatically infer `'static` because of other lifetimes in scope - --> $DIR/static-trait-impl.rs:8:10 - | -LL | impl Bar<'_> for A { - | ^^ - = 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: the lint level is defined here - --> $DIR/static-trait-impl.rs:1:9 - | -LL | #![deny(elided_lifetimes_in_associated_constant)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: use the `'static` lifetime - | -LL | const STATIC: &'static str = ""; - | +++++++ - -error[E0195]: lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration - --> $DIR/static-trait-impl.rs:9:17 - | -LL | const STATIC: &'a str; - | - lifetimes in impl do not match this associated constant in trait -... -LL | const STATIC: &str = ""; - | ^ lifetimes do not match associated constant in trait - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0195`. 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 a60f0b94587f8..7745ebaceb9aa 100644 --- a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs +++ b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs @@ -9,6 +9,11 @@ trait ZstAssert: Sized { const D: T = T { a: &(), b: &() }; //~ ERROR implicit elided lifetime not allowed here } +const A: &str = ""; +const B: S = S { s: &() }; +const C: &'_ str = ""; +const D: T = T { a: &(), b: &() }; + struct S<'a> { s: &'a (), }