Remove `LintDiagnostic::msg`

* instead simply set the primary message inside the lint decorator functions
* it used to be this way before [#]101986 which introduced `msg` to prevent
  good path delayed bugs (which no longer exist) from firing under certain
  circumstances when lints were suppressed / silenced
* this is no longer necessary for various reasons I presume
* it shaves off complexity and makes further changes easier to implement
This commit is contained in:
León Orell Valerian Liehr 2024-05-22 16:46:05 +02:00
parent 366ef95407
commit 06bc4fc671
No known key found for this signature in database
GPG Key ID: D17A07215F68E713
44 changed files with 430 additions and 488 deletions

View File

@ -564,8 +564,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
lint::builtin::INLINE_NO_SANITIZE, lint::builtin::INLINE_NO_SANITIZE,
hir_id, hir_id,
no_sanitize_span, no_sanitize_span,
"`no_sanitize` will have no effect after inlining",
|lint| { |lint| {
lint.primary_message("`no_sanitize` will have no effect after inlining");
lint.span_note(inline_span, "inlining requested here"); lint.span_note(inline_span, "inlining requested here");
}, },
) )

View File

@ -200,8 +200,6 @@ pub trait SubdiagMessageOp<G: EmissionGuarantee> =
pub trait LintDiagnostic<'a, G: EmissionGuarantee> { pub trait LintDiagnostic<'a, G: EmissionGuarantee> {
/// Decorate and emit a lint. /// Decorate and emit a lint.
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>); fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>);
fn msg(&self) -> DiagMessage;
} }
#[derive(Clone, Debug, Encodable, Decodable)] #[derive(Clone, Debug, Encodable, Decodable)]

View File

@ -46,13 +46,9 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
.emit(); .emit();
} }
None => { None => {
tcx.node_span_lint( tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
UNSUPPORTED_CALLING_CONVENTIONS, lint.primary_message("use of calling convention not supported on this target");
hir_id, });
span,
"use of calling convention not supported on this target",
|_| {},
);
} }
} }
@ -243,8 +239,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
UNINHABITED_STATIC, UNINHABITED_STATIC,
tcx.local_def_id_to_hir_id(def_id), tcx.local_def_id_to_hir_id(def_id),
span, span,
"static of uninhabited type",
|lint| { |lint| {
lint.primary_message("static of uninhabited type");
lint lint
.note("uninhabited statics cannot be initialized, and any access would be an immediate error"); .note("uninhabited statics cannot be initialized, and any access would be an immediate error");
}, },
@ -1315,9 +1311,11 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
tcx.local_def_id_to_hir_id(adt.did().expect_local()), tcx.local_def_id_to_hir_id(adt.did().expect_local()),
span, span,
|lint| {
lint.primary_message(
"zero-sized fields in `repr(transparent)` cannot \ "zero-sized fields in `repr(transparent)` cannot \
contain external non-exhaustive types", contain external non-exhaustive types",
|lint| { );
let note = if non_exhaustive { let note = if non_exhaustive {
"is marked with `#[non_exhaustive]`" "is marked with `#[non_exhaustive]`"
} else { } else {

View File

@ -281,8 +281,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
lint::builtin::ASM_SUB_REGISTER, lint::builtin::ASM_SUB_REGISTER,
expr.hir_id, expr.hir_id,
spans, spans,
"formatting may not be suitable for sub-register argument",
|lint| { |lint| {
lint.primary_message("formatting may not be suitable for sub-register argument");
lint.span_label(expr.span, "for this argument"); lint.span_label(expr.span, "for this argument");
lint.help(format!( lint.help(format!(
"use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}` (for {suggested_size}-bit values)", "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}` (for {suggested_size}-bit values)",

View File

@ -35,11 +35,12 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
continue; continue;
} }
let (path, _) = item.expect_use(); let (path, _) = item.expect_use();
let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) { tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| {
format!("unused import: `{snippet}`") if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
lint.primary_message(format!("unused import: `{snippet}`"));
} else { } else {
"unused import".to_owned() lint.primary_message("unused import");
}; }
tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, msg, |_| {}); });
} }
} }

View File

@ -317,8 +317,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
lint::builtin::INVALID_TYPE_PARAM_DEFAULT, lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
param.hir_id, param.hir_id,
param.span, param.span,
TYPE_DEFAULT_NOT_ALLOWED, |lint| {
|_| {}, lint.primary_message(TYPE_DEFAULT_NOT_ALLOWED);
},
); );
} }
Defaults::Deny => { Defaults::Deny => {

View File

@ -646,8 +646,9 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
LATE_BOUND_LIFETIME_ARGUMENTS, LATE_BOUND_LIFETIME_ARGUMENTS,
args.args[0].hir_id(), args.args[0].hir_id(),
multispan, multispan,
msg, |lint| {
|_| {}, lint.primary_message(msg);
},
); );
} }

View File

@ -72,8 +72,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag); self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
diag.stash(self_ty.span, StashKey::TraitMissingMethod); diag.stash(self_ty.span, StashKey::TraitMissingMethod);
} else { } else {
let msg = "trait objects without an explicit `dyn` are deprecated"; tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| {
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| { lint.primary_message("trait objects without an explicit `dyn` are deprecated");
if self_ty.span.can_be_used_for_suggestions() { if self_ty.span.can_be_used_for_suggestions() {
lint.multipart_suggestion_verbose( lint.multipart_suggestion_verbose(
"if this is an object-safe trait, use `dyn`", "if this is an object-safe trait, use `dyn`",

View File

@ -1164,12 +1164,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let ty = self.lower_assoc_ty(span, assoc_ty_did, assoc_segment, bound); let ty = self.lower_assoc_ty(span, assoc_ty_did, assoc_segment, bound);
if let Some(variant_def_id) = variant_resolution { if let Some(variant_def_id) = variant_resolution {
tcx.node_span_lint( tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| {
AMBIGUOUS_ASSOCIATED_ITEMS, lint.primary_message("ambiguous associated item");
hir_ref_id,
span,
"ambiguous associated item",
|lint| {
let mut could_refer_to = |kind: DefKind, def_id, also| { let mut could_refer_to = |kind: DefKind, def_id, also| {
let note_msg = format!( let note_msg = format!(
"`{}` could{} refer to the {} defined here", "`{}` could{} refer to the {} defined here",
@ -1189,8 +1185,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
}, });
);
} }
Ok((ty, DefKind::AssocTy, assoc_ty_did)) Ok((ty, DefKind::AssocTy, assoc_ty_did))
} }

View File

@ -63,19 +63,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind); debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
let msg = format!("unreachable {kind}"); let msg = format!("unreachable {kind}");
self.tcx().node_span_lint( self.tcx().node_span_lint(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
lint::builtin::UNREACHABLE_CODE, lint.primary_message(msg.clone());
id,
span,
msg.clone(),
|lint| {
lint.span_label(span, msg).span_label( lint.span_label(span, msg).span_label(
orig_span, orig_span,
custom_note custom_note.unwrap_or("any code following this expression is unreachable"),
.unwrap_or("any code following this expression is unreachable"),
); );
}, })
)
} }
} }
} }

View File

