From e38764d73b84eb625102233623e79f36515345e2 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sun, 1 Sep 2024 01:14:06 +0300 Subject: [PATCH 1/4] elided_named_lifetimes: unify lint def & pass MissingLifetimeKind --- .../rustc_lint/src/context/diagnostics.rs | 23 +++++++++++-------- compiler/rustc_lint_defs/src/lib.rs | 17 ++++++++------ compiler/rustc_resolve/src/late.rs | 14 +++++++---- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index fd43afa174383..b1c1e4f4dd686 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -8,7 +8,7 @@ use rustc_errors::{ elided_lifetime_in_path_suggestion, Applicability, Diag, DiagArgValue, LintDiagnostic, }; use rustc_middle::middle::stability; -use rustc_session::lint::BuiltinLintDiag; +use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution}; use rustc_session::Session; use rustc_span::symbol::kw; use rustc_span::BytePos; @@ -442,15 +442,18 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => { lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag) } - BuiltinLintDiag::ElidedIsStatic { elided } => { - lints::ElidedNamedLifetime { elided, name: kw::StaticLifetime, named_declaration: None } - .decorate_lint(diag) - } - BuiltinLintDiag::ElidedIsParam { elided, param: (param_name, param_span) } => { - lints::ElidedNamedLifetime { - elided, - name: param_name, - named_declaration: Some(param_span), + BuiltinLintDiag::ElidedNamedLifetimes { elided: (elided, _kind), resolution } => { + match resolution { + ElidedLifetimeResolution::Static => lints::ElidedNamedLifetime { + elided, + name: kw::StaticLifetime, + named_declaration: None, + }, + ElidedLifetimeResolution::Param(name, declaration) => lints::ElidedNamedLifetime { + elided, + name, + named_declaration: Some(declaration), + }, } .decorate_lint(diag) } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 6ee330416236f..9a72e4f673934 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -10,7 +10,7 @@ use rustc_data_structures::stable_hasher::{ }; use rustc_error_messages::{DiagMessage, MultiSpan}; use rustc_hir::def::Namespace; -use rustc_hir::{HashStableContext, HirId}; +use rustc_hir::{HashStableContext, HirId, MissingLifetimeKind}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::Edition; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent}; @@ -556,6 +556,12 @@ pub enum DeprecatedSinceKind { InVersion(String), } +#[derive(Debug)] +pub enum ElidedLifetimeResolution { + Static, + Param(Symbol, Span), +} + // This could be a closure, but then implementing derive trait // becomes hacky (and it gets allocated). #[derive(Debug)] @@ -568,12 +574,9 @@ pub enum BuiltinLintDiag { }, MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), ElidedLifetimesInPaths(usize, Span, bool, Span), - ElidedIsStatic { - elided: Span, - }, - ElidedIsParam { - elided: Span, - param: (Symbol, Span), + ElidedNamedLifetimes { + elided: (Span, MissingLifetimeKind), + resolution: ElidedLifetimeResolution, }, UnknownCrateTypes { span: Span, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 79c42456cf8c9..917cb81aa511f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2062,7 +2062,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { lint::builtin::ELIDED_NAMED_LIFETIMES, missing.id_for_lint, missing.span, - BuiltinLintDiag::ElidedIsStatic { elided: missing.span }, + BuiltinLintDiag::ElidedNamedLifetimes { + elided: (missing.span, missing.kind), + resolution: lint::ElidedLifetimeResolution::Static, + }, ); } } @@ -2072,9 +2075,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { lint::builtin::ELIDED_NAMED_LIFETIMES, missing.id_for_lint, missing.span, - BuiltinLintDiag::ElidedIsParam { - elided: missing.span, - param: (tcx.item_name(param.into()), tcx.source_span(param)), + BuiltinLintDiag::ElidedNamedLifetimes { + elided: (missing.span, missing.kind), + resolution: lint::ElidedLifetimeResolution::Param( + tcx.item_name(param.into()), + tcx.source_span(param), + ), }, ); } From dcfc71310d560a77b4813f60511c2b15c5125b80 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sun, 1 Sep 2024 03:42:18 +0300 Subject: [PATCH 2/4] elided_named_lifetimes: add suggestions --- compiler/rustc_lint/messages.ftl | 2 + .../rustc_lint/src/context/diagnostics.rs | 44 ++++++++++++------- compiler/rustc_lint/src/lints.rs | 2 +- .../async-await/issues/issue-63388-1.stderr | 4 ++ .../type-dependent/issue-71348.full.stderr | 4 ++ .../type-dependent/issue-71348.min.stderr | 4 ++ .../consts/min_const_fn/min_const_fn.stderr | 9 ++++ .../ui/impl-trait/impl-fn-hrtb-bounds.stderr | 4 ++ .../impl-fn-predefined-lifetimes.stderr | 4 ++ .../rpit-assoc-pair-with-lifetime.stderr | 4 ++ ...urn-type-requires-explicit-lifetime.stderr | 4 ++ ...-existing-name-if-else-using-impl-3.stderr | 4 ++ .../example-from-issue48686.stderr | 4 ++ .../missing-lifetime-kind.stderr | 19 ++++++++ .../not-tied-to-crate.stderr | 8 ++++ .../lint/elided-named-lifetimes/static.stderr | 19 ++++++++ .../object-lifetime-default-elision.stderr | 4 ++ .../ignore-non-reference-lifetimes.stderr | 9 ++++ tests/ui/self/self_lifetime-async.stderr | 9 ++++ tests/ui/self/self_lifetime.stderr | 9 ++++ .../impl-trait-missing-lifetime-gated.stderr | 4 ++ .../missing-lifetimes-in-signature.stderr | 4 ++ .../missing_lifetime_bound.stderr | 4 ++ 23 files changed, 166 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 759320b9eb65f..fe211355ac38a 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -256,6 +256,8 @@ lint_elided_named_lifetime = elided lifetime has a name .label_elided = this elided lifetime gets resolved as `{$name}` .label_named = lifetime `{$name}` declared here +lint_elided_named_lifetime_suggestion = consider specifying it explicitly + lint_enum_intrinsics_mem_discriminant = the return value of `mem::discriminant` is unspecified when called with a non-enum type .note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index b1c1e4f4dd686..a1a371a032e90 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -7,6 +7,7 @@ use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; use rustc_errors::{ elided_lifetime_in_path_suggestion, Applicability, Diag, DiagArgValue, LintDiagnostic, }; +use rustc_hir::MissingLifetimeKind; use rustc_middle::middle::stability; use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution}; use rustc_session::Session; @@ -14,7 +15,8 @@ use rustc_span::symbol::kw; use rustc_span::BytePos; use tracing::debug; -use crate::lints; +use crate::fluent_generated; +use crate::lints::{self, ElidedNamedLifetime}; mod check_cfg; @@ -442,20 +444,32 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => { lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag) } - BuiltinLintDiag::ElidedNamedLifetimes { elided: (elided, _kind), resolution } => { - match resolution { - ElidedLifetimeResolution::Static => lints::ElidedNamedLifetime { - elided, - name: kw::StaticLifetime, - named_declaration: None, - }, - ElidedLifetimeResolution::Param(name, declaration) => lints::ElidedNamedLifetime { - elided, - name, - named_declaration: Some(declaration), - }, - } - .decorate_lint(diag) + BuiltinLintDiag::ElidedNamedLifetimes { elided: (span, kind), resolution } => { + let (name, named_declaration) = match resolution { + ElidedLifetimeResolution::Static => (kw::StaticLifetime, None), + ElidedLifetimeResolution::Param(name, declaration) => (name, Some(declaration)), + }; + ElidedNamedLifetime { span, name, named_declaration }.decorate_lint(diag); + + let (applicability, suggestion) = match kind { + MissingLifetimeKind::Underscore => { + (Applicability::MachineApplicable, format!("{name}")) + } + MissingLifetimeKind::Ampersand => { + (Applicability::MachineApplicable, format!("&{name} ")) + } + MissingLifetimeKind::Comma => (Applicability::Unspecified, format!("<{name}, ")), + MissingLifetimeKind::Brackets => ( + Applicability::Unspecified, + format!("{}<{name}>", sess.source_map().span_to_snippet(span).unwrap()), + ), + }; + diag.span_suggestion_verbose( + span, + fluent_generated::lint_elided_named_lifetime_suggestion, + suggestion, + applicability, + ); } } } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 9050f36acba7b..426d671f8e0a6 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2627,7 +2627,7 @@ pub(crate) struct ElidedLifetimesInPaths { #[diag(lint_elided_named_lifetime)] pub(crate) struct ElidedNamedLifetime { #[label(lint_label_elided)] - pub elided: Span, + pub span: Span, pub name: Symbol, #[label(lint_label_named)] pub named_declaration: Option, diff --git a/tests/ui/async-await/issues/issue-63388-1.stderr b/tests/ui/async-await/issues/issue-63388-1.stderr index ef74bfe32375e..c8b55977faf3a 100644 --- a/tests/ui/async-await/issues/issue-63388-1.stderr +++ b/tests/ui/async-await/issues/issue-63388-1.stderr @@ -8,6 +8,10 @@ LL | ) -> &dyn Foo | ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | ) -> &'a dyn Foo + | ~~~ error[E0621]: explicit lifetime required in the type of `foo` --> $DIR/issue-63388-1.rs:13:5 diff --git a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr index 177ff20fbf9ea..8d1c1ea23a81c 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr @@ -5,6 +5,10 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Ta | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target + | ~~~~ warning: 1 warning emitted diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr index 5aee282952aa2..57da3ce21cecd 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr @@ -5,6 +5,10 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Ta | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target + | ~~~~ error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/issue-71348.rs:10:24 diff --git a/tests/ui/consts/min_const_fn/min_const_fn.stderr b/tests/ui/consts/min_const_fn/min_const_fn.stderr index 4b348a182b87f..b7db403ad16b2 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn.stderr @@ -8,6 +8,10 @@ LL | const fn get_lt(&'a self) -> &T { &self.0 } | ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | const fn get_lt(&'a self) -> &'a T { &self.0 } + | ~~~ warning: elided lifetime has a name --> $DIR/min_const_fn.rs:48:42 @@ -17,6 +21,11 @@ LL | impl<'a, T> Foo { ... LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } | ^ this elided lifetime gets resolved as `'a` + | +help: consider specifying it explicitly + | +LL | const fn get_mut_lt(&'a mut self) -> &'a mut T { &mut self.0 } + | ~~~ error[E0493]: destructor of `Foo` cannot be evaluated at compile-time --> $DIR/min_const_fn.rs:37:25 diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr index d0f8f7689d17c..ccea9d5e6e92a 100644 --- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr +++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr @@ -17,6 +17,10 @@ LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { | -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { + | ~~ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/impl-fn-hrtb-bounds.rs:4:41 diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr index 50a9f3ebeabb8..a60f398684330 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr @@ -5,6 +5,10 @@ LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { | -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + 'a) { + | ~~ error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/impl-fn-predefined-lifetimes.rs:7:9 diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr index bff3ffd934ac6..ec0f0708b156f 100644 --- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr +++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr @@ -5,6 +5,10 @@ LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator { + | ~~~ warning: 1 warning emitted diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index f835d2655bb01..a7512158661fb 100644 --- a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -114,6 +114,10 @@ LL | fn m<'a>(_: &'a Foo<'a>) -> &str { "" } | lifetime `'a` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn m<'a>(_: &'a Foo<'a>) -> &'a str { "" } + | ~~~ error: aborting due to 7 previous errors; 1 warning emitted diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr index 2d5d4fb0e72ec..0943e0cc0d9d4 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr @@ -7,6 +7,10 @@ LL | fn foo<'a>(&'a self, x: &i32) -> &i32 { | lifetime `'a` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn foo<'a>(&'a self, x: &i32) -> &'a i32 { + | ~~~ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:9:36 diff --git a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr index 8c5426a60cb72..5af5123c03237 100644 --- a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr +++ b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr @@ -9,6 +9,10 @@ note: the lint level is defined here | LL | #![deny(elided_named_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying it explicitly + | +LL | pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 { + | ~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr index 249ae146b1675..6abaad7f5d218 100644 --- a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr +++ b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr @@ -11,6 +11,10 @@ note: the lint level is defined here | LL | #![deny(elided_named_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying it explicitly + | +LL | fn ampersand<'a>(x: &'a u8) -> &'a u8 { + | ~~~ error: elided lifetime has a name --> $DIR/missing-lifetime-kind.rs:10:31 @@ -19,6 +23,11 @@ LL | fn brackets<'a>(x: &'a u8) -> Brackets { | -- ^^^^^^^^ this elided lifetime gets resolved as `'a` | | | lifetime `'a` declared here + | +help: consider specifying it explicitly + | +LL | fn brackets<'a>(x: &'a u8) -> Brackets<'a> { + | ~~~~~~~~~~~~ error: elided lifetime has a name --> $DIR/missing-lifetime-kind.rs:17:33 @@ -27,6 +36,11 @@ LL | fn comma<'a>(x: &'a u8) -> Comma { | -- ^ this elided lifetime gets resolved as `'a` | | | lifetime `'a` declared here + | +help: consider specifying it explicitly + | +LL | fn comma<'a>(x: &'a u8) -> Comma<'a, u8> { + | ~~~~ error: elided lifetime has a name --> $DIR/missing-lifetime-kind.rs:22:34 @@ -35,6 +49,11 @@ LL | fn underscore<'a>(x: &'a u8) -> &'_ u8 { | -- ^^ this elided lifetime gets resolved as `'a` | | | lifetime `'a` declared here + | +help: consider specifying it explicitly + | +LL | fn underscore<'a>(x: &'a u8) -> &'a u8 { + | ~~ error: aborting due to 4 previous errors diff --git a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr index c465aab1a03d2..cbc1b862caabd 100644 --- a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr +++ b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr @@ -9,6 +9,10 @@ note: the lint level is defined here | LL | #[warn(elided_named_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying it explicitly + | +LL | fn bar(x: &'static u8) -> &'static u8 { + | ~~~~~~~~ error: elided lifetime has a name --> $DIR/not-tied-to-crate.rs:11:31 @@ -21,6 +25,10 @@ note: the lint level is defined here | LL | #[deny(elided_named_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying it explicitly + | +LL | fn baz(x: &'static u8) -> &'static u8 { + | ~~~~~~~~ error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/lint/elided-named-lifetimes/static.stderr b/tests/ui/lint/elided-named-lifetimes/static.stderr index d2e9776cb4f0e..6c3944e5ea580 100644 --- a/tests/ui/lint/elided-named-lifetimes/static.stderr +++ b/tests/ui/lint/elided-named-lifetimes/static.stderr @@ -9,24 +9,43 @@ note: the lint level is defined here | LL | #![deny(elided_named_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying it explicitly + | +LL | fn ampersand(x: &'static u8) -> &'static u8 { + | ~~~~~~~~ error: elided lifetime has a name --> $DIR/static.rs:23:32 | LL | fn brackets(x: &'static u8) -> Brackets { | ^^^^^^^^ this elided lifetime gets resolved as `'static` + | +help: consider specifying it explicitly + | +LL | fn brackets(x: &'static u8) -> Brackets<'static> { + | ~~~~~~~~~~~~~~~~~ error: elided lifetime has a name --> $DIR/static.rs:30:34 | LL | fn comma(x: &'static u8) -> Comma { | ^ this elided lifetime gets resolved as `'static` + | +help: consider specifying it explicitly + | +LL | fn comma(x: &'static u8) -> Comma<'static, u8> { + | ~~~~~~~~~ error: elided lifetime has a name --> $DIR/static.rs:35:35 | LL | fn underscore(x: &'static u8) -> &'_ u8 { | ^^ this elided lifetime gets resolved as `'static` + | +help: consider specifying it explicitly + | +LL | fn underscore(x: &'static u8) -> &'static u8 { + | ~~~~~~~ error: aborting due to 4 previous errors diff --git a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr index b44a184c6848f..7d239a54eda4f 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr +++ b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr @@ -7,6 +7,10 @@ LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait { | lifetime `'a` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &'a dyn SomeTrait { + | ~~~ error: lifetime may not live long enough --> $DIR/object-lifetime-default-elision.rs:73:5 diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr index 4465dbae52989..460d2ce2cc907 100644 --- a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr +++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr @@ -5,12 +5,21 @@ LL | fn a<'a>(self: Self, a: &'a str) -> &str { | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn a<'a>(self: Self, a: &'a str) -> &'a str { + | ~~~ warning: elided lifetime has a name --> $DIR/ignore-non-reference-lifetimes.rs:10:44 | LL | fn b<'a>(self: Foo<'b>, a: &'a str) -> &str { | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` + | +help: consider specifying it explicitly + | +LL | fn b<'a>(self: Foo<'b>, a: &'a str) -> &'a str { + | ~~~ warning: 2 warnings emitted diff --git a/tests/ui/self/self_lifetime-async.stderr b/tests/ui/self/self_lifetime-async.stderr index 32de3fd18c97f..fd167cf392fb6 100644 --- a/tests/ui/self/self_lifetime-async.stderr +++ b/tests/ui/self/self_lifetime-async.stderr @@ -7,12 +7,21 @@ LL | async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } | lifetime `'b` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | async fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 } + | ~~~ warning: elided lifetime has a name --> $DIR/self_lifetime-async.rs:12:52 | LL | async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` + | +help: consider specifying it explicitly + | +LL | async fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg } + | ~~~ warning: 2 warnings emitted diff --git a/tests/ui/self/self_lifetime.stderr b/tests/ui/self/self_lifetime.stderr index cd8f4d8adf8b1..52189084f04c0 100644 --- a/tests/ui/self/self_lifetime.stderr +++ b/tests/ui/self/self_lifetime.stderr @@ -7,12 +7,21 @@ LL | fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } | lifetime `'b` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 } + | ~~~ warning: elided lifetime has a name --> $DIR/self_lifetime.rs:13:46 | LL | fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` + | +help: consider specifying it explicitly + | +LL | fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg } + | ~~~ warning: 2 warnings emitted diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr index 30f4509d49dee..92f774767c863 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr +++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr @@ -131,6 +131,10 @@ LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) { | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &'a T) { + | ~~~ error[E0658]: anonymous lifetimes in `impl Trait` are unstable --> $DIR/impl-trait-missing-lifetime-gated.rs:6:35 diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index ea01dcd5020cf..baa5fa949ec41 100644 --- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -13,6 +13,10 @@ LL | fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a | -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a + 'a + | ~~ error[E0700]: hidden type for `impl FnOnce()` captures lifetime that does not appear in bounds --> $DIR/missing-lifetimes-in-signature.rs:19:5 diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr index e2c21f1636b0c..73a362d28e7d7 100644 --- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr +++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr @@ -7,6 +7,10 @@ LL | fn defining<'a, T>(x: &'a i32) -> Opaque { x } | lifetime `'a` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default +help: consider specifying it explicitly + | +LL | fn defining<'a, T>(x: &'a i32) -> Opaque<'a, T> { x } + | ~~~~ error[E0700]: hidden type for `Opaque2` captures lifetime that does not appear in bounds --> $DIR/missing_lifetime_bound.rs:5:47 From 547db4a4b7c9bfea52b519d0095510126a0a1cb0 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sun, 1 Sep 2024 04:08:55 +0300 Subject: [PATCH 3/4] elided_named_lifetimes: manually implement `LintDiagnostic` --- compiler/rustc_lint/messages.ftl | 3 +- .../rustc_lint/src/context/diagnostics.rs | 32 +++---------- compiler/rustc_lint/src/lints.rs | 47 ++++++++++++++++--- .../async-await/issues/issue-63388-1.stderr | 2 +- .../type-dependent/issue-71348.full.stderr | 2 +- .../type-dependent/issue-71348.min.stderr | 2 +- .../consts/min_const_fn/min_const_fn.stderr | 4 +- .../rpit-assoc-pair-with-lifetime.stderr | 2 +- ...urn-type-requires-explicit-lifetime.stderr | 2 +- ...-existing-name-if-else-using-impl-3.stderr | 2 +- .../example-from-issue48686.stderr | 2 +- .../missing-lifetime-kind.stderr | 6 +-- .../not-tied-to-crate.stderr | 4 +- .../lint/elided-named-lifetimes/static.stderr | 6 +-- .../object-lifetime-default-elision.stderr | 2 +- .../ignore-non-reference-lifetimes.stderr | 4 +- tests/ui/self/self_lifetime-async.stderr | 4 +- tests/ui/self/self_lifetime.stderr | 4 +- .../impl-trait-missing-lifetime-gated.stderr | 2 +- .../missing_lifetime_bound.stderr | 2 +- 20 files changed, 75 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index fe211355ac38a..5a368f4ed9a54 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -255,8 +255,7 @@ lint_duplicate_matcher_binding = duplicate matcher binding lint_elided_named_lifetime = elided lifetime has a name .label_elided = this elided lifetime gets resolved as `{$name}` .label_named = lifetime `{$name}` declared here - -lint_elided_named_lifetime_suggestion = consider specifying it explicitly + .suggestion = consider specifying it explicitly lint_enum_intrinsics_mem_discriminant = the return value of `mem::discriminant` is unspecified when called with a non-enum type diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index a1a371a032e90..de34b9bebe9f5 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -7,7 +7,6 @@ use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; use rustc_errors::{ elided_lifetime_in_path_suggestion, Applicability, Diag, DiagArgValue, LintDiagnostic, }; -use rustc_hir::MissingLifetimeKind; use rustc_middle::middle::stability; use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution}; use rustc_session::Session; @@ -15,7 +14,6 @@ use rustc_span::symbol::kw; use rustc_span::BytePos; use tracing::debug; -use crate::fluent_generated; use crate::lints::{self, ElidedNamedLifetime}; mod check_cfg; @@ -445,31 +443,15 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag) } BuiltinLintDiag::ElidedNamedLifetimes { elided: (span, kind), resolution } => { - let (name, named_declaration) = match resolution { - ElidedLifetimeResolution::Static => (kw::StaticLifetime, None), - ElidedLifetimeResolution::Param(name, declaration) => (name, Some(declaration)), - }; - ElidedNamedLifetime { span, name, named_declaration }.decorate_lint(diag); - - let (applicability, suggestion) = match kind { - MissingLifetimeKind::Underscore => { - (Applicability::MachineApplicable, format!("{name}")) + match resolution { + ElidedLifetimeResolution::Static => { + ElidedNamedLifetime { span, kind, name: kw::StaticLifetime, declaration: None } } - MissingLifetimeKind::Ampersand => { - (Applicability::MachineApplicable, format!("&{name} ")) + ElidedLifetimeResolution::Param(name, declaration) => { + ElidedNamedLifetime { span, kind, name, declaration: Some(declaration) } } - MissingLifetimeKind::Comma => (Applicability::Unspecified, format!("<{name}, ")), - MissingLifetimeKind::Brackets => ( - Applicability::Unspecified, - format!("{}<{name}>", sess.source_map().span_to_snippet(span).unwrap()), - ), - }; - diag.span_suggestion_verbose( - span, - fluent_generated::lint_elided_named_lifetime_suggestion, - suggestion, - applicability, - ); + } + .decorate_lint(diag) } } } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 426d671f8e0a6..693f1b2258745 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -9,7 +9,7 @@ use rustc_errors::{ }; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir}; +use rustc_hir::{self as hir, MissingLifetimeKind}; use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::inhabitedness::InhabitedPredicate; use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt}; @@ -2623,14 +2623,49 @@ pub(crate) struct ElidedLifetimesInPaths { pub subdiag: ElidedLifetimeInPathSubdiag, } -#[derive(LintDiagnostic)] -#[diag(lint_elided_named_lifetime)] pub(crate) struct ElidedNamedLifetime { - #[label(lint_label_elided)] pub span: Span, + pub kind: MissingLifetimeKind, pub name: Symbol, - #[label(lint_label_named)] - pub named_declaration: Option, + pub declaration: Option, +} + +impl LintDiagnostic<'_, G> for ElidedNamedLifetime { + fn decorate_lint(self, diag: &mut rustc_errors::Diag<'_, G>) { + let Self { span, kind, name, declaration } = self; + diag.primary_message(fluent::lint_elided_named_lifetime); + diag.arg("name", name); + diag.span_label(span, fluent::lint_label_elided); + if let Some(declaration) = declaration { + diag.span_label(declaration, fluent::lint_label_named); + } + match kind { + MissingLifetimeKind::Underscore => diag.span_suggestion_verbose( + span, + fluent::lint_suggestion, + format!("{name}"), + Applicability::MachineApplicable, + ), + MissingLifetimeKind::Ampersand => diag.span_suggestion_verbose( + span.shrink_to_hi(), + fluent::lint_suggestion, + format!("{name} "), + Applicability::MachineApplicable, + ), + MissingLifetimeKind::Comma => diag.span_suggestion_verbose( + span.shrink_to_hi(), + fluent::lint_suggestion, + format!("{name}, "), + Applicability::MachineApplicable, + ), + MissingLifetimeKind::Brackets => diag.span_suggestion_verbose( + span.shrink_to_hi(), + fluent::lint_suggestion, + format!("<{name}>"), + Applicability::MachineApplicable, + ), + }; + } } #[derive(LintDiagnostic)] diff --git a/tests/ui/async-await/issues/issue-63388-1.stderr b/tests/ui/async-await/issues/issue-63388-1.stderr index c8b55977faf3a..713e4e4dcf5ca 100644 --- a/tests/ui/async-await/issues/issue-63388-1.stderr +++ b/tests/ui/async-await/issues/issue-63388-1.stderr @@ -11,7 +11,7 @@ LL | ) -> &dyn Foo help: consider specifying it explicitly | LL | ) -> &'a dyn Foo - | ~~~ + | ++ error[E0621]: explicit lifetime required in the type of `foo` --> $DIR/issue-63388-1.rs:13:5 diff --git a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr index 8d1c1ea23a81c..394259ce55ddb 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr @@ -8,7 +8,7 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Ta help: consider specifying it explicitly | LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target - | ~~~~ + | +++ warning: 1 warning emitted diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr index 57da3ce21cecd..0f0d75dbac13e 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr @@ -8,7 +8,7 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Ta help: consider specifying it explicitly | LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target - | ~~~~ + | +++ error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/issue-71348.rs:10:24 diff --git a/tests/ui/consts/min_const_fn/min_const_fn.stderr b/tests/ui/consts/min_const_fn/min_const_fn.stderr index b7db403ad16b2..1e88a908af083 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn.stderr @@ -11,7 +11,7 @@ LL | const fn get_lt(&'a self) -> &T { &self.0 } help: consider specifying it explicitly | LL | const fn get_lt(&'a self) -> &'a T { &self.0 } - | ~~~ + | ++ warning: elided lifetime has a name --> $DIR/min_const_fn.rs:48:42 @@ -25,7 +25,7 @@ LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } help: consider specifying it explicitly | LL | const fn get_mut_lt(&'a mut self) -> &'a mut T { &mut self.0 } - | ~~~ + | ++ error[E0493]: destructor of `Foo` cannot be evaluated at compile-time --> $DIR/min_const_fn.rs:37:25 diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr index ec0f0708b156f..6eea25b4fc8f8 100644 --- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr +++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr @@ -8,7 +8,7 @@ LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator { - | ~~~ + | ++ warning: 1 warning emitted diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index a7512158661fb..1339c644f5339 100644 --- a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -117,7 +117,7 @@ LL | fn m<'a>(_: &'a Foo<'a>) -> &str { "" } help: consider specifying it explicitly | LL | fn m<'a>(_: &'a Foo<'a>) -> &'a str { "" } - | ~~~ + | ++ error: aborting due to 7 previous errors; 1 warning emitted diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr index 0943e0cc0d9d4..144f9454513c5 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr @@ -10,7 +10,7 @@ LL | fn foo<'a>(&'a self, x: &i32) -> &i32 { help: consider specifying it explicitly | LL | fn foo<'a>(&'a self, x: &i32) -> &'a i32 { - | ~~~ + | ++ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:9:36 diff --git a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr index 5af5123c03237..2d8c6e996439d 100644 --- a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr +++ b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr @@ -12,7 +12,7 @@ LL | #![deny(elided_named_lifetimes)] help: consider specifying it explicitly | LL | pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 { - | ~~~~~~~~ + | +++++++ error: aborting due to 1 previous error diff --git a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr index 6abaad7f5d218..834292d103dc8 100644 --- a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr +++ b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr @@ -14,7 +14,7 @@ LL | #![deny(elided_named_lifetimes)] help: consider specifying it explicitly | LL | fn ampersand<'a>(x: &'a u8) -> &'a u8 { - | ~~~ + | ++ error: elided lifetime has a name --> $DIR/missing-lifetime-kind.rs:10:31 @@ -27,7 +27,7 @@ LL | fn brackets<'a>(x: &'a u8) -> Brackets { help: consider specifying it explicitly | LL | fn brackets<'a>(x: &'a u8) -> Brackets<'a> { - | ~~~~~~~~~~~~ + | ++++ error: elided lifetime has a name --> $DIR/missing-lifetime-kind.rs:17:33 @@ -40,7 +40,7 @@ LL | fn comma<'a>(x: &'a u8) -> Comma { help: consider specifying it explicitly | LL | fn comma<'a>(x: &'a u8) -> Comma<'a, u8> { - | ~~~~ + | +++ error: elided lifetime has a name --> $DIR/missing-lifetime-kind.rs:22:34 diff --git a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr index cbc1b862caabd..3c01375d50191 100644 --- a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr +++ b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr @@ -12,7 +12,7 @@ LL | #[warn(elided_named_lifetimes)] help: consider specifying it explicitly | LL | fn bar(x: &'static u8) -> &'static u8 { - | ~~~~~~~~ + | +++++++ error: elided lifetime has a name --> $DIR/not-tied-to-crate.rs:11:31 @@ -28,7 +28,7 @@ LL | #[deny(elided_named_lifetimes)] help: consider specifying it explicitly | LL | fn baz(x: &'static u8) -> &'static u8 { - | ~~~~~~~~ + | +++++++ error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/lint/elided-named-lifetimes/static.stderr b/tests/ui/lint/elided-named-lifetimes/static.stderr index 6c3944e5ea580..fa2a2d3460fea 100644 --- a/tests/ui/lint/elided-named-lifetimes/static.stderr +++ b/tests/ui/lint/elided-named-lifetimes/static.stderr @@ -12,7 +12,7 @@ LL | #![deny(elided_named_lifetimes)] help: consider specifying it explicitly | LL | fn ampersand(x: &'static u8) -> &'static u8 { - | ~~~~~~~~ + | +++++++ error: elided lifetime has a name --> $DIR/static.rs:23:32 @@ -23,7 +23,7 @@ LL | fn brackets(x: &'static u8) -> Brackets { help: consider specifying it explicitly | LL | fn brackets(x: &'static u8) -> Brackets<'static> { - | ~~~~~~~~~~~~~~~~~ + | +++++++++ error: elided lifetime has a name --> $DIR/static.rs:30:34 @@ -34,7 +34,7 @@ LL | fn comma(x: &'static u8) -> Comma { help: consider specifying it explicitly | LL | fn comma(x: &'static u8) -> Comma<'static, u8> { - | ~~~~~~~~~ + | ++++++++ error: elided lifetime has a name --> $DIR/static.rs:35:35 diff --git a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr index 7d239a54eda4f..f8ed92111a967 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr +++ b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr @@ -10,7 +10,7 @@ LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait { help: consider specifying it explicitly | LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &'a dyn SomeTrait { - | ~~~ + | ++ error: lifetime may not live long enough --> $DIR/object-lifetime-default-elision.rs:73:5 diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr index 460d2ce2cc907..13cc3a431a5d2 100644 --- a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr +++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr @@ -8,7 +8,7 @@ LL | fn a<'a>(self: Self, a: &'a str) -> &str { help: consider specifying it explicitly | LL | fn a<'a>(self: Self, a: &'a str) -> &'a str { - | ~~~ + | ++ warning: elided lifetime has a name --> $DIR/ignore-non-reference-lifetimes.rs:10:44 @@ -19,7 +19,7 @@ LL | fn b<'a>(self: Foo<'b>, a: &'a str) -> &str { help: consider specifying it explicitly | LL | fn b<'a>(self: Foo<'b>, a: &'a str) -> &'a str { - | ~~~ + | ++ warning: 2 warnings emitted diff --git a/tests/ui/self/self_lifetime-async.stderr b/tests/ui/self/self_lifetime-async.stderr index fd167cf392fb6..2892d790ac7b8 100644 --- a/tests/ui/self/self_lifetime-async.stderr +++ b/tests/ui/self/self_lifetime-async.stderr @@ -10,7 +10,7 @@ LL | async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } help: consider specifying it explicitly | LL | async fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 } - | ~~~ + | ++ warning: elided lifetime has a name --> $DIR/self_lifetime-async.rs:12:52 @@ -21,7 +21,7 @@ LL | async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } help: consider specifying it explicitly | LL | async fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg } - | ~~~ + | ++ warning: 2 warnings emitted diff --git a/tests/ui/self/self_lifetime.stderr b/tests/ui/self/self_lifetime.stderr index 52189084f04c0..ceb0ce345a3eb 100644 --- a/tests/ui/self/self_lifetime.stderr +++ b/tests/ui/self/self_lifetime.stderr @@ -10,7 +10,7 @@ LL | fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } help: consider specifying it explicitly | LL | fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 } - | ~~~ + | ++ warning: elided lifetime has a name --> $DIR/self_lifetime.rs:13:46 @@ -21,7 +21,7 @@ LL | fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } help: consider specifying it explicitly | LL | fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg } - | ~~~ + | ++ warning: 2 warnings emitted diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr index 92f774767c863..3744dd9f996ce 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr +++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr @@ -134,7 +134,7 @@ LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) { help: consider specifying it explicitly | LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &'a T) { - | ~~~ + | ++ error[E0658]: anonymous lifetimes in `impl Trait` are unstable --> $DIR/impl-trait-missing-lifetime-gated.rs:6:35 diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr index 73a362d28e7d7..376e58ef9e07e 100644 --- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr +++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr @@ -10,7 +10,7 @@ LL | fn defining<'a, T>(x: &'a i32) -> Opaque { x } help: consider specifying it explicitly | LL | fn defining<'a, T>(x: &'a i32) -> Opaque<'a, T> { x } - | ~~~~ + | +++ error[E0700]: hidden type for `Opaque2` captures lifetime that does not appear in bounds --> $DIR/missing_lifetime_bound.rs:5:47 From 9e2d264fa251f98780084382a071e10a123770d6 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sun, 1 Sep 2024 16:49:55 +0300 Subject: [PATCH 4/4] Hack around a conflict with `clippy::needless_lifetimes` --- compiler/rustc_lint/src/lints.rs | 7 +++++++ .../async-await/issues/issue-63388-1.stderr | 4 ---- .../type-dependent/issue-71348.full.stderr | 4 ---- .../type-dependent/issue-71348.min.stderr | 4 ---- .../consts/min_const_fn/min_const_fn.stderr | 9 --------- .../ui/impl-trait/impl-fn-hrtb-bounds.stderr | 4 ---- .../impl-fn-predefined-lifetimes.stderr | 4 ---- .../rpit-assoc-pair-with-lifetime.stderr | 4 ---- ...urn-type-requires-explicit-lifetime.stderr | 4 ---- ...-existing-name-if-else-using-impl-3.stderr | 4 ---- .../missing-lifetime-kind.stderr | 19 ------------------- .../object-lifetime-default-elision.stderr | 4 ---- .../ignore-non-reference-lifetimes.stderr | 9 --------- tests/ui/self/self_lifetime-async.stderr | 9 --------- tests/ui/self/self_lifetime.stderr | 9 --------- .../impl-trait-missing-lifetime-gated.stderr | 4 ---- .../missing-lifetimes-in-signature.stderr | 4 ---- .../missing_lifetime_bound.stderr | 4 ---- 18 files changed, 7 insertions(+), 103 deletions(-) diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 693f1b2258745..ae7e965985635 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2639,6 +2639,13 @@ impl LintDiagnostic<'_, G> for ElidedNamedLifetime { if let Some(declaration) = declaration { diag.span_label(declaration, fluent::lint_label_named); } + // FIXME(GrigorenkoPV): this `if` and `return` should be removed, + // but currently this lint's suggestions can conflict with those of `clippy::needless_lifetimes`: + // https://github.com/rust-lang/rust/pull/129840#issuecomment-2323349119 + // HACK: `'static` suggestions will never sonflict, emit only those for now. + if name != rustc_span::symbol::kw::StaticLifetime { + return; + } match kind { MissingLifetimeKind::Underscore => diag.span_suggestion_verbose( span, diff --git a/tests/ui/async-await/issues/issue-63388-1.stderr b/tests/ui/async-await/issues/issue-63388-1.stderr index 713e4e4dcf5ca..ef74bfe32375e 100644 --- a/tests/ui/async-await/issues/issue-63388-1.stderr +++ b/tests/ui/async-await/issues/issue-63388-1.stderr @@ -8,10 +8,6 @@ LL | ) -> &dyn Foo | ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | ) -> &'a dyn Foo - | ++ error[E0621]: explicit lifetime required in the type of `foo` --> $DIR/issue-63388-1.rs:13:5 diff --git a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr index 394259ce55ddb..177ff20fbf9ea 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr @@ -5,10 +5,6 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Ta | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target - | +++ warning: 1 warning emitted diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr index 0f0d75dbac13e..5aee282952aa2 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr @@ -5,10 +5,6 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Ta | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target - | +++ error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/issue-71348.rs:10:24 diff --git a/tests/ui/consts/min_const_fn/min_const_fn.stderr b/tests/ui/consts/min_const_fn/min_const_fn.stderr index 1e88a908af083..4b348a182b87f 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn.stderr @@ -8,10 +8,6 @@ LL | const fn get_lt(&'a self) -> &T { &self.0 } | ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | const fn get_lt(&'a self) -> &'a T { &self.0 } - | ++ warning: elided lifetime has a name --> $DIR/min_const_fn.rs:48:42 @@ -21,11 +17,6 @@ LL | impl<'a, T> Foo { ... LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } | ^ this elided lifetime gets resolved as `'a` - | -help: consider specifying it explicitly - | -LL | const fn get_mut_lt(&'a mut self) -> &'a mut T { &mut self.0 } - | ++ error[E0493]: destructor of `Foo` cannot be evaluated at compile-time --> $DIR/min_const_fn.rs:37:25 diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr index ccea9d5e6e92a..d0f8f7689d17c 100644 --- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr +++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr @@ -17,10 +17,6 @@ LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { | -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { - | ~~ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` --> $DIR/impl-fn-hrtb-bounds.rs:4:41 diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr index a60f398684330..50a9f3ebeabb8 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr @@ -5,10 +5,6 @@ LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { | -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + 'a) { - | ~~ error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/impl-fn-predefined-lifetimes.rs:7:9 diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr index 6eea25b4fc8f8..bff3ffd934ac6 100644 --- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr +++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr @@ -5,10 +5,6 @@ LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator { - | ++ warning: 1 warning emitted diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index 1339c644f5339..f835d2655bb01 100644 --- a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -114,10 +114,6 @@ LL | fn m<'a>(_: &'a Foo<'a>) -> &str { "" } | lifetime `'a` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn m<'a>(_: &'a Foo<'a>) -> &'a str { "" } - | ++ error: aborting due to 7 previous errors; 1 warning emitted diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr index 144f9454513c5..2d5d4fb0e72ec 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr @@ -7,10 +7,6 @@ LL | fn foo<'a>(&'a self, x: &i32) -> &i32 { | lifetime `'a` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn foo<'a>(&'a self, x: &i32) -> &'a i32 { - | ++ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:9:36 diff --git a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr index 834292d103dc8..249ae146b1675 100644 --- a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr +++ b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr @@ -11,10 +11,6 @@ note: the lint level is defined here | LL | #![deny(elided_named_lifetimes)] | ^^^^^^^^^^^^^^^^^^^^^^ -help: consider specifying it explicitly - | -LL | fn ampersand<'a>(x: &'a u8) -> &'a u8 { - | ++ error: elided lifetime has a name --> $DIR/missing-lifetime-kind.rs:10:31 @@ -23,11 +19,6 @@ LL | fn brackets<'a>(x: &'a u8) -> Brackets { | -- ^^^^^^^^ this elided lifetime gets resolved as `'a` | | | lifetime `'a` declared here - | -help: consider specifying it explicitly - | -LL | fn brackets<'a>(x: &'a u8) -> Brackets<'a> { - | ++++ error: elided lifetime has a name --> $DIR/missing-lifetime-kind.rs:17:33 @@ -36,11 +27,6 @@ LL | fn comma<'a>(x: &'a u8) -> Comma { | -- ^ this elided lifetime gets resolved as `'a` | | | lifetime `'a` declared here - | -help: consider specifying it explicitly - | -LL | fn comma<'a>(x: &'a u8) -> Comma<'a, u8> { - | +++ error: elided lifetime has a name --> $DIR/missing-lifetime-kind.rs:22:34 @@ -49,11 +35,6 @@ LL | fn underscore<'a>(x: &'a u8) -> &'_ u8 { | -- ^^ this elided lifetime gets resolved as `'a` | | | lifetime `'a` declared here - | -help: consider specifying it explicitly - | -LL | fn underscore<'a>(x: &'a u8) -> &'a u8 { - | ~~ error: aborting due to 4 previous errors diff --git a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr index f8ed92111a967..b44a184c6848f 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr +++ b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr @@ -7,10 +7,6 @@ LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait { | lifetime `'a` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &'a dyn SomeTrait { - | ++ error: lifetime may not live long enough --> $DIR/object-lifetime-default-elision.rs:73:5 diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr index 13cc3a431a5d2..4465dbae52989 100644 --- a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr +++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr @@ -5,21 +5,12 @@ LL | fn a<'a>(self: Self, a: &'a str) -> &str { | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn a<'a>(self: Self, a: &'a str) -> &'a str { - | ++ warning: elided lifetime has a name --> $DIR/ignore-non-reference-lifetimes.rs:10:44 | LL | fn b<'a>(self: Foo<'b>, a: &'a str) -> &str { | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` - | -help: consider specifying it explicitly - | -LL | fn b<'a>(self: Foo<'b>, a: &'a str) -> &'a str { - | ++ warning: 2 warnings emitted diff --git a/tests/ui/self/self_lifetime-async.stderr b/tests/ui/self/self_lifetime-async.stderr index 2892d790ac7b8..32de3fd18c97f 100644 --- a/tests/ui/self/self_lifetime-async.stderr +++ b/tests/ui/self/self_lifetime-async.stderr @@ -7,21 +7,12 @@ LL | async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } | lifetime `'b` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | async fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 } - | ++ warning: elided lifetime has a name --> $DIR/self_lifetime-async.rs:12:52 | LL | async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` - | -help: consider specifying it explicitly - | -LL | async fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg } - | ++ warning: 2 warnings emitted diff --git a/tests/ui/self/self_lifetime.stderr b/tests/ui/self/self_lifetime.stderr index ceb0ce345a3eb..cd8f4d8adf8b1 100644 --- a/tests/ui/self/self_lifetime.stderr +++ b/tests/ui/self/self_lifetime.stderr @@ -7,21 +7,12 @@ LL | fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } | lifetime `'b` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 } - | ++ warning: elided lifetime has a name --> $DIR/self_lifetime.rs:13:46 | LL | fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` - | -help: consider specifying it explicitly - | -LL | fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg } - | ++ warning: 2 warnings emitted diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr index 3744dd9f996ce..30f4509d49dee 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr +++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr @@ -131,10 +131,6 @@ LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) { | -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &'a T) { - | ++ error[E0658]: anonymous lifetimes in `impl Trait` are unstable --> $DIR/impl-trait-missing-lifetime-gated.rs:6:35 diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index baa5fa949ec41..ea01dcd5020cf 100644 --- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -13,10 +13,6 @@ LL | fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a | -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a` | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a + 'a - | ~~ error[E0700]: hidden type for `impl FnOnce()` captures lifetime that does not appear in bounds --> $DIR/missing-lifetimes-in-signature.rs:19:5 diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr index 376e58ef9e07e..e2c21f1636b0c 100644 --- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr +++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr @@ -7,10 +7,6 @@ LL | fn defining<'a, T>(x: &'a i32) -> Opaque { x } | lifetime `'a` declared here | = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -LL | fn defining<'a, T>(x: &'a i32) -> Opaque<'a, T> { x } - | +++ error[E0700]: hidden type for `Opaque2` captures lifetime that does not appear in bounds --> $DIR/missing_lifetime_bound.rs:5:47