Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 41a20dc

Browse files
authoredSep 7, 2024
Rollup merge of rust-lang#129840 - GrigorenkoPV:elided-named-lifetimes-suggestion, r=cjgillot
Implement suggestions for `elided_named_lifetimes` A follow-up to rust-lang#129207, as per rust-lang#129207 (comment). r? cjgillot I will probably squash this a bit, but later. `@rustbot` label +A-lint
2 parents 040be55 + 9e2d264 commit 41a20dc

File tree

8 files changed

+111
-29
lines changed

8 files changed

+111
-29
lines changed
 

‎compiler/rustc_lint/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ lint_duplicate_matcher_binding = duplicate matcher binding
255255
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
258+
.suggestion = consider specifying it explicitly
258259
259260
lint_enum_intrinsics_mem_discriminant =
260261
the return value of `mem::discriminant` is unspecified when called with a non-enum type

‎compiler/rustc_lint/src/context/diagnostics.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ use rustc_errors::{
88
elided_lifetime_in_path_suggestion, Applicability, Diag, DiagArgValue, LintDiagnostic,
99
};
1010
use rustc_middle::middle::stability;
11-
use rustc_session::lint::BuiltinLintDiag;
11+
use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution};
1212
use rustc_session::Session;
1313
use rustc_span::symbol::kw;
1414
use rustc_span::BytePos;
1515
use tracing::debug;
1616

17-
use crate::lints;
17+
use crate::lints::{self, ElidedNamedLifetime};
1818

1919
mod check_cfg;
2020

@@ -442,15 +442,14 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
442442
BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => {
443443
lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag)
444444
}
445-
BuiltinLintDiag::ElidedIsStatic { elided } => {
446-
lints::ElidedNamedLifetime { elided, name: kw::StaticLifetime, named_declaration: None }
447-
.decorate_lint(diag)
448-
}
449-
BuiltinLintDiag::ElidedIsParam { elided, param: (param_name, param_span) } => {
450-
lints::ElidedNamedLifetime {
451-
elided,
452-
name: param_name,
453-
named_declaration: Some(param_span),
445+
BuiltinLintDiag::ElidedNamedLifetimes { elided: (span, kind), resolution } => {
446+
match resolution {
447+
ElidedLifetimeResolution::Static => {
448+
ElidedNamedLifetime { span, kind, name: kw::StaticLifetime, declaration: None }
449+
}
450+
ElidedLifetimeResolution::Param(name, declaration) => {
451+
ElidedNamedLifetime { span, kind, name, declaration: Some(declaration) }
452+
}
454453
}
455454
.decorate_lint(diag)
456455
}

‎compiler/rustc_lint/src/lints.rs

+49-7
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_errors::{
99
};
1010
use rustc_hir::def::Namespace;
1111
use rustc_hir::def_id::DefId;
12-
use rustc_hir::{self as hir};
12+
use rustc_hir::{self as hir, MissingLifetimeKind};
1313
use rustc_macros::{LintDiagnostic, Subdiagnostic};
1414
use rustc_middle::ty::inhabitedness::InhabitedPredicate;
1515
use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt};
@@ -2623,14 +2623,56 @@ pub(crate) struct ElidedLifetimesInPaths {
26232623
pub subdiag: ElidedLifetimeInPathSubdiag,
26242624
}
26252625

2626-
#[derive(LintDiagnostic)]
2627-
#[diag(lint_elided_named_lifetime)]
26282626
pub(crate) struct ElidedNamedLifetime {
2629-
#[label(lint_label_elided)]
2630-
pub elided: Span,
2627+
pub span: Span,
2628+
pub kind: MissingLifetimeKind,
26312629
pub name: Symbol,
2632-
#[label(lint_label_named)]
2633-
pub named_declaration: Option<Span>,
2630+
pub declaration: Option<Span>,
2631+
}
2632+
2633+
impl<G: EmissionGuarantee> LintDiagnostic<'_, G> for ElidedNamedLifetime {
2634+
fn decorate_lint(self, diag: &mut rustc_errors::Diag<'_, G>) {
2635+
let Self { span, kind, name, declaration } = self;
2636+
diag.primary_message(fluent::lint_elided_named_lifetime);
2637+
diag.arg("name", name);
2638+
diag.span_label(span, fluent::lint_label_elided);
2639+
if let Some(declaration) = declaration {
2640+
diag.span_label(declaration, fluent::lint_label_named);
2641+
}
2642+
// FIXME(GrigorenkoPV): this `if` and `return` should be removed,
2643+
// but currently this lint's suggestions can conflict with those of `clippy::needless_lifetimes`:
2644+
// https://github.com/rust-lang/rust/pull/129840#issuecomment-2323349119
2645+
// HACK: `'static` suggestions will never sonflict, emit only those for now.
2646+
if name != rustc_span::symbol::kw::StaticLifetime {
2647+
return;
2648+
}
2649+
match kind {
2650+
MissingLifetimeKind::Underscore => diag.span_suggestion_verbose(
2651+
span,
2652+
fluent::lint_suggestion,
2653+
format!("{name}"),
2654+
Applicability::MachineApplicable,
2655+
),
2656+
MissingLifetimeKind::Ampersand => diag.span_suggestion_verbose(
2657+
span.shrink_to_hi(),
2658+
fluent::lint_suggestion,
2659+
format!("{name} "),
2660+
Applicability::MachineApplicable,
2661+
),
2662+
MissingLifetimeKind::Comma => diag.span_suggestion_verbose(
2663+
span.shrink_to_hi(),
2664+
fluent::lint_suggestion,
2665+
format!("{name}, "),
2666+
Applicability::MachineApplicable,
2667+
),
2668+
MissingLifetimeKind::Brackets => diag.span_suggestion_verbose(
2669+
span.shrink_to_hi(),
2670+
fluent::lint_suggestion,
2671+
format!("<{name}>"),
2672+
Applicability::MachineApplicable,
2673+
),
2674+
};
2675+
}
26342676
}
26352677