@ -91,11 +91,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
prelude_or_array_lint, prelude_or_array_lint,
self_expr.hir_id, self_expr.hir_id,
self_expr.span, self_expr.span,
format!( |lint| {
lint.primary_message(format!(
"trait method `{}` will become ambiguous in Rust {edition}", "trait method `{}` will become ambiguous in Rust {edition}",
segment.ident.name segment.ident.name
), ));
|lint| {
let sp = self_expr.span; let sp = self_expr.span;
let derefs = "*".repeat(pick.autoderefs); let derefs = "*".repeat(pick.autoderefs);
@ -144,11 +145,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
prelude_or_array_lint, prelude_or_array_lint,
call_expr.hir_id, call_expr.hir_id,
call_expr.span, call_expr.span,
format!( |lint| {
lint.primary_message(format!(
"trait method `{}` will become ambiguous in Rust {edition}", "trait method `{}` will become ambiguous in Rust {edition}",
segment.ident.name segment.ident.name
), ));
|lint| {
let sp = call_expr.span; let sp = call_expr.span;
let trait_name = self.trait_path_or_bare_name( let trait_name = self.trait_path_or_bare_name(
span, span,
@ -251,15 +253,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return; return;
} }
self.tcx.node_span_lint( self.tcx.node_span_lint(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| {
RUST_2021_PRELUDE_COLLISIONS, lint.primary_message(format!(
expr_id,
span,
format!(
"trait-associated function `{}` will become ambiguous in Rust 2021", "trait-associated function `{}` will become ambiguous in Rust 2021",
method_name.name method_name.name
), ));
|lint| {
// "type" refers to either a type or, more likely, a trait from which // "type" refers to either a type or, more likely, a trait from which
// the associated function or method is from. // the associated function or method is from.
let container_id = pick.item.container_id(self.tcx); let container_id = pick.item.container_id(self.tcx);
@ -301,9 +300,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"<{}>", "<{}>",
std::iter::repeat("'_") std::iter::repeat("'_")
.take(counts.lifetimes) .take(counts.lifetimes)
.chain( .chain(std::iter::repeat("_").take(counts.types + counts.consts))
std::iter::repeat("_").take(counts.types + counts.consts)
)
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .join(", ")
); );
@ -316,8 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
}, });
);
} }
fn trait_path_or_bare_name( fn trait_path_or_bare_name(

View File

@ -408,8 +408,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lint::builtin::TYVAR_BEHIND_RAW_POINTER, lint::builtin::TYVAR_BEHIND_RAW_POINTER,
scope_expr_id, scope_expr_id,
span, span,
"type annotations needed", |lint| {
|_| {}, lint.primary_message("type annotations needed");
},
); );
} else { } else {
// Ended up encountering a type variable when doing autoderef, // Ended up encountering a type variable when doing autoderef,
@ -1279,16 +1280,13 @@ impl<'tcx> Pick<'tcx> {
return; return;
} }
let def_kind = self.item.kind.as_def_kind(); let def_kind = self.item.kind.as_def_kind();
tcx.node_span_lint( tcx.node_span_lint(lint::builtin::UNSTABLE_NAME_COLLISIONS, scope_expr_id, span, |lint| {
lint::builtin::UNSTABLE_NAME_COLLISIONS, lint.primary_message(format!(
scope_expr_id,
span,
format!(
"{} {} with this name may be added to the standard library in the future", "{} {} with this name may be added to the standard library in the future",
tcx.def_kind_descr_article(def_kind, self.item.def_id), tcx.def_kind_descr_article(def_kind, self.item.def_id),
tcx.def_kind_descr(def_kind, self.item.def_id), tcx.def_kind_descr(def_kind, self.item.def_id),
), ));
|lint| {
match (self.item.kind, self.item.container) { match (self.item.kind, self.item.container) {
(ty::AssocKind::Fn, _) => { (ty::AssocKind::Fn, _) => {
// FIXME: This should be a `span_suggestion` instead of `help` // FIXME: This should be a `span_suggestion` instead of `help`
@ -1324,8 +1322,7 @@ impl<'tcx> Pick<'tcx> {
(format!(" `{}`", tcx.def_path_str(candidate.item.def_id)), *feature) (format!(" `{}`", tcx.def_path_str(candidate.item.def_id)), *feature)
}), }),
); );
}, });
);
} }
} }

View File

@ -1950,7 +1950,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&unmentioned_fields.iter().map(|(_, i)| i).collect::<Vec<_>>(), &unmentioned_fields.iter().map(|(_, i)| i).collect::<Vec<_>>(),
); );
self.tcx.node_span_lint(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, "some fields are not explicitly listed", |lint| { self.tcx.node_span_lint(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, |lint| {
lint.primary_message("some fields are not explicitly listed");
lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns)); lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns));
lint.help( lint.help(
"ensure that all fields are mentioned explicitly by adding the suggested fields", "ensure that all fields are mentioned explicitly by adding the suggested fields",

View File

@ -928,8 +928,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
closure_hir_id, closure_hir_id,
closure_head_span, closure_head_span,
reasons.migration_message(),
|lint| { |lint| {
lint.primary_message(reasons.migration_message());
for NeededMigration { var_hir_id, diagnostics_info } in &need_migrations { for NeededMigration { var_hir_id, diagnostics_info } in &need_migrations {
// Labels all the usage of the captured variable and why they are responsible // Labels all the usage of the captured variable and why they are responsible
// for migration being needed // for migration being needed

View File

@ -21,7 +21,7 @@ use crate::passes::{EarlyLintPassObject, LateLintPassObject};
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync; use rustc_data_structures::sync;
use rustc_data_structures::unord::UnordMap; use rustc_data_structures::unord::UnordMap;
use rustc_errors::{Diag, DiagMessage, LintDiagnostic, MultiSpan}; use rustc_errors::{Diag, LintDiagnostic, MultiSpan};
use rustc_feature::Features; use rustc_feature::Features;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::Res;
@ -556,7 +556,6 @@ pub trait LintContext {
&self, &self,
lint: &'static Lint, lint: &'static Lint,
span: Option<S>, span: Option<S>,
msg: impl Into<DiagMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
); );
@ -568,8 +567,8 @@ pub trait LintContext {
span: S, span: S,
decorator: impl for<'a> LintDiagnostic<'a, ()>, decorator: impl for<'a> LintDiagnostic<'a, ()>,
) { ) {
self.opt_span_lint(lint, Some(span), decorator.msg(), |diag| { self.opt_span_lint(lint, Some(span), |lint| {
decorator.decorate_lint(diag); decorator.decorate_lint(lint);
}); });
} }
@ -581,17 +580,16 @@ pub trait LintContext {
&self, &self,
lint: &'static Lint, lint: &'static Lint,
span: S, span: S,
msg: impl Into<DiagMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
) { ) {
self.opt_span_lint(lint, Some(span), msg, decorate); self.opt_span_lint(lint, Some(span), decorate);
} }
/// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically
/// generated by `#[derive(LintDiagnostic)]`). /// generated by `#[derive(LintDiagnostic)]`).
fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> LintDiagnostic<'a, ()>) { fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> LintDiagnostic<'a, ()>) {
self.opt_span_lint(lint, None as Option<Span>, decorator.msg(), |diag| { self.opt_span_lint(lint, None as Option<Span>, |lint| {
decorator.decorate_lint(diag); decorator.decorate_lint(lint);
}); });
} }
@ -599,13 +597,8 @@ pub trait LintContext {
/// ///
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
fn lint( fn lint(&self, lint: &'static Lint, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)) {
&self, self.opt_span_lint(lint, None as Option<Span>, decorate);
lint: &'static Lint,
msg: impl Into<DiagMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
) {
self.opt_span_lint(lint, None as Option<Span>, msg, decorate);
} }
/// This returns the lint level for the given lint at the current location. /// This returns the lint level for the given lint at the current location.
@ -668,14 +661,13 @@ impl<'tcx> LintContext for LateContext<'tcx> {
&self, &self,
lint: &'static Lint, lint: &'static Lint,
span: Option<S>, span: Option<S>,
msg: impl Into<DiagMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
) { ) {
let hir_id = self.last_node_with_lint_attrs; let hir_id = self.last_node_with_lint_attrs;
match span { match span {
Some(s) => self.tcx.node_span_lint(lint, hir_id, s, msg, decorate), Some(s) => self.tcx.node_span_lint(lint, hir_id, s, decorate),
None => self.tcx.node_lint(lint, hir_id, msg, decorate), None => self.tcx.node_lint(lint, hir_id, decorate),
} }
} }
@ -695,10 +687,9 @@ impl LintContext for EarlyContext<'_> {
&self, &self,
lint: &'static Lint, lint: &'static Lint,
span: Option<S>, span: Option<S>,
msg: impl Into<DiagMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
) { ) {
self.builder.opt_span_lint(lint, span.map(|s| s.into()), msg, decorate) self.builder.opt_span_lint(lint, span.map(|s| s.into()), decorate)
} }
fn get_lint_level(&self, lint: &'static Lint) -> Level { fn get_lint_level(&self, lint: &'static Lint) -> Level {

View File

@ -369,6 +369,7 @@ struct ImplTraitOvercapturesLint<'tcx> {
impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> {
fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) {
diag.primary_message(fluent::lint_impl_trait_overcaptures);
diag.arg("self_ty", self.self_ty.to_string()) diag.arg("self_ty", self.self_ty.to_string())
.arg("num_captured", self.num_captured) .arg("num_captured", self.num_captured)
.span_note(self.uncaptured_spans, fluent::lint_note) .span_note(self.uncaptured_spans, fluent::lint_note)
@ -382,10 +383,6 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> {
); );
} }
} }
fn msg(&self) -> rustc_errors::DiagMessage {
fluent::lint_impl_trait_overcaptures
}
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]

View File

