Skip to content

Commit 563916d

Browse files
committed
Lint single-use-lifetimes on the AST.
1 parent db8a927 commit 563916d

19 files changed

+364
-469
lines changed

compiler/rustc_lint/src/context.rs

+37
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,43 @@ pub trait LintContext: Sized {
819819
"see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information",
820820
);
821821
},
822+
BuiltinLintDiagnostics::SingleUseLifetime {
823+
param_span,
824+
use_span: Some((use_span, elide)),
825+
deletion_span,
826+
} => {
827+
debug!(?param_span, ?use_span, ?deletion_span);
828+
db.span_label(param_span, "this lifetime...");
829+
db.span_label(use_span, "...is used only here");
830+
let msg = "elide the single-use lifetime";
831+
let (use_span, replace_lt) = if elide {
832+
let use_span = sess.source_map().span_extend_while(
833+
use_span,
834+
char::is_whitespace,
835+
).unwrap_or(use_span);
836+
(use_span, String::new())
837+
} else {
838+
(use_span, "'_".to_owned())
839+
};
840+
db.multipart_suggestion(
841+
msg,
842+
vec![(deletion_span, String::new()), (use_span, replace_lt)],
843+
Applicability::MachineApplicable,
844+
);
845+
},
846+
BuiltinLintDiagnostics::SingleUseLifetime {
847+
param_span: _,
848+
use_span: None,
849+
deletion_span,
850+
} => {
851+
debug!(?deletion_span);
852+
db.span_suggestion(
853+
deletion_span,
854+
"elide the unused lifetime",
855+
String::new(),
856+
Applicability::MachineApplicable,
857+
);
858+
},
822859
}
823860
// Rewrap `db`, and pass control to the user.
824861
decorate(LintDiagnosticBuilder::new(db));

compiler/rustc_lint/src/early.rs

+1
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
239239

240240
fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
241241
run_early_pass!(self, check_generic_param, param);
242+
self.check_id(param.id);
242243
ast_visit::walk_generic_param(self, param);
243244
}
244245

compiler/rustc_lint/src/levels.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::lint::{
1414
use rustc_middle::ty::query::Providers;
1515
use rustc_middle::ty::{RegisteredTools, TyCtxt};
1616
use rustc_session::lint::{
17-
builtin::{self, FORBIDDEN_LINT_GROUPS, UNFULFILLED_LINT_EXPECTATIONS},
17+
builtin::{self, FORBIDDEN_LINT_GROUPS, SINGLE_USE_LIFETIMES, UNFULFILLED_LINT_EXPECTATIONS},
1818
Level, Lint, LintExpectationId, LintId,
1919
};
2020
use rustc_session::parse::{add_feature_diagnostics, feature_err};
@@ -259,6 +259,14 @@ impl<'s> LintLevelsBuilder<'s> {
259259
let sess = self.sess;
260260
let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input");
261261
for (attr_index, attr) in attrs.iter().enumerate() {
262+
if attr.has_name(sym::automatically_derived) {
263+
self.current_specs_mut().insert(
264+
LintId::of(SINGLE_USE_LIFETIMES),
265+
(Level::Allow, LintLevelSource::Default),
266+
);
267+
continue;
268+
}
269+
262270
let level = match Level::from_attr(attr) {
263271
None => continue,
264272
Some(Level::Expect(unstable_id)) if let Some(hir_id) = source_hir_id => {

compiler/rustc_lint_defs/src/lib.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,11 @@ pub enum BuiltinLintDiagnostics {
423423
DeprecatedMacro(Option<Symbol>, Span),
424424
MissingAbi(Span, Abi),
425425
UnusedDocComment(Span),
426-
UnusedBuiltinAttribute { attr_name: Symbol, macro_name: String, invoc_span: Span },
426+
UnusedBuiltinAttribute {
427+
attr_name: Symbol,
428+
macro_name: String,
429+
invoc_span: Span,
430+
},
427431
PatternsInFnsWithoutBody(Span, Ident),
428432
LegacyDeriveHelpers(Span),
429433
ProcMacroBackCompat(String),
@@ -435,6 +439,16 @@ pub enum BuiltinLintDiagnostics {
435439
UnicodeTextFlow(Span, String),
436440
UnexpectedCfg((Symbol, Span), Option<(Symbol, Span)>),
437441
DeprecatedWhereclauseLocation(Span, String),
442+
SingleUseLifetime {
443+
/// Span of the parameter which declares this lifetime.
444+
param_span: Span,
445+
/// Span of the code that should be removed when eliding this lifetime.
446+
/// This span should include leading or trailing comma.
447+
deletion_span: Span,
448+
/// Span of the single use, or None if the lifetime is never used.
449+
/// If true, the lifetime will be fully elided.
450+
use_span: Option<(Span, bool)>,
451+
},
438452
}
439453

440454
/// Lints that are buffered up early on in the `Session` before the

0 commit comments

Comments
 (0)