26362678
#[derive(LintDiagnostic)]

‎compiler/rustc_lint_defs/src/lib.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_data_structures::stable_hasher::{
1010
};
1111
use rustc_error_messages::{DiagMessage, MultiSpan};
1212
use rustc_hir::def::Namespace;
13-
use rustc_hir::{HashStableContext, HirId};
13+
use rustc_hir::{HashStableContext, HirId, MissingLifetimeKind};
1414
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
1515
use rustc_span::edition::Edition;
1616
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
@@ -556,6 +556,12 @@ pub enum DeprecatedSinceKind {
556556
InVersion(String),
557557
}
558558

559+
#[derive(Debug)]
560+
pub enum ElidedLifetimeResolution {
561+
Static,
562+
Param(Symbol, Span),
563+
}
564+
559565
// This could be a closure, but then implementing derive trait
560566
// becomes hacky (and it gets allocated).
561567
#[derive(Debug)]
@@ -568,12 +574,9 @@ pub enum BuiltinLintDiag {
568574
},
569575
MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
570576
ElidedLifetimesInPaths(usize, Span, bool, Span),
571-
ElidedIsStatic {
572-
elided: Span,
573-
},
574-
ElidedIsParam {
575-
elided: Span,
576-
param: (Symbol, Span),
577+
ElidedNamedLifetimes {
578+
elided: (Span, MissingLifetimeKind),
579+
resolution: ElidedLifetimeResolution,
577580
},
578581
UnknownCrateTypes {
579582
span: Span,

‎compiler/rustc_resolve/src/late.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -2062,7 +2062,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
20622062
lint::builtin::ELIDED_NAMED_LIFETIMES,
20632063
missing.id_for_lint,
20642064
missing.span,
2065-
BuiltinLintDiag::ElidedIsStatic { elided: missing.span },
2065+
BuiltinLintDiag::ElidedNamedLifetimes {
2066+
elided: (missing.span, missing.kind),
2067+
resolution: lint::ElidedLifetimeResolution::Static,
2068+
},
20662069
);
20672070
}
20682071
}
@@ -2072,9 +2075,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
20722075
lint::builtin::ELIDED_NAMED_LIFETIMES,
20732076
missing.id_for_lint,
20742077
missing.span,
2075-
BuiltinLintDiag::ElidedIsParam {
2076-
elided: missing.span,
2077-
param: (tcx.item_name(param.into()), tcx.source_span(param)),
2078+
BuiltinLintDiag::ElidedNamedLifetimes {
2079+
elided: (missing.span, missing.kind),
2080+
resolution: lint::ElidedLifetimeResolution::Param(
2081+
tcx.item_name(param.into()),
2082+
tcx.source_span(param),
2083+
),
20782084
},
20792085
);
20802086
}