@ -16,7 +16,7 @@ use crate::{
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::{Diag, DiagMessage, LintDiagnostic, MultiSpan}; use rustc_errors::{Diag, LintDiagnostic, MultiSpan};
use rustc_feature::{Features, GateIssue}; use rustc_feature::{Features, GateIssue};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
@ -1063,14 +1063,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
// FIXME: make this translatable // FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
lint_level( lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
self.sess, lint.primary_message(fluent::lint_unknown_gated_lint);
lint,
level,
src,
Some(span.into()),
fluent::lint_unknown_gated_lint,
|lint| {
lint.arg("name", lint_id.lint.name_lower()); lint.arg("name", lint_id.lint.name_lower());
lint.note(fluent::lint_note); lint.note(fluent::lint_note);
rustc_session::parse::add_feature_diagnostics_for_issue( rustc_session::parse::add_feature_diagnostics_for_issue(
@ -1081,8 +1075,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
lint_from_cli, lint_from_cli,
None, None,
); );
}, });
);
} }
false false
@ -1103,11 +1096,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
&self, &self,
lint: &'static Lint, lint: &'static Lint,
span: Option<MultiSpan>, span: Option<MultiSpan>,
msg: impl Into<DiagMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
) { ) {
let (level, src) = self.lint_level(lint); let (level, src) = self.lint_level(lint);
lint_level(self.sess, lint, level, src, span, msg, decorate) lint_level(self.sess, lint, level, src, span, decorate)
} }
#[track_caller] #[track_caller]
@ -1118,7 +1110,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
decorate: impl for<'a> LintDiagnostic<'a, ()>, decorate: impl for<'a> LintDiagnostic<'a, ()>,
) { ) {
let (level, src) = self.lint_level(lint); let (level, src) = self.lint_level(lint);
lint_level(self.sess, lint, level, src, Some(span), decorate.msg(), |lint| { lint_level(self.sess, lint, level, src, Some(span), |lint| {
decorate.decorate_lint(lint); decorate.decorate_lint(lint);
}); });
} }
@ -1126,7 +1118,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
#[track_caller] #[track_caller]
pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> LintDiagnostic<'a, ()>) { pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> LintDiagnostic<'a, ()>) {
let (level, src) = self.lint_level(lint); let (level, src) = self.lint_level(lint);
lint_level(self.sess, lint, level, src, None, decorate.msg(), |lint| { lint_level(self.sess, lint, level, src, None, |lint| {
decorate.decorate_lint(lint); decorate.decorate_lint(lint);
}); });
} }

View File

@ -145,12 +145,9 @@ pub struct BuiltinMissingDebugImpl<'a> {
// Needed for def_path_str // Needed for def_path_str
impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> { impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> {
fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) {
diag.primary_message(fluent::lint_builtin_missing_debug_impl);
diag.arg("debug", self.tcx.def_path_str(self.def_id)); diag.arg("debug", self.tcx.def_path_str(self.def_id));
} }
fn msg(&self) -> DiagMessage {
fluent::lint_builtin_missing_debug_impl
}
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
@ -250,6 +247,7 @@ pub struct BuiltinUngatedAsyncFnTrackCaller<'a> {
impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(fluent::lint_ungated_async_fn_track_caller);
diag.span_label(self.label, fluent::lint_label); diag.span_label(self.label, fluent::lint_label);
rustc_session::parse::add_feature_diagnostics( rustc_session::parse::add_feature_diagnostics(
diag, diag,
@ -257,10 +255,6 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
sym::async_fn_track_caller, sym::async_fn_track_caller,
); );
} }
fn msg(&self) -> DiagMessage {
fluent::lint_ungated_async_fn_track_caller
}
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
@ -432,6 +426,7 @@ pub struct BuiltinUnpermittedTypeInit<'a> {
impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> { impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(self.msg);
diag.arg("ty", self.ty); diag.arg("ty", self.ty);
diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label); diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label);
if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) { if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) {
@ -443,10 +438,6 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
} }
self.sub.add_to_diag(diag); self.sub.add_to_diag(diag);
} }
fn msg(&self) -> DiagMessage {
self.msg.clone()
}
} }
// FIXME(davidtwco): make translatable // FIXME(davidtwco): make translatable
@ -1168,6 +1159,7 @@ pub struct NonFmtPanicUnused {
// Used because of two suggestions based on one Option<Span> // Used because of two suggestions based on one Option<Span>
impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused { impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(fluent::lint_non_fmt_panic_unused);
diag.arg("count", self.count); diag.arg("count", self.count);
diag.note(fluent::lint_note); diag.note(fluent::lint_note);
if let Some(span) = self.suggestion { if let Some(span) = self.suggestion {
@ -1185,10 +1177,6 @@ impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused {
); );
} }
} }
fn msg(&self) -> DiagMessage {
fluent::lint_non_fmt_panic_unused
}
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
@ -1410,13 +1398,10 @@ pub struct DropTraitConstraintsDiag<'a> {
// Needed for def_path_str // Needed for def_path_str
impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> { impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(fluent::lint_drop_trait_constraints);
diag.arg("predicate", self.predicate); diag.arg("predicate", self.predicate);
diag.arg("needs_drop", self.tcx.def_path_str(self.def_id)); diag.arg("needs_drop", self.tcx.def_path_str(self.def_id));
} }
fn msg(&self) -> DiagMessage {
fluent::lint_drop_trait_constraints
}
} }
pub struct DropGlue<'a> { pub struct DropGlue<'a> {
@ -1427,12 +1412,9 @@ pub struct DropGlue<'a> {
// Needed for def_path_str // Needed for def_path_str
impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> { impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(fluent::lint_drop_glue);
diag.arg("needs_drop", self.tcx.def_path_str(self.def_id)); diag.arg("needs_drop", self.tcx.def_path_str(self.def_id));
} }
fn msg(&self) -> DiagMessage {
fluent::lint_drop_glue
}
} }
// types.rs // types.rs
@ -1710,6 +1692,7 @@ pub struct ImproperCTypes<'a> {
// Used because of the complexity of Option<DiagMessage>, DiagMessage, and Option<Span> // Used because of the complexity of Option<DiagMessage>, DiagMessage, and Option<Span>
impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(fluent::lint_improper_ctypes);
diag.arg("ty", self.ty); diag.arg("ty", self.ty);
diag.arg("desc", self.desc); diag.arg("desc", self.desc);
diag.span_label(self.label, fluent::lint_label); diag.span_label(self.label, fluent::lint_label);
@ -1721,10 +1704,6 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
diag.span_note(note, fluent::lint_note); diag.span_note(note, fluent::lint_note);
} }
} }
fn msg(&self) -> DiagMessage {
fluent::lint_improper_ctypes
}
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
@ -1853,6 +1832,7 @@ pub enum UnusedDefSuggestion {
// Needed because of def_path_str // Needed because of def_path_str
impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> { impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(fluent::lint_unused_def);
diag.arg("pre", self.pre); diag.arg("pre", self.pre);
diag.arg("post", self.post); diag.arg("post", self.post);
diag.arg("def", self.cx.tcx.def_path_str(self.def_id)); diag.arg("def", self.cx.tcx.def_path_str(self.def_id));
@ -1864,10 +1844,6 @@ impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> {
diag.subdiagnostic(diag.dcx, sugg); diag.subdiagnostic(diag.dcx, sugg);
} }
} }
fn msg(&self) -> DiagMessage {
fluent::lint_unused_def
}
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
@ -1936,15 +1912,12 @@ pub struct AsyncFnInTraitDiag {
impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag { impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(fluent::lint_async_fn_in_trait);
diag.note(fluent::lint_note); diag.note(fluent::lint_note);
if let Some(sugg) = self.sugg { if let Some(sugg) = self.sugg {
diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect); diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect);
} }
} }
fn msg(&self) -> DiagMessage {
fluent::lint_async_fn_in_trait
}
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
@ -2260,10 +2233,8 @@ pub struct UnstableFeature {
} }
impl<'a> LintDiagnostic<'a, ()> for UnstableFeature { impl<'a> LintDiagnostic<'a, ()> for UnstableFeature {
fn decorate_lint<'b>(self, _diag: &'b mut Diag<'a, ()>) {} fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(self.msg);
fn msg(&self) -> DiagMessage {
self.msg.clone()
} }
} }
@ -2725,12 +2696,9 @@ pub struct AmbiguousGlobImports {
impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports { impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
diag.primary_message(self.ambiguity.msg.clone());
rustc_errors::report_ambiguity_error(diag, self.ambiguity); rustc_errors::report_ambiguity_error(diag, self.ambiguity);
} }
fn msg(&self) -> DiagMessage {
DiagMessage::Str(self.ambiguity.msg.clone().into())
}
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]

View File

