Rollup merge of #129840 - GrigorenkoPV:elided-named-lifetimes-suggestion, r=cjgillot
Implement suggestions for `elided_named_lifetimes` A follow-up to #129207, as per https://github.com/rust-lang/rust/pull/129207#issuecomment-2308992849. r? cjgillot I will probably squash this a bit, but later. `@rustbot` label +A-lint
This commit is contained in:
commit
41a20dcb87
@ -255,6 +255,7 @@ lint_duplicate_matcher_binding = duplicate matcher binding
|
|||||||
lint_elided_named_lifetime = elided lifetime has a name
|
lint_elided_named_lifetime = elided lifetime has a name
|
||||||
.label_elided = this elided lifetime gets resolved as `{$name}`
|
.label_elided = this elided lifetime gets resolved as `{$name}`
|
||||||
.label_named = lifetime `{$name}` declared here
|
.label_named = lifetime `{$name}` declared here
|
||||||
|
.suggestion = consider specifying it explicitly
|
||||||
|
|
||||||
lint_enum_intrinsics_mem_discriminant =
|
lint_enum_intrinsics_mem_discriminant =
|
||||||
the return value of `mem::discriminant` is unspecified when called with a non-enum type
|
the return value of `mem::discriminant` is unspecified when called with a non-enum type
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
elided_lifetime_in_path_suggestion, Applicability, Diag, DiagArgValue, LintDiagnostic,
|
elided_lifetime_in_path_suggestion, Applicability, Diag, DiagArgValue, LintDiagnostic,
|
||||||
};
|
};
|
||||||
use rustc_middle::middle::stability;
|
use rustc_middle::middle::stability;
|
||||||
use rustc_session::lint::BuiltinLintDiag;
|
use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::kw;
|
use rustc_span::symbol::kw;
|
||||||
use rustc_span::BytePos;
|
use rustc_span::BytePos;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::lints;
|
use crate::lints::{self, ElidedNamedLifetime};
|
||||||
|
|
||||||
mod check_cfg;
|
mod check_cfg;
|
||||||
|
|
||||||
@ -442,15 +442,14 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
|
|||||||
BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => {
|
BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => {
|
||||||
lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag)
|
lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag)
|
||||||
}
|
}
|
||||||
BuiltinLintDiag::ElidedIsStatic { elided } => {
|
BuiltinLintDiag::ElidedNamedLifetimes { elided: (span, kind), resolution } => {
|
||||||
lints::ElidedNamedLifetime { elided, name: kw::StaticLifetime, named_declaration: None }
|
match resolution {
|
||||||
.decorate_lint(diag)
|
ElidedLifetimeResolution::Static => {
|
||||||
}
|
ElidedNamedLifetime { span, kind, name: kw::StaticLifetime, declaration: None }
|
||||||
BuiltinLintDiag::ElidedIsParam { elided, param: (param_name, param_span) } => {
|
}
|
||||||
lints::ElidedNamedLifetime {
|
ElidedLifetimeResolution::Param(name, declaration) => {
|
||||||
elided,
|
ElidedNamedLifetime { span, kind, name, declaration: Some(declaration) }
|
||||||
name: param_name,
|
}
|
||||||
named_declaration: Some(param_span),
|
|
||||||
}
|
}
|
||||||
.decorate_lint(diag)
|
.decorate_lint(diag)
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
};
|
};
|
||||||
use rustc_hir::def::Namespace;
|
use rustc_hir::def::Namespace;
|
||||||
use rustc_hir::def_id::DefId;
|
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_macros::{LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::inhabitedness::InhabitedPredicate;
|
use rustc_middle::ty::inhabitedness::InhabitedPredicate;
|
||||||
use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt};
|
use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt};
|
||||||
@ -2623,14 +2623,56 @@ pub(crate) struct ElidedLifetimesInPaths {
|
|||||||
pub subdiag: ElidedLifetimeInPathSubdiag,
|
pub subdiag: ElidedLifetimeInPathSubdiag,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
|
||||||
#[diag(lint_elided_named_lifetime)]
|
|
||||||
pub(crate) struct ElidedNamedLifetime {
|
pub(crate) struct ElidedNamedLifetime {
|
||||||
#[label(lint_label_elided)]
|
pub span: Span,
|
||||||
pub elided: Span,
|
pub kind: MissingLifetimeKind,
|
||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
#[label(lint_label_named)]
|
pub declaration: Option<Span>,
|
||||||
pub named_declaration: Option<Span>,
|
}
|
||||||
|
|
||||||
|
impl<G: EmissionGuarantee> 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);
|
||||||
|
}
|
||||||
|
// 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,
|
||||||
|
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)]
|
#[derive(LintDiagnostic)]
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
};
|
};
|
||||||
use rustc_error_messages::{DiagMessage, MultiSpan};
|
use rustc_error_messages::{DiagMessage, MultiSpan};
|
||||||
use rustc_hir::def::Namespace;
|
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_macros::{Decodable, Encodable, HashStable_Generic};
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
|
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
|
||||||
@ -556,6 +556,12 @@ pub enum DeprecatedSinceKind {
|
|||||||
InVersion(String),
|
InVersion(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ElidedLifetimeResolution {
|
||||||
|
Static,
|
||||||
|
Param(Symbol, Span),
|
||||||
|
}
|
||||||
|
|
||||||
// This could be a closure, but then implementing derive trait
|
// This could be a closure, but then implementing derive trait
|
||||||
// becomes hacky (and it gets allocated).
|
// becomes hacky (and it gets allocated).
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -568,12 +574,9 @@ pub enum BuiltinLintDiag {
|
|||||||
},
|
},
|
||||||
MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
|
MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
|
||||||
ElidedLifetimesInPaths(usize, Span, bool, Span),
|
ElidedLifetimesInPaths(usize, Span, bool, Span),
|
||||||
ElidedIsStatic {
|
ElidedNamedLifetimes {
|
||||||
elided: Span,
|
elided: (Span, MissingLifetimeKind),
|
||||||
},
|
resolution: ElidedLifetimeResolution,
|
||||||
ElidedIsParam {
|
|
||||||
elided: Span,
|
|
||||||
param: (Symbol, Span),
|
|
||||||
},
|
},
|
||||||
UnknownCrateTypes {
|
UnknownCrateTypes {
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -2062,7 +2062,10 @@ fn record_lifetime_res(
|
|||||||
lint::builtin::ELIDED_NAMED_LIFETIMES,
|
lint::builtin::ELIDED_NAMED_LIFETIMES,
|
||||||
missing.id_for_lint,
|
missing.id_for_lint,
|
||||||
missing.span,
|
missing.span,
|
||||||
BuiltinLintDiag::ElidedIsStatic { elided: missing.span },
|
BuiltinLintDiag::ElidedNamedLifetimes {
|
||||||
|
elided: (missing.span, missing.kind),
|
||||||
|
resolution: lint::ElidedLifetimeResolution::Static,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2072,9 +2075,12 @@ fn record_lifetime_res(
|
|||||||
lint::builtin::ELIDED_NAMED_LIFETIMES,
|
lint::builtin::ELIDED_NAMED_LIFETIMES,
|
||||||
missing.id_for_lint,
|
missing.id_for_lint,
|
||||||
missing.span,
|
missing.span,
|
||||||
BuiltinLintDiag::ElidedIsParam {
|
BuiltinLintDiag::ElidedNamedLifetimes {
|
||||||
elided: missing.span,
|
elided: (missing.span, missing.kind),
|
||||||
param: (tcx.item_name(param.into()), tcx.source_span(param)),
|
resolution: lint::ElidedLifetimeResolution::Param(
|
||||||
|
tcx.item_name(param.into()),
|
||||||
|
tcx.source_span(param),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,10 @@ note: the lint level is defined here
|
|||||||
|
|
|
|
||||||
LL | #![deny(elided_named_lifetimes)]
|
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
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -9,6 +9,10 @@ note: the lint level is defined here
|
|||||||
|
|
|
|
||||||
LL | #[warn(elided_named_lifetimes)]
|
LL | #[warn(elided_named_lifetimes)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: consider specifying it explicitly
|
||||||
|
|
|
||||||
|
LL | fn bar(x: &'static u8) -> &'static u8 {
|
||||||
|
| +++++++
|
||||||
|
|
||||||
error: elided lifetime has a name
|
error: elided lifetime has a name
|
||||||
--> $DIR/not-tied-to-crate.rs:11:31
|
--> $DIR/not-tied-to-crate.rs:11:31
|
||||||
@ -21,6 +25,10 @@ note: the lint level is defined here
|
|||||||
|
|
|
|
||||||
LL | #[deny(elided_named_lifetimes)]
|
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
|
error: aborting due to 1 previous error; 1 warning emitted
|
||||||
|
|
||||||
|
@ -9,24 +9,43 @@ note: the lint level is defined here
|
|||||||
|
|
|
|
||||||
LL | #![deny(elided_named_lifetimes)]
|
LL | #![deny(elided_named_lifetimes)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: consider specifying it explicitly
|
||||||
|
|
|
||||||
|
LL | fn ampersand(x: &'static u8) -> &'static u8 {
|
||||||
|
| +++++++
|
||||||
|
|
||||||
error: elided lifetime has a name
|
error: elided lifetime has a name
|
||||||
--> $DIR/static.rs:23:32
|
--> $DIR/static.rs:23:32
|
||||||
|
|
|
|
||||||
LL | fn brackets(x: &'static u8) -> Brackets {
|
LL | fn brackets(x: &'static u8) -> Brackets {
|
||||||
| ^^^^^^^^ this elided lifetime gets resolved as `'static`
|
| ^^^^^^^^ 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
|
error: elided lifetime has a name
|
||||||
--> $DIR/static.rs:30:34
|
--> $DIR/static.rs:30:34
|
||||||
|
|
|
|
||||||
LL | fn comma(x: &'static u8) -> Comma<u8> {
|
LL | fn comma(x: &'static u8) -> Comma<u8> {
|
||||||
| ^ this elided lifetime gets resolved as `'static`
|
| ^ 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
|
error: elided lifetime has a name
|
||||||
--> $DIR/static.rs:35:35
|
--> $DIR/static.rs:35:35
|
||||||
|
|
|
|
||||||
LL | fn underscore(x: &'static u8) -> &'_ u8 {
|
LL | fn underscore(x: &'static u8) -> &'_ u8 {
|
||||||
| ^^ this elided lifetime gets resolved as `'static`
|
| ^^ 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
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user