‎tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ note: the lint level is defined here
99
|
1010
LL | #![deny(elided_named_lifetimes)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^
12+
help: consider specifying it explicitly
13+
|
14+
LL | pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 {
15+
| +++++++
1216

1317
error: aborting due to 1 previous error
1418

‎tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ note: the lint level is defined here
99
|
1010
LL | #[warn(elided_named_lifetimes)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^
12+
help: consider specifying it explicitly
13+
|
14+
LL | fn bar(x: &'static u8) -> &'static u8 {
15+
| +++++++
1216

1317
error: elided lifetime has a name
1418
--> $DIR/not-tied-to-crate.rs:11:31
@@ -21,6 +25,10 @@ note: the lint level is defined here
2125
|
2226
LL | #[deny(elided_named_lifetimes)]
2327
| ^^^^^^^^^^^^^^^^^^^^^^
28+
help: consider specifying it explicitly
29+
|
30+
LL | fn baz(x: &'static u8) -> &'static u8 {
31+
| +++++++
2432

2533
error: aborting due to 1 previous error; 1 warning emitted
2634

‎tests/ui/lint/elided-named-lifetimes/static.stderr

+19
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,43 @@ note: the lint level is defined here
99
|
1010
LL | #![deny(elided_named_lifetimes)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^
12+
help: consider specifying it explicitly
13+
|
14+
LL | fn ampersand(x: &'static u8) -> &'static u8 {
15+
| +++++++
1216

1317
error: elided lifetime has a name
1418
--> $DIR/static.rs:23:32
1519
|
1620
LL | fn brackets(x: &'static u8) -> Brackets {
1721
| ^^^^^^^^ this elided lifetime gets resolved as `'static`
22+
|
23+
help: consider specifying it explicitly
24+
|
25+
LL | fn brackets(x: &'static u8) -> Brackets<'static> {
26+
| +++++++++
1827

1928
error: elided lifetime has a name
2029
--> $DIR/static.rs:30:34
2130
|
2231
LL | fn comma(x: &'static u8) -> Comma<u8> {
2332
| ^ this elided lifetime gets resolved as `'static`
33+
|
34+
help: consider specifying it explicitly
35+
|
36+
LL | fn comma(x: &'static u8) -> Comma<'static, u8> {
37+
| ++++++++
2438

2539
error: elided lifetime has a name
2640
--> $DIR/static.rs:35:35
2741
|
2842
LL | fn underscore(x: &'static u8) -> &'_ u8 {
2943
| ^^ this elided lifetime gets resolved as `'static`
44+
|
45+
help: consider specifying it explicitly
46+
|
47+
LL | fn underscore(x: &'static u8) -> &'static u8 {
48+
| ~~~~~~~
3049

3150
error: aborting due to 4 previous errors
3251

0 commit comments

Comments
 (0)
Failed to load comments.