diff options
Diffstat (limited to 'compiler/rustc_lint/src/context.rs')
-rw-r--r-- | compiler/rustc_lint/src/context.rs | 87 |
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() }) } |