@ -123,7 +123,8 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
} }
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
cx.span_lint(NON_FMT_PANICS, arg_span, fluent::lint_non_fmt_panic, |lint| { cx.span_lint(NON_FMT_PANICS, arg_span, |lint| {
lint.primary_message(fluent::lint_non_fmt_panic);
lint.arg("name", symbol); lint.arg("name", symbol);
lint.note(fluent::lint_note); lint.note(fluent::lint_note);
lint.note(fluent::lint_more_info_note); lint.note(fluent::lint_more_info_note);

View File

@ -105,25 +105,12 @@ impl<'a> LintDiagnosticDerive<'a> {
pub(crate) fn into_tokens(self) -> TokenStream { pub(crate) fn into_tokens(self) -> TokenStream {
let LintDiagnosticDerive { mut structure } = self; let LintDiagnosticDerive { mut structure } = self;
let kind = DiagnosticDeriveKind::LintDiagnostic; let kind = DiagnosticDeriveKind::LintDiagnostic;
let slugs = RefCell::new(Vec::new());
let implementation = kind.each_variant(&mut structure, |mut builder, variant| { let implementation = kind.each_variant(&mut structure, |mut builder, variant| {
let preamble = builder.preamble(variant); let preamble = builder.preamble(variant);
let body = builder.body(variant); let body = builder.body(variant);
let formatting_init = &builder.formatting_init; let primary_message = match builder.slug.value_ref() {
quote! {
#preamble
#formatting_init
#body
diag
}
});
let slugs = RefCell::new(Vec::new());
let msg = kind.each_variant(&mut structure, |mut builder, variant| {
// Collect the slug by generating the preamble.
let _ = builder.preamble(variant);
match builder.slug.value_ref() {
None => { None => {
span_err(builder.span, "diagnostic slug not specified") span_err(builder.span, "diagnostic slug not specified")
.help( .help(
@ -146,9 +133,18 @@ impl<'a> LintDiagnosticDerive<'a> {
Some(slug) => { Some(slug) => {
slugs.borrow_mut().push(slug.clone()); slugs.borrow_mut().push(slug.clone());
quote! { quote! {
crate::fluent_generated::#slug.into() diag.primary_message(crate::fluent_generated::#slug);
} }
} }
};
let formatting_init = &builder.formatting_init;
quote! {
#primary_message
#preamble
#formatting_init
#body
diag
} }
}); });
@ -161,10 +157,6 @@ impl<'a> LintDiagnosticDerive<'a> {
) { ) {
#implementation; #implementation;
} }
fn msg(&self) -> rustc_errors::DiagMessage {
#msg
}
} }
}); });
for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) {

View File

@ -2,7 +2,7 @@ use std::cmp;
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::sorted_map::SortedMap;
use rustc_errors::{Diag, DiagMessage, MultiSpan}; use rustc_errors::{Diag, MultiSpan};
use rustc_hir::{HirId, ItemLocalId}; use rustc_hir::{HirId, ItemLocalId};
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_session::lint::{ use rustc_session::lint::{
@ -269,7 +269,6 @@ pub fn lint_level(
level: Level, level: Level,
src: LintLevelSource, src: LintLevelSource,
span: Option<MultiSpan>, span: Option<MultiSpan>,
msg: impl Into<DiagMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
) { ) {
// Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to
@ -281,7 +280,6 @@ pub fn lint_level(
level: Level, level: Level,
src: LintLevelSource, src: LintLevelSource,
span: Option<MultiSpan>, span: Option<MultiSpan>,
msg: impl Into<DiagMessage>,
decorate: Box<dyn '_ + for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)>, decorate: Box<dyn '_ + for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)>,
) { ) {
// Check for future incompatibility lints and issue a stronger warning. // Check for future incompatibility lints and issue a stronger warning.
@ -350,10 +348,6 @@ pub fn lint_level(
} }
} }
// Delay evaluating and setting the primary message until after we've
// suppressed the lint due to macros.
err.primary_message(msg);
err.is_lint(lint.name_lower(), has_future_breakage); err.is_lint(lint.name_lower(), has_future_breakage);
// Lint diagnostics that are covered by the expect level will not be emitted outside // Lint diagnostics that are covered by the expect level will not be emitted outside
@ -418,7 +412,7 @@ pub fn lint_level(
explain_lint_level_source(lint, level, src, &mut err); explain_lint_level_source(lint, level, src, &mut err);
err.emit() err.emit()
} }
lint_level_impl(sess, lint, level, src, span, msg, Box::new(decorate)) lint_level_impl(sess, lint, level, src, span, Box::new(decorate))
} }
/// Returns whether `span` originates in a foreign crate's external macro. /// Returns whether `span` originates in a foreign crate's external macro.

View File

@ -156,6 +156,13 @@ pub struct Deprecated {
impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated { impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
diag.primary_message(match &self.since_kind {
DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated,
DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future,
DeprecatedSinceKind::InVersion(_) => {
crate::fluent_generated::middle_deprecated_in_version
}
});
diag.arg("kind", self.kind); diag.arg("kind", self.kind);
diag.arg("path", self.path); diag.arg("path", self.path);
if let DeprecatedSinceKind::InVersion(version) = self.since_kind { if let DeprecatedSinceKind::InVersion(version) = self.since_kind {
@ -171,16 +178,6 @@ impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecate
diag.subdiagnostic(diag.dcx, sub); diag.subdiagnostic(diag.dcx, sub);
} }
} }
fn msg(&self) -> rustc_errors::DiagMessage {
match &self.since_kind {
DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated,
DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future,
DeprecatedSinceKind::InVersion(_) => {
crate::fluent_generated::middle_deprecated_in_version
}
}
}
} }
fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind { fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind {
@ -597,7 +594,9 @@ impl<'tcx> TyCtxt<'tcx> {
unmarked: impl FnOnce(Span, DefId), unmarked: impl FnOnce(Span, DefId),
) -> bool { ) -> bool {
let soft_handler = |lint, span, msg: String| { let soft_handler = |lint, span, msg: String| {
self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |_| {}) self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
lint.primary_message(msg);
})
}; };
let eval_result = let eval_result =
self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable); self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);

View File

@ -112,8 +112,7 @@ impl<'tcx> TyCtxt<'tcx> {
lint::builtin::CONST_EVALUATABLE_UNCHECKED, lint::builtin::CONST_EVALUATABLE_UNCHECKED,
self.local_def_id_to_hir_id(local_def_id), self.local_def_id_to_hir_id(local_def_id),
self.def_span(ct.def), self.def_span(ct.def),
"cannot use constants which depend on generic parameters in types", |lint| { lint.primary_message("cannot use constants which depend on generic parameters in types"); },
|_| {},
) )
} }
} }

View File

