Skip to content

Commit dcfc713

Browse files
committed
elided_named_lifetimes: add suggestions
1 parent e38764d commit dcfc713

23 files changed

+166
-16
lines changed

compiler/rustc_lint/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ lint_elided_named_lifetime = elided lifetime has a name
256256
.label_elided = this elided lifetime gets resolved as `{$name}`
257257
.label_named = lifetime `{$name}` declared here
258258
259+
lint_elided_named_lifetime_suggestion = consider specifying it explicitly
260+
259261
lint_enum_intrinsics_mem_discriminant =
260262
the return value of `mem::discriminant` is unspecified when called with a non-enum type
261263
.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

compiler/rustc_lint/src/context/diagnostics.rs

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@ use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
77
use rustc_errors::{
88
elided_lifetime_in_path_suggestion, Applicability, Diag, DiagArgValue, LintDiagnostic,
99
};
10+
use rustc_hir::MissingLifetimeKind;
1011
use rustc_middle::middle::stability;
1112
use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution};
1213
use rustc_session::Session;
1314
use rustc_span::symbol::kw;
1415
use rustc_span::BytePos;
1516
use tracing::debug;
1617

17-
use crate::lints;
18+
use crate::fluent_generated;
19+
use crate::lints::{self, ElidedNamedLifetime};
1820

1921
mod check_cfg;
2022

@@ -442,20 +444,32 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
442444
BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => {
443445
lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag)
444446
}
445-
BuiltinLintDiag::ElidedNamedLifetimes { elided: (elided, _kind), resolution } => {
446-
match resolution {
447-
ElidedLifetimeResolution::Static => lints::ElidedNamedLifetime {
448-
elided,
449-
name: kw::StaticLifetime,
450-
named_declaration: None,
451-
},
452-
ElidedLifetimeResolution::Param(name, declaration) => lints::ElidedNamedLifetime {
453-
elided,
454-
name,
455-
named_declaration: Some(declaration),
456-
},
457-
}
458-
.decorate_lint(diag)
447+
BuiltinLintDiag::ElidedNamedLifetimes { elided: (span, kind), resolution } => {
448+
let (name, named_declaration) = match resolution {
449+
ElidedLifetimeResolution::Static => (kw::StaticLifetime, None),
450+
ElidedLifetimeResolution::Param(name, declaration) => (name, Some(declaration)),
451+
};
452+
ElidedNamedLifetime { span, name, named_declaration }.decorate_lint(diag);
453+
454+
let (applicability, suggestion) = match kind {
455+
MissingLifetimeKind::Underscore => {
456+
(Applicability::MachineApplicable, format!("{name}"))
457+
}
458+
MissingLifetimeKind::Ampersand => {
459+
(Applicability::MachineApplicable, format!("&{name} "))
460+
}
461+
MissingLifetimeKind::Comma => (Applicability::Unspecified, format!("<{name}, ")),
462+
MissingLifetimeKind::Brackets => (
463+
Applicability::Unspecified,
464+
format!("{}<{name}>", sess.source_map().span_to_snippet(span).unwrap()),
465+
),
466+
};
467+
diag.span_suggestion_verbose(
468+
span,
469+
fluent_generated::lint_elided_named_lifetime_suggestion,
470+
suggestion,
471+
applicability,
472+
);
459473
}
460474
}
461475
}

compiler/rustc_lint/src/lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2627,7 +2627,7 @@ pub(crate) struct ElidedLifetimesInPaths {
26272627
#[diag(lint_elided_named_lifetime)]
26282628
pub(crate) struct ElidedNamedLifetime {
26292629
#[label(lint_label_elided)]
2630-
pub elided: Span,
2630+
pub span: Span,
26312631
pub name: Symbol,
26322632
#[label(lint_label_named)]
26332633
pub named_declaration: Option<Span>,

tests/ui/async-await/issues/issue-63388-1.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ LL | ) -> &dyn Foo
88
| ^ this elided lifetime gets resolved as `'a`
99
|
1010
= note: `#[warn(elided_named_lifetimes)]` on by default
11+
help: consider specifying it explicitly
12+
|
13+
LL | ) -> &'a dyn Foo
14+
| ~~~
1115

1216
error[E0621]: explicit lifetime required in the type of `foo`
1317
--> $DIR/issue-63388-1.rs:13:5

tests/ui/const-generics/type-dependent/issue-71348.full.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Ta
55
| -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a`
66
|
77
= note: `#[warn(elided_named_lifetimes)]` on by default
8+
help: consider specifying it explicitly
9+
|
10+
LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<'a, N>>::Target
11+
| ~~~~
812

913
warning: 1 warning emitted
1014

tests/ui/const-generics/type-dependent/issue-71348.min.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Ta
55
| -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a`
66
|
77
= note: `#[warn(elided_named_lifetimes)]` on by default
8+
help: consider specifying it explicitly
9+
|
10+
LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<'a, N>>::Target
11+
| ~~~~
812

913
error: `&'static str` is forbidden as the type of a const generic parameter
1014
--> $DIR/issue-71348.rs:10:24

tests/ui/consts/min_const_fn/min_const_fn.stderr

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ LL | const fn get_lt(&'a self) -> &T { &self.0 }
88
| ^ this elided lifetime gets resolved as `'a`
99
|
1010
= note: `#[warn(elided_named_lifetimes)]` on by default
11+
help: consider specifying it explicitly
12+
|
13+
LL | const fn get_lt(&'a self) -> &'a T { &self.0 }
14+
| ~~~
1115

1216
warning: elided lifetime has a name
1317
--> $DIR/min_const_fn.rs:48:42
@@ -17,6 +21,11 @@ LL | impl<'a, T> Foo<T> {
1721
...
1822
LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
1923
| ^ this elided lifetime gets resolved as `'a`
24+
|
25+
help: consider specifying it explicitly
26+
|
27+
LL | const fn get_mut_lt(&'a mut self) -> &'a mut T { &mut self.0 }
28+
| ~~~
2029

2130
error[E0493]: destructor of `Foo<T>` cannot be evaluated at compile-time
2231
--> $DIR/min_const_fn.rs:37:25

tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
1717
| -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a`
1818
|
1919
= note: `#[warn(elided_named_lifetimes)]` on by default
20+
help: consider specifying it explicitly
21+
|
22+
LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
23+
| ~~
2024

2125
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
2226
--> $DIR/impl-fn-hrtb-bounds.rs:4:41

tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
55
| -- lifetime `'a` declared here ^^ this elided lifetime gets resolved as `'a`
66
|
77
= note: `#[warn(elided_named_lifetimes)]` on by default
8+
help: consider specifying it explicitly
9+
|
10+
LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + 'a) {
11+
| ~~
812

913
error[E0792]: expected generic lifetime parameter, found `'_`
1014
--> $DIR/impl-fn-predefined-lifetimes.rs:7:9

tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item =
55
| -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a`
66
|
77
= note: `#[warn(elided_named_lifetimes)]` on by default
8+
help: consider specifying it explicitly
9+
|
10+
LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &'a u32)> {
11+
| ~~~
812

913
warning: 1 warning emitted
1014

0 commit comments

Comments
 (0)