summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_lint/src/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_lint/src/context.rs')
-rw-r--r--compiler/rustc_lint/src/context.rs87
1 files changed, 51 insertions, 36 deletions
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index e6a0d7e60..8046cc21c 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -355,14 +355,12 @@ impl LintStore {
sub: RequestedLevel { level, lint_name },
});
}
- CheckLintNameResult::Tool(result) => {
- if let Err((Some(_), new_name)) = result {
- sess.emit_warning(CheckNameDeprecated {
- lint_name: lint_name.clone(),
- new_name,
- sub: RequestedLevel { level, lint_name },
- });
- }
+ CheckLintNameResult::Tool(Err((Some(_), new_name))) => {
+ sess.emit_warning(CheckNameDeprecated {
+ lint_name: lint_name.clone(),
+ new_name,
+ sub: RequestedLevel { level, lint_name },
+ });
}
CheckLintNameResult::NoTool => {
sess.emit_err(CheckNameUnknownTool {
@@ -438,18 +436,18 @@ impl LintStore {
return CheckLintNameResult::Tool(Ok(&lint_ids));
}
},
- Some(&Id(ref id)) => return CheckLintNameResult::Tool(Ok(slice::from_ref(id))),
+ Some(Id(id)) => return CheckLintNameResult::Tool(Ok(slice::from_ref(id))),
// If the lint was registered as removed or renamed by the lint tool, we don't need
// to treat tool_lints and rustc lints different and can use the code below.
_ => {}
}
}
match self.by_name.get(&complete_name) {
- Some(&Renamed(ref new_name, _)) => CheckLintNameResult::Warning(
+ Some(Renamed(new_name, _)) => CheckLintNameResult::Warning(
format!("lint `{}` has been renamed to `{}`", complete_name, new_name),
Some(new_name.to_owned()),
),
- Some(&Removed(ref reason)) => CheckLintNameResult::Warning(
+ Some(Removed(reason)) => CheckLintNameResult::Warning(
format!("lint `{}` has been removed: {}", complete_name, reason),
None,
),
@@ -470,7 +468,7 @@ impl LintStore {
CheckLintNameResult::Ok(&lint_ids)
}
},
- Some(&Id(ref id)) => CheckLintNameResult::Ok(slice::from_ref(id)),
+ Some(Id(id)) => CheckLintNameResult::Ok(slice::from_ref(id)),
Some(&Ignored) => CheckLintNameResult::Ok(&[]),
}
}
@@ -483,7 +481,16 @@ impl LintStore {
return CheckLintNameResult::NoLint(Some(Symbol::intern(&name_lower)));
}
// ...if not, search for lints with a similar name
- let groups = self.lint_groups.keys().copied().map(Symbol::intern);
+ // Note: find_best_match_for_name depends on the sort order of its input vector.
+ // To ensure deterministic output, sort elements of the lint_groups hash map.
+ // Also, never suggest deprecated lint groups.
+ let mut groups: Vec<_> = self
+ .lint_groups
+ .iter()
+ .filter_map(|(k, LintGroup { depr, .. })| if depr.is_none() { Some(k) } else { None })
+ .collect();
+ groups.sort();
+ let groups = groups.iter().map(|k| Symbol::intern(k));
let lints = self.lints.iter().map(|l| Symbol::intern(&l.name_lower()));
let names: Vec<Symbol> = groups.chain(lints).collect();
let suggestion = find_best_match_for_name(&names, Symbol::intern(&name_lower), None);
@@ -513,7 +520,7 @@ impl LintStore {
CheckLintNameResult::Tool(Err((Some(&lint_ids), complete_name)))
}
},
- Some(&Id(ref id)) => {
+ Some(Id(id)) => {
CheckLintNameResult::Tool(Err((Some(slice::from_ref(id)), complete_name)))
}
Some(other) => {
@@ -818,21 +825,24 @@ pub trait LintContext: Sized {
debug!(?param_span, ?use_span, ?deletion_span);
db.span_label(param_span, "this lifetime...");
db.span_label(use_span, "...is used only here");
- let msg = "elide the single-use lifetime";
- let (use_span, replace_lt) = if elide {
- let use_span = sess.source_map().span_extend_while(
- use_span,
- char::is_whitespace,
- ).unwrap_or(use_span);
- (use_span, String::new())
- } else {
- (use_span, "'_".to_owned())
- };
- db.multipart_suggestion(
- msg,
- vec![(deletion_span, String::new()), (use_span, replace_lt)],
- Applicability::MachineApplicable,
- );
+ if let Some(deletion_span) = deletion_span {
+ let msg = "elide the single-use lifetime";
+ let (use_span, replace_lt) = if elide {
+ let use_span = sess.source_map().span_extend_while(
+ use_span,
+ char::is_whitespace,
+ ).unwrap_or(use_span);
+ (use_span, String::new())
+ } else {
+ (use_span, "'_".to_owned())
+ };
+ debug!(?deletion_span, ?use_span);
+ db.multipart_suggestion(
+ msg,
+ vec![(deletion_span, String::new()), (use_span, replace_lt)],
+ Applicability::MachineApplicable,
+ );
+ }
},
BuiltinLintDiagnostics::SingleUseLifetime {
param_span: _,
@@ -840,12 +850,14 @@ pub trait LintContext: Sized {
deletion_span,
} => {
debug!(?deletion_span);
- db.span_suggestion(
- deletion_span,
- "elide the unused lifetime",
- "",
- Applicability::MachineApplicable,
- );
+ if let Some(deletion_span) = deletion_span {
+ db.span_suggestion(
+ deletion_span,
+ "elide the unused lifetime",
+ "",
+ Applicability::MachineApplicable,
+ );
+ }
},
BuiltinLintDiagnostics::NamedArgumentUsedPositionally{ position_sp_to_replace, position_sp_for_msg, named_arg_sp, named_arg_name, is_formatting_arg} => {
db.span_label(named_arg_sp, "this named argument is referred to by position in formatting string");
@@ -958,6 +970,7 @@ pub trait LintContext: Sized {
/// Note that this function should only be called for [`LintExpectationId`]s
/// retrieved from the current lint pass. Buffered or manually created ids can
/// cause ICEs.
+ #[rustc_lint_diagnostics]
fn fulfill_expectation(&self, expectation: LintExpectationId) {
// We need to make sure that submitted expectation ids are correctly fulfilled suppressed
// and stored between compilation sessions. To not manually do these steps, we simply create
@@ -1004,6 +1017,7 @@ impl<'tcx> LintContext for LateContext<'tcx> {
&*self.lint_store
}
+ #[rustc_lint_diagnostics]
fn lookup<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
@@ -1038,6 +1052,7 @@ impl LintContext for EarlyContext<'_> {
self.builder.lint_store()
}
+ #[rustc_lint_diagnostics]
fn lookup<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
@@ -1258,7 +1273,7 @@ impl<'tcx> LateContext<'tcx> {
tcx.associated_items(trait_id)
.find_by_name_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
.and_then(|assoc| {
- let proj = tcx.mk_projection(assoc.def_id, tcx.mk_substs_trait(self_ty, []));
+ let proj = tcx.mk_projection(assoc.def_id, [self_ty]);
tcx.try_normalize_erasing_regions(self.param_env, proj).ok()
})
}