@ -48,9 +48,7 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, RwLock, Work
#[cfg(parallel_compiler)] #[cfg(parallel_compiler)]
use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_data_structures::unord::UnordSet; use rustc_data_structures::unord::UnordSet;
use rustc_errors::{ use rustc_errors::{Applicability, Diag, DiagCtxt, ErrorGuaranteed, LintDiagnostic, MultiSpan};
Applicability, Diag, DiagCtxt, DiagMessage, ErrorGuaranteed, LintDiagnostic, MultiSpan,
};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
@ -2475,10 +2473,9 @@ impl<'tcx> TyCtxt<'tcx> {
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
decorator: impl for<'a> LintDiagnostic<'a, ()>, decorator: impl for<'a> LintDiagnostic<'a, ()>,
) { ) {
let msg = decorator.msg();
let (level, src) = self.lint_level_at_node(lint, hir_id); let (level, src) = self.lint_level_at_node(lint, hir_id);
lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| { lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
decorator.decorate_lint(diag); decorator.decorate_lint(lint);
}) })
} }
@ -2492,11 +2489,10 @@ impl<'tcx> TyCtxt<'tcx> {
lint: &'static Lint, lint: &'static Lint,
hir_id: HirId, hir_id: HirId,
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
msg: impl Into<DiagMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
) { ) {
let (level, src) = self.lint_level_at_node(lint, hir_id); let (level, src) = self.lint_level_at_node(lint, hir_id);
lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate); lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
} }
/// Find the crate root and the appropriate span where `use` and outer attributes can be /// Find the crate root and the appropriate span where `use` and outer attributes can be
@ -2547,8 +2543,8 @@ impl<'tcx> TyCtxt<'tcx> {
id: HirId, id: HirId,
decorator: impl for<'a> LintDiagnostic<'a, ()>, decorator: impl for<'a> LintDiagnostic<'a, ()>,
) { ) {
self.node_lint(lint, id, decorator.msg(), |diag| { self.node_lint(lint, id, |lint| {
decorator.decorate_lint(diag); decorator.decorate_lint(lint);
}) })
} }
@ -2561,11 +2557,10 @@ impl<'tcx> TyCtxt<'tcx> {
self, self,
lint: &'static Lint, lint: &'static Lint,
id: HirId, id: HirId,
msg: impl Into<DiagMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
) { ) {
let (level, src) = self.lint_level_at_node(lint, id); let (level, src) = self.lint_level_at_node(lint, id);
lint_level(self.sess, lint, level, src, None, msg, decorate); lint_level(self.sess, lint, level, src, None, decorate);
} }
pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> { pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {

View File

@ -1,4 +1,4 @@
use rustc_errors::{codes::*, Diag, DiagMessage, LintDiagnostic}; use rustc_errors::{codes::*, Diag, LintDiagnostic};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_middle::mir::AssertKind; use rustc_middle::mir::AssertKind;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
@ -50,18 +50,15 @@ pub(crate) enum AssertLintKind {
impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint<P> { impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint<P> {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
let message = self.assert_kind.diagnostic_message(); diag.primary_message(match self.lint_kind {
AssertLintKind::ArithmeticOverflow => fluent::mir_transform_arithmetic_overflow,
AssertLintKind::UnconditionalPanic => fluent::mir_transform_operation_will_panic,
});
let label = self.assert_kind.diagnostic_message();
self.assert_kind.add_args(&mut |name, value| { self.assert_kind.add_args(&mut |name, value| {
diag.arg(name, value); diag.arg(name, value);
}); });
diag.span_label(self.span, message); diag.span_label(self.span, label);
}
fn msg(&self) -> DiagMessage {
match self.lint_kind {
AssertLintKind::ArithmeticOverflow => fluent::mir_transform_arithmetic_overflow,
AssertLintKind::UnconditionalPanic => fluent::mir_transform_operation_will_panic,
}
} }
} }
@ -104,6 +101,7 @@ pub(crate) struct MustNotSupend<'tcx, 'a> {
// Needed for def_path_str // Needed for def_path_str
impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> { impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> {
fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) {
diag.primary_message(fluent::mir_transform_must_not_suspend);
diag.span_label(self.yield_sp, fluent::_subdiag::label); diag.span_label(self.yield_sp, fluent::_subdiag::label);
if let Some(reason) = self.reason { if let Some(reason) = self.reason {
diag.subdiagnostic(diag.dcx, reason); diag.subdiagnostic(diag.dcx, reason);
@ -113,10 +111,6 @@ impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> {
diag.arg("def_path", self.tcx.def_path_str(self.def_id)); diag.arg("def_path", self.tcx.def_path_str(self.def_id));
diag.arg("post", self.post); diag.arg("post", self.post);
} }
fn msg(&self) -> rustc_errors::DiagMessage {
fluent::mir_transform_must_not_suspend
}
} }
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]

View File

@ -99,7 +99,6 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>(
use rustc_errors::LintDiagnostic; use rustc_errors::LintDiagnostic;
let mut err = rcx.tcx.dcx().struct_span_warn(arm.pat.data().span, ""); let mut err = rcx.tcx.dcx().struct_span_warn(arm.pat.data().span, "");
err.primary_message(decorator.msg());
decorator.decorate_lint(&mut err); decorator.decorate_lint(&mut err);
err.emit(); err.emit();
} }

View File

@ -13,7 +13,7 @@ use super::elaborate;
use crate::infer::TyCtxtInferExt; use crate::infer::TyCtxtInferExt;
use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::{self, Obligation, ObligationCause}; use crate::traits::{self, Obligation, ObligationCause};
use rustc_errors::{DelayDm, FatalError, MultiSpan}; use rustc_errors::{FatalError, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
@ -162,19 +162,15 @@ fn lint_object_unsafe_trait(
) { ) {
// Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
// It's also hard to get a use site span, so we use the method definition span. // It's also hard to get a use site span, so we use the method definition span.
tcx.node_span_lint( tcx.node_span_lint(WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, span, |err| {
WHERE_CLAUSES_OBJECT_SAFETY, err.primary_message(format!(
hir::CRATE_HIR_ID, "the trait `{}` cannot be made into an object",
span, tcx.def_path_str(trait_def_id)
DelayDm(|| format!("the trait `{}` cannot be made into an object", tcx.def_path_str(trait_def_id))), ));
|err| {
let node = tcx.hir().get_if_local(trait_def_id); let node = tcx.hir().get_if_local(trait_def_id);
let mut spans = MultiSpan::from_span(span); let mut spans = MultiSpan::from_span(span);
if let Some(hir::Node::Item(item)) = node { if let Some(hir::Node::Item(item)) = node {
spans.push_span_label( spans.push_span_label(item.ident.span, "this trait cannot be made into an object...");
item.ident.span,
"this trait cannot be made into an object...",
);
spans.push_span_label(span, format!("...because {}", violation.error_msg())); spans.push_span_label(span, format!("...because {}", violation.error_msg()));
} else { } else {
spans.push_span_label( spans.push_span_label(
@ -195,8 +191,7 @@ fn lint_object_unsafe_trait(
// Only provide the help if its a local trait, otherwise it's not // Only provide the help if its a local trait, otherwise it's not
violation.solution().add_to(err); violation.solution().add_to(err);
} }
}, });
);
} }
fn sized_trait_bound_spans<'tcx>( fn sized_trait_bound_spans<'tcx>(

View File

@ -21,7 +21,7 @@ use crate::traits::{
self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt, self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt,
}; };
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{codes::*, DelayDm, Diag, EmissionGuarantee}; use rustc_errors::{codes::*, Diag, EmissionGuarantee};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
@ -449,7 +449,7 @@ fn report_conflicting_impls<'tcx>(
} }
} }
let msg = DelayDm(|| { let msg = || {
format!( format!(
"conflicting implementations of trait `{}`{}{}", "conflicting implementations of trait `{}`{}{}",
overlap.trait_ref.print_trait_sugared(), overlap.trait_ref.print_trait_sugared(),
@ -459,7 +459,7 @@ fn report_conflicting_impls<'tcx>(
_ => "", _ => "",
} }
) )
}); };
// Don't report overlap errors if the header references error // Don't report overlap errors if the header references error
if let Err(err) = (overlap.trait_ref, overlap.self_ty).error_reported() { if let Err(err) = (overlap.trait_ref, overlap.self_ty).error_reported() {
@ -471,7 +471,7 @@ fn report_conflicting_impls<'tcx>(
let reported = if overlap.with_impl.is_local() let reported = if overlap.with_impl.is_local()
|| tcx.ensure().orphan_check_impl(impl_def_id).is_ok() || tcx.ensure().orphan_check_impl(impl_def_id).is_ok()
{ {
let mut err = tcx.dcx().struct_span_err(impl_span, msg); let mut err = tcx.dcx().struct_span_err(impl_span, msg());
err.code(E0119); err.code(E0119);
decorate(tcx, &overlap, impl_span, &mut err); decorate(tcx, &overlap, impl_span, &mut err);
err.emit() err.emit()
@ -485,15 +485,10 @@ fn report_conflicting_impls<'tcx>(
FutureCompatOverlapErrorKind::OrderDepTraitObjects => ORDER_DEPENDENT_TRAIT_OBJECTS, FutureCompatOverlapErrorKind::OrderDepTraitObjects => ORDER_DEPENDENT_TRAIT_OBJECTS,
FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK, FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
}; };
tcx.node_span_lint( tcx.node_span_lint(lint, tcx.local_def_id_to_hir_id(impl_def_id), impl_span, |err| {
lint, err.primary_message(msg());
tcx.local_def_id_to_hir_id(impl_def_id),
impl_span,
msg,
|err| {
decorate(tcx, &overlap, impl_span, err); decorate(tcx, &overlap, impl_span, err);
}, });
);
Ok(()) Ok(())
} }
} }

View File

@ -372,8 +372,8 @@ pub(crate) fn run_global_ctxt(
tcx.node_lint( tcx.node_lint(
crate::lint::MISSING_CRATE_LEVEL_DOCS, crate::lint::MISSING_CRATE_LEVEL_DOCS,
DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(), DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(),
"no documentation found for this crate's top-level module",
|lint| { |lint| {
lint.primary_message("no documentation found for this crate's top-level module");
lint.help(help); lint.help(help);
}, },
); );

View File

@ -834,8 +834,9 @@ impl<'tcx> ExtraInfo<'tcx> {
crate::lint::INVALID_CODEBLOCK_ATTRIBUTES, crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
self.tcx.local_def_id_to_hir_id(def_id), self.tcx.local_def_id_to_hir_id(def_id),
self.sp, self.sp,
msg, |lint| {
|_| {}, lint.primary_message(msg);
},
); );
} }
} }
@ -850,8 +851,10 @@ impl<'tcx> ExtraInfo<'tcx> {
crate::lint::INVALID_CODEBLOCK_ATTRIBUTES, crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
self.tcx.local_def_id_to_hir_id(def_id), self.tcx.local_def_id_to_hir_id(def_id),
self.sp, self.sp,
msg, |lint| {
f, lint.primary_message(msg);
f(lint);
},
); );
} }
} }

View File

@ -125,13 +125,9 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
if should_have_doc_example(cx, item) { if should_have_doc_example(cx, item) {
debug!("reporting error for {item:?} (hir_id={hir_id:?})"); debug!("reporting error for {item:?} (hir_id={hir_id:?})");
let sp = item.attr_span(cx.tcx); let sp = item.attr_span(cx.tcx);
cx.tcx.node_span_lint( cx.tcx.node_span_lint(crate::lint::MISSING_DOC_CODE_EXAMPLES, hir_id, sp, |lint| {
crate::lint::MISSING_DOC_CODE_EXAMPLES, lint.primary_message("missing code example in this documentation");
hir_id, });
sp,
"missing code example in this documentation",
|_| {},
);
} }
} else if tests.found_tests > 0 } else if tests.found_tests > 0
&& !cx.cache.effective_visibilities.is_exported(cx.tcx, item.item_id.expect_def_id()) && !cx.cache.effective_visibilities.is_exported(cx.tcx, item.item_id.expect_def_id())
@ -140,8 +136,9 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
crate::lint::PRIVATE_DOC_TESTS, crate::lint::PRIVATE_DOC_TESTS,
hir_id, hir_id,
item.attr_span(cx.tcx), item.attr_span(cx.tcx),
"documentation test in private item", |lint| {
|_| {}, lint.primary_message("documentation test in private item");
},
); );
} }
} }

