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 {
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);
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: _,
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");
);
}
}
+ BuiltinLintDiagnostics::ByteSliceInPackedStructWithDerive => {
+ db.help("consider implementing the trait by hand, or remove the `packed` attribute");
+ }
}
// Rewrap `db`, and pass control to the user.
decorate(db)
/// 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
&*self.lint_store
}
+ #[rustc_lint_diagnostics]
fn lookup<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
self.builder.lint_store()
}
+ #[rustc_lint_diagnostics]
fn lookup<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,