View File

@ -1689,7 +1689,9 @@ fn report_diagnostic(
let sp = item.attr_span(tcx); let sp = item.attr_span(tcx);
tcx.node_span_lint(lint, hir_id, sp, msg, |lint| { tcx.node_span_lint(lint, hir_id, sp, |lint| {
lint.primary_message(msg);
let (span, link_range) = match link_range { let (span, link_range) = match link_range {
MarkdownLinkRange::Destination(md_range) => { MarkdownLinkRange::Destination(md_range) => {
let mut md_range = md_range.clone(); let mut md_range = md_range.clone();

View File

@ -24,8 +24,9 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) {
let sp = let sp =
source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings) source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings)
.unwrap_or_else(|| item.attr_span(cx.tcx)); .unwrap_or_else(|| item.attr_span(cx.tcx));
cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| { cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| {
lint.note("bare URLs are not automatically turned into clickable links") lint.primary_message(msg)
.note("bare URLs are not automatically turned into clickable links")
.span_suggestion( .span_suggestion(
sp, sp,
"use an automatic link instead", "use an automatic link instead",

View File

@ -99,7 +99,9 @@ fn check_rust_syntax(
// All points of divergence have been handled earlier so this can be // All points of divergence have been handled earlier so this can be
// done the same way whether the span is precise or not. // done the same way whether the span is precise or not.
let hir_id = cx.tcx.local_def_id_to_hir_id(local_id); let hir_id = cx.tcx.local_def_id_to_hir_id(local_id);
cx.tcx.node_span_lint(crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, msg, |lint| { cx.tcx.node_span_lint(crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, |lint| {
lint.primary_message(msg);
let explanation = if is_ignore { let explanation = if is_ignore {
"`ignore` code blocks require valid Rust code for syntax highlighting; \ "`ignore` code blocks require valid Rust code for syntax highlighting; \
mark blocks that do not contain Rust code as text" mark blocks that do not contain Rust code as text"

View File

@ -25,8 +25,11 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
Some(sp) => sp, Some(sp) => sp,
None => item.attr_span(tcx), None => item.attr_span(tcx),
}; };
tcx.node_span_lint(crate::lint::INVALID_HTML_TAGS, hir_id, sp, msg, |lint| { tcx.node_span_lint(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| {
use rustc_lint_defs::Applicability; use rustc_lint_defs::Applicability;
lint.primary_message(msg);
// If a tag looks like `<this>`, it might actually be a generic. // If a tag looks like `<this>`, it might actually be a generic.
// We don't try to detect stuff `<like, this>` because that's not valid HTML, // We don't try to detect stuff `<like, this>` because that's not valid HTML,
// and we don't try to detect stuff `<like this>` because that's not valid Rust. // and we don't try to detect stuff `<like this>` because that's not valid Rust.

View File

@ -188,8 +188,9 @@ fn check_inline_or_reference_unknown_redundancy(
&item.attrs.doc_strings, &item.attrs.doc_strings,
)?; )?;
cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, "redundant explicit link target", |lint| { cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| {
lint.span_label(explicit_span, "explicit target is redundant") lint.primary_message("redundant explicit link target")
.span_label(explicit_span, "explicit target is redundant")
.span_label(display_span, "because label contains path that resolves to same destination") .span_label(display_span, "because label contains path that resolves to same destination")
.note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links")
.span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways); .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways);
@ -238,8 +239,9 @@ fn check_reference_redundancy(
&item.attrs.doc_strings, &item.attrs.doc_strings,
)?; )?;
cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, "redundant explicit link target", |lint| { cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| {
lint.span_label(explicit_span, "explicit target is redundant") lint.primary_message("redundant explicit link target")
.span_label(explicit_span, "explicit target is redundant")
.span_label(display_span, "because label contains path that resolves to same destination") .span_label(display_span, "because label contains path that resolves to same destination")
.span_note(def_span, "referenced explicit link target defined here") .span_note(def_span, "referenced explicit link target defined here")
.note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links")

View File

@ -56,17 +56,28 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
) )
.unwrap_or_else(|| item.attr_span(tcx)); .unwrap_or_else(|| item.attr_span(tcx));
tcx.node_span_lint(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, "unescaped backtick", |lint| { tcx.node_span_lint(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, |lint| {
lint.primary_message("unescaped backtick");
let mut help_emitted = false; let mut help_emitted = false;
match element.prev_code_guess { match element.prev_code_guess {
PrevCodeGuess::None => {} PrevCodeGuess::None => {}
PrevCodeGuess::Start { guess, .. } => { PrevCodeGuess::Start { guess, .. } => {
// "foo` `bar`" -> "`foo` `bar`" // "foo` `bar`" -> "`foo` `bar`"
if let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges) if let Some(suggest_index) =
clamp_start(guess, &element.suggestible_ranges)
&& can_suggest_backtick(&dox, suggest_index) && can_suggest_backtick(&dox, suggest_index)
{ {
suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the opening backtick of a previous inline code may be missing"); suggest_insertion(
cx,
item,
&dox,
lint,
suggest_index,
'`',
"the opening backtick of a previous inline code may be missing",
);
help_emitted = true; help_emitted = true;
} }
} }
@ -76,7 +87,15 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
// an inline code node and we intentionally "break" the inline code here. // an inline code node and we intentionally "break" the inline code here.
let suggest_index = guess; let suggest_index = guess;
if can_suggest_backtick(&dox, suggest_index) { if can_suggest_backtick(&dox, suggest_index) {
suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "a previous inline code might be longer than expected"); suggest_insertion(
cx,
item,
&dox,
lint,
suggest_index,
'`',
"a previous inline code might be longer than expected",
);
help_emitted = true; help_emitted = true;
} }
} }
@ -84,11 +103,21 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
if !element.prev_code_guess.is_confident() { if !element.prev_code_guess.is_confident() {
// "`foo` bar`" -> "`foo` `bar`" // "`foo` bar`" -> "`foo` `bar`"
if let Some(guess) = guess_start_of_code(&dox, element.element_range.start..backtick_index) if let Some(guess) =
&& let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges) guess_start_of_code(&dox, element.element_range.start..backtick_index)
&& let Some(suggest_index) =
clamp_start(guess, &element.suggestible_ranges)
&& can_suggest_backtick(&dox, suggest_index) && can_suggest_backtick(&dox, suggest_index)
{ {
suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the opening backtick of an inline code may be missing"); suggest_insertion(
cx,
item,
&dox,
lint,
suggest_index,
'`',
"the opening backtick of an inline code may be missing",
);
help_emitted = true; help_emitted = true;
} }
@ -96,21 +125,41 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
// Don't suggest closing backtick after single trailing char, // Don't suggest closing backtick after single trailing char,
// if we already suggested opening backtick. For example: // if we already suggested opening backtick. For example:
// "foo`." -> "`foo`." or "foo`s" -> "`foo`s". // "foo`." -> "`foo`." or "foo`s" -> "`foo`s".
if let Some(guess) = guess_end_of_code(&dox, backtick_index + 1..element.element_range.end) if let Some(guess) =
&& let Some(suggest_index) = clamp_end(guess, &element.suggestible_ranges) guess_end_of_code(&dox, backtick_index + 1..element.element_range.end)
&& let Some(suggest_index) =
clamp_end(guess, &element.suggestible_ranges)
&& can_suggest_backtick(&dox, suggest_index) && can_suggest_backtick(&dox, suggest_index)
&& (!help_emitted || suggest_index - backtick_index > 2) && (!help_emitted || suggest_index - backtick_index > 2)
{ {
suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the closing backtick of an inline code may be missing"); suggest_insertion(
cx,
item,
&dox,
lint,
suggest_index,
'`',
"the closing backtick of an inline code may be missing",
);
help_emitted = true; help_emitted = true;
} }
} }
if !help_emitted { if !help_emitted {
lint.help("the opening or closing backtick of an inline code may be missing"); lint.help(
"the opening or closing backtick of an inline code may be missing",
);
} }
suggest_insertion(cx, item, &dox, lint, backtick_index, '\\', "if you meant to use a literal backtick, escape it"); suggest_insertion(
cx,
item,
&dox,
lint,
backtick_index,
'\\',
"if you meant to use a literal backtick, escape it",
);
}); });
} }
Event::Code(_) => { Event::Code(_) => {

View File

@ -61,7 +61,8 @@ fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) {
/// ``` /// ```
pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) { pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.span_lint(lint, sp, msg.into(), |diag| { cx.span_lint(lint, sp, |diag| {
diag.primary_message(msg);
docs_link(diag, lint); docs_link(diag, lint);
}); });
} }
@ -109,7 +110,8 @@ pub fn span_lint_and_help<T: LintContext>(
help: impl Into<SubdiagMessage>, help: impl Into<SubdiagMessage>,
) { ) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.span_lint(lint, span, msg.into(), |diag| { cx.span_lint(lint, span, |diag| {
diag.primary_message(msg);
if let Some(help_span) = help_span { if let Some(help_span) = help_span {
diag.span_help(help_span, help.into()); diag.span_help(help_span, help.into());
} else { } else {
@ -165,7 +167,8 @@ pub fn span_lint_and_note<T: LintContext>(
note: impl Into<SubdiagMessage>, note: impl Into<SubdiagMessage>,
) { ) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.span_lint(lint, span, msg.into(), |diag| { cx.span_lint(lint, span, |diag| {
diag.primary_message(msg);
if let Some(note_span) = note_span { if let Some(note_span) = note_span {
diag.span_note(note_span, note.into()); diag.span_note(note_span, note.into());
} else { } else {
@ -201,7 +204,8 @@ where
F: FnOnce(&mut Diag<'_, ()>), F: FnOnce(&mut Diag<'_, ()>),
{ {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.span_lint(lint, sp, msg, |diag| { cx.span_lint(lint, sp, |diag| {
diag.primary_message(msg);
f(diag); f(diag);
docs_link(diag, lint); docs_link(diag, lint);
}); });
@ -233,7 +237,8 @@ where
/// the `#[allow]` will work. /// the `#[allow]` will work.
pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: impl Into<DiagMessage>) { pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: impl Into<DiagMessage>) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.tcx.node_span_lint(lint, hir_id, sp, msg.into(), |diag| { cx.tcx.node_span_lint(lint, hir_id, sp, |diag| {
diag.primary_message(msg);
docs_link(diag, lint); docs_link(diag, lint);
}); });
} }
@ -271,7 +276,8 @@ pub fn span_lint_hir_and_then(
f: impl FnOnce(&mut Diag<'_, ()>), f: impl FnOnce(&mut Diag<'_, ()>),
) { ) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.tcx.node_span_lint(lint, hir_id, sp, msg.into(), |diag| { cx.tcx.node_span_lint(lint, hir_id, sp, |diag| {
diag.primary_message(msg);
f(diag); f(diag);
docs_link(diag, lint); docs_link(diag, lint);
}); });

View File

@ -11,11 +11,11 @@ use rustc_lint::{Lint, LintContext};
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) { pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
cx.span_lint(lint, span, msg, |_| {}); cx.span_lint(lint, span, |lint| { lint.primary_message(msg); });
} }
pub fn b(tcx: TyCtxt<'_>, lint: &'static Lint, hir_id: HirId, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) { pub fn b(tcx: TyCtxt<'_>, lint: &'static Lint, hir_id: HirId, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
tcx.node_span_lint(lint, hir_id, span, msg, |_| {}); tcx.node_span_lint(lint, hir_id, span, |lint| { lint.primary_message(msg); });
} }
fn main() {} fn main() {}

View File

@ -1,8 +1,8 @@
error: use of a disallowed method `rustc_lint::context::LintContext::span_lint` error: use of a disallowed method `rustc_lint::context::LintContext::span_lint`
--> tests/ui-internal/disallow_span_lint.rs:14:5 --> tests/ui-internal/disallow_span_lint.rs:14:5
| |
LL | cx.span_lint(lint, span, msg, |_| {}); LL | cx.span_lint(lint, span, |lint| { lint.primary_message(msg); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint*` functions instead (from clippy.toml) = note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint*` functions instead (from clippy.toml)
= note: `-D clippy::disallowed-methods` implied by `-D warnings` = note: `-D clippy::disallowed-methods` implied by `-D warnings`
@ -11,8 +11,8 @@ LL | cx.span_lint(lint, span, msg, |_| {});
error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint` error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint`
--> tests/ui-internal/disallow_span_lint.rs:18:5 --> tests/ui-internal/disallow_span_lint.rs:18:5
| |
LL | tcx.node_span_lint(lint, hir_id, span, msg, |_| {}); LL | tcx.node_span_lint(lint, hir_id, span, |lint| { lint.primary_message(msg); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead (from clippy.toml) = note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead (from clippy.toml)

View File

@ -85,10 +85,6 @@ impl<'a> LintDiagnostic<'a, ()> for UntranslatableInLintDiagnostic {
diag.note("untranslatable diagnostic"); diag.note("untranslatable diagnostic");
//~^ ERROR diagnostics should be created using translatable messages //~^ ERROR diagnostics should be created using translatable messages
} }
fn msg(&self) -> DiagMessage {
unreachable!();
}
} }
pub struct TranslatableInLintDiagnostic; pub struct TranslatableInLintDiagnostic;
@ -97,10 +93,6 @@ impl<'a> LintDiagnostic<'a, ()> for TranslatableInLintDiagnostic {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.note(crate::fluent_generated::no_crate_note); diag.note(crate::fluent_generated::no_crate_note);
} }
fn msg(&self) -> DiagMessage {
unreachable!();
}
} }
pub fn make_diagnostics<'a>(dcx: &'a DiagCtxt) { pub fn make_diagnostics<'a>(dcx: &'a DiagCtxt) {

View File

@ -23,7 +23,7 @@ LL | diag.note("untranslatable diagnostic");
| ^^^^ | ^^^^
error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls
--> $DIR/diagnostics.rs:107:21 --> $DIR/diagnostics.rs:99:21
| |
LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example); LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example);
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -35,13 +35,13 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls
--> $DIR/diagnostics.rs:110:21 --> $DIR/diagnostics.rs:102:21
| |
LL | let _diag = dcx.struct_err("untranslatable diagnostic"); LL | let _diag = dcx.struct_err("untranslatable diagnostic");
| ^^^^^^^^^^ | ^^^^^^^^^^
error: diagnostics should be created using translatable messages error: diagnostics should be created using translatable messages
--> $DIR/diagnostics.rs:110:21 --> $DIR/diagnostics.rs:102:21
| |
LL | let _diag = dcx.struct_err("untranslatable diagnostic"); LL | let _diag = dcx.struct_err("untranslatable diagnostic");
| ^^^^^^^^^^ | ^^^^^^^^^^

View File

@ -603,7 +603,6 @@ struct LintAttributeOnSessionDiag {}
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[lint(no_crate_example, code = E0123)] #[lint(no_crate_example, code = E0123)]
//~^ ERROR `#[lint(...)]` is not a valid attribute //~^ ERROR `#[lint(...)]` is not a valid attribute
//~| ERROR `#[lint(...)]` is not a valid attribute
//~| ERROR diagnostic slug not specified //~| ERROR diagnostic slug not specified
//~| ERROR cannot find attribute `lint` in this scope //~| ERROR cannot find attribute `lint` in this scope
struct LintAttributeOnLintDiag {} struct LintAttributeOnLintDiag {}

View File

@ -378,14 +378,6 @@ error: `#[lint(...)]` is not a valid attribute
LL | #[lint(no_crate_example, code = E0123)] LL | #[lint(no_crate_example, code = E0123)]
| ^ | ^
error: `#[lint(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:604:1
|
LL | #[lint(no_crate_example, code = E0123)]
| ^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: diagnostic slug not specified error: diagnostic slug not specified
--> $DIR/diagnostic-derive.rs:604:1 --> $DIR/diagnostic-derive.rs:604:1
| |
@ -395,19 +387,19 @@ LL | #[lint(no_crate_example, code = E0123)]
= help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]`
error: specified multiple times error: specified multiple times
--> $DIR/diagnostic-derive.rs:614:53 --> $DIR/diagnostic-derive.rs:613:53
| |
LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
| ^^^^ | ^^^^
| |
note: previously specified here note: previously specified here
--> $DIR/diagnostic-derive.rs:614:39 --> $DIR/diagnostic-derive.rs:613:39
| |
LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
| ^^^^ | ^^^^
error: wrong types for suggestion error: wrong types for suggestion
--> $DIR/diagnostic-derive.rs:623:24 --> $DIR/diagnostic-derive.rs:622:24
| |
LL | suggestion: (Span, usize), LL | suggestion: (Span, usize),
| ^^^^^ | ^^^^^
@ -415,7 +407,7 @@ LL | suggestion: (Span, usize),
= help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
error: wrong types for suggestion error: wrong types for suggestion
--> $DIR/diagnostic-derive.rs:631:17 --> $DIR/diagnostic-derive.rs:630:17
| |
LL | suggestion: (Span,), LL | suggestion: (Span,),
| ^^^^^^^ | ^^^^^^^
@ -423,13 +415,13 @@ LL | suggestion: (Span,),
= help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
error: suggestion without `code = "..."` error: suggestion without `code = "..."`
--> $DIR/diagnostic-derive.rs:638:5 --> $DIR/diagnostic-derive.rs:637:5
| |
LL | #[suggestion(no_crate_suggestion)] LL | #[suggestion(no_crate_suggestion)]
| ^ | ^
error: `#[multipart_suggestion(...)]` is not a valid attribute error: `#[multipart_suggestion(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:645:1 --> $DIR/diagnostic-derive.rs:644:1
| |
LL | #[multipart_suggestion(no_crate_suggestion)] LL | #[multipart_suggestion(no_crate_suggestion)]
| ^ | ^
@ -437,7 +429,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)]
= help: consider creating a `Subdiagnostic` instead = help: consider creating a `Subdiagnostic` instead
error: `#[multipart_suggestion(...)]` is not a valid attribute error: `#[multipart_suggestion(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:648:1 --> $DIR/diagnostic-derive.rs:647:1
| |
LL | #[multipart_suggestion()] LL | #[multipart_suggestion()]
| ^ | ^
@ -445,7 +437,7 @@ LL | #[multipart_suggestion()]
= help: consider creating a `Subdiagnostic` instead = help: consider creating a `Subdiagnostic` instead
error: `#[multipart_suggestion(...)]` is not a valid attribute error: `#[multipart_suggestion(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:652:5 --> $DIR/diagnostic-derive.rs:651:5
| |
LL | #[multipart_suggestion(no_crate_suggestion)] LL | #[multipart_suggestion(no_crate_suggestion)]
| ^ | ^
@ -453,7 +445,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)]
= help: consider creating a `Subdiagnostic` instead = help: consider creating a `Subdiagnostic` instead
error: `#[suggestion(...)]` is not a valid attribute error: `#[suggestion(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:660:1 --> $DIR/diagnostic-derive.rs:659:1
| |
LL | #[suggestion(no_crate_suggestion, code = "...")] LL | #[suggestion(no_crate_suggestion, code = "...")]
| ^ | ^
@ -461,7 +453,7 @@ LL | #[suggestion(no_crate_suggestion, code = "...")]
= help: `#[label]` and `#[suggestion]` can only be applied to fields = help: `#[label]` and `#[suggestion]` can only be applied to fields
error: `#[label]` is not a valid attribute error: `#[label]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:669:1 --> $DIR/diagnostic-derive.rs:668:1
| |
LL | #[label] LL | #[label]
| ^ | ^
@ -469,61 +461,61 @@ LL | #[label]
= help: `#[label]` and `#[suggestion]` can only be applied to fields = help: `#[label]` and `#[suggestion]` can only be applied to fields
error: `#[subdiagnostic(...)]` is not a valid attribute error: `#[subdiagnostic(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:703:5 --> $DIR/diagnostic-derive.rs:702:5
| |
LL | #[subdiagnostic(bad)] LL | #[subdiagnostic(bad)]
| ^ | ^
error: `#[subdiagnostic = ...]` is not a valid attribute error: `#[subdiagnostic = ...]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:711:5 --> $DIR/diagnostic-derive.rs:710:5
| |
LL | #[subdiagnostic = "bad"] LL | #[subdiagnostic = "bad"]
| ^ | ^
error: `#[subdiagnostic(...)]` is not a valid attribute error: `#[subdiagnostic(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:719:5 --> $DIR/diagnostic-derive.rs:718:5
| |
LL | #[subdiagnostic(bad, bad)] LL | #[subdiagnostic(bad, bad)]
| ^ | ^
error: `#[subdiagnostic(...)]` is not a valid attribute error: `#[subdiagnostic(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:727:5 --> $DIR/diagnostic-derive.rs:726:5
| |
LL | #[subdiagnostic("bad")] LL | #[subdiagnostic("bad")]
| ^ | ^
error: `#[subdiagnostic(...)]` is not a valid attribute error: `#[subdiagnostic(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:735:5 --> $DIR/diagnostic-derive.rs:734:5
| |
LL | #[subdiagnostic(eager)] LL | #[subdiagnostic(eager)]
| ^ | ^
error: `#[subdiagnostic(...)]` is not a valid attribute error: `#[subdiagnostic(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:743:5 --> $DIR/diagnostic-derive.rs:742:5
| |
LL | #[subdiagnostic(eager)] LL | #[subdiagnostic(eager)]
| ^ | ^
error: `#[subdiagnostic(...)]` is not a valid attribute error: `#[subdiagnostic(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:764:5 --> $DIR/diagnostic-derive.rs:763:5
| |
LL | #[subdiagnostic(eager)] LL | #[subdiagnostic(eager)]
| ^ | ^
error: expected at least one string literal for `code(...)` error: expected at least one string literal for `code(...)`
--> $DIR/diagnostic-derive.rs:795:23 --> $DIR/diagnostic-derive.rs:794:23
| |
LL | #[suggestion(code())] LL | #[suggestion(code())]
| ^ | ^
error: `code(...)` must contain only string literals error: `code(...)` must contain only string literals
--> $DIR/diagnostic-derive.rs:803:23 --> $DIR/diagnostic-derive.rs:802:23
| |
LL | #[suggestion(code(foo))] LL | #[suggestion(code(foo))]
| ^^^ | ^^^
error: `#[suggestion(...)]` is not a valid attribute error: `#[suggestion(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:827:5 --> $DIR/diagnostic-derive.rs:826:5
| |
LL | #[suggestion(no_crate_suggestion, code = "")] LL | #[suggestion(no_crate_suggestion, code = "")]
| ^ | ^
@ -539,13 +531,13 @@ LL | #[diag = "E0123"]
| ^ maybe a missing crate `core`? | ^ maybe a missing crate `core`?
error[E0433]: failed to resolve: maybe a missing crate `core`? error[E0433]: failed to resolve: maybe a missing crate `core`?
--> $DIR/diagnostic-derive.rs:803:23 --> $DIR/diagnostic-derive.rs:802:23
| |
LL | #[suggestion(code(foo))] LL | #[suggestion(code(foo))]
| ^^^ maybe a missing crate `core`? | ^^^ maybe a missing crate `core`?
error[E0433]: failed to resolve: maybe a missing crate `core`? error[E0433]: failed to resolve: maybe a missing crate `core`?
--> $DIR/diagnostic-derive.rs:812:25 --> $DIR/diagnostic-derive.rs:811:25
| |
LL | #[suggestion(code = 3)] LL | #[suggestion(code = 3)]
| ^ maybe a missing crate `core`? | ^ maybe a missing crate `core`?
@ -587,19 +579,19 @@ LL | #[lint(no_crate_example, code = E0123)]
| ^^^^ help: a built-in attribute with a similar name exists: `link` | ^^^^ help: a built-in attribute with a similar name exists: `link`
error: cannot find attribute `multipart_suggestion` in this scope error: cannot find attribute `multipart_suggestion` in this scope
--> $DIR/diagnostic-derive.rs:645:3 --> $DIR/diagnostic-derive.rs:644:3
| |
LL | #[multipart_suggestion(no_crate_suggestion)] LL | #[multipart_suggestion(no_crate_suggestion)]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: cannot find attribute `multipart_suggestion` in this scope error: cannot find attribute `multipart_suggestion` in this scope
--> $DIR/diagnostic-derive.rs:648:3 --> $DIR/diagnostic-derive.rs:647:3
| |
LL | #[multipart_suggestion()] LL | #[multipart_suggestion()]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: cannot find attribute `multipart_suggestion` in this scope error: cannot find attribute `multipart_suggestion` in this scope
--> $DIR/diagnostic-derive.rs:652:7 --> $DIR/diagnostic-derive.rs:651:7
| |
LL | #[multipart_suggestion(no_crate_suggestion)] LL | #[multipart_suggestion(no_crate_suggestion)]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -611,7 +603,7 @@ LL | #[diag(nonsense, code = E0123)]
| ^^^^^^^^ not found in `crate::fluent_generated` | ^^^^^^^^ not found in `crate::fluent_generated`
error[E0425]: cannot find value `__code_34` in this scope error[E0425]: cannot find value `__code_34` in this scope
--> $DIR/diagnostic-derive.rs:809:10 --> $DIR/diagnostic-derive.rs:808:10
| |
LL | #[derive(Diagnostic)] LL | #[derive(Diagnostic)]
| ^^^^^^^^^^ not found in this scope | ^^^^^^^^^^ not found in this scope
@ -632,7 +624,7 @@ note: required by a bound in `Diag::<'a, G>::arg`
--> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC
= note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 86 previous errors error: aborting due to 85 previous errors
Some errors have detailed explanations: E0277, E0425, E0433. Some errors have detailed explanations: E0277, E0425, E0433.
For more information about an error, try `rustc --explain E0277`. For more information about an error, try `rustc --explain E0277`.