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:
parent
366ef95407
commit
06bc4fc671
44 changed files with 430 additions and 488 deletions
|
@ -564,8 +564,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
lint::builtin::INLINE_NO_SANITIZE,
|
||||
hir_id,
|
||||
no_sanitize_span,
|
||||
"`no_sanitize` will have no effect after inlining",
|
||||
|lint| {
|
||||
lint.primary_message("`no_sanitize` will have no effect after inlining");
|
||||
lint.span_note(inline_span, "inlining requested here");
|
||||
},
|
||||
)
|
||||
|
|
|
@ -200,8 +200,6 @@ pub trait SubdiagMessageOp<G: EmissionGuarantee> =
|
|||
pub trait LintDiagnostic<'a, G: EmissionGuarantee> {
|
||||
/// Decorate and emit a lint.
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>);
|
||||
|
||||
fn msg(&self) -> DiagMessage;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Encodable, Decodable)]
|
||||
|
|
|
@ -46,13 +46,9 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
|
|||
.emit();
|
||||
}
|
||||
None => {
|
||||
tcx.node_span_lint(
|
||||
UNSUPPORTED_CALLING_CONVENTIONS,
|
||||
hir_id,
|
||||
span,
|
||||
"use of calling convention not supported on this target",
|
||||
|_| {},
|
||||
);
|
||||
tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
|
||||
lint.primary_message("use of calling convention not supported on this target");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,8 +239,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
UNINHABITED_STATIC,
|
||||
tcx.local_def_id_to_hir_id(def_id),
|
||||
span,
|
||||
"static of uninhabited type",
|
||||
|lint| {
|
||||
lint.primary_message("static of uninhabited type");
|
||||
lint
|
||||
.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,
|
||||
tcx.local_def_id_to_hir_id(adt.did().expect_local()),
|
||||
span,
|
||||
"zero-sized fields in `repr(transparent)` cannot \
|
||||
contain external non-exhaustive types",
|
||||
|lint| {
|
||||
lint.primary_message(
|
||||
"zero-sized fields in `repr(transparent)` cannot \
|
||||
contain external non-exhaustive types",
|
||||
);
|
||||
let note = if non_exhaustive {
|
||||
"is marked with `#[non_exhaustive]`"
|
||||
} else {
|
||||
|
|
|
@ -281,8 +281,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
lint::builtin::ASM_SUB_REGISTER,
|
||||
expr.hir_id,
|
||||
spans,
|
||||
"formatting may not be suitable for sub-register argument",
|
||||
|lint| {
|
||||
lint.primary_message("formatting may not be suitable for sub-register argument");
|
||||
lint.span_label(expr.span, "for this argument");
|
||||
lint.help(format!(
|
||||
"use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}` (for {suggested_size}-bit values)",
|
||||
|
|
|
@ -35,11 +35,12 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
|
|||
continue;
|
||||
}
|
||||
let (path, _) = item.expect_use();
|
||||
let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
|
||||
format!("unused import: `{snippet}`")
|
||||
} else {
|
||||
"unused import".to_owned()
|
||||
};
|
||||
tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, msg, |_| {});
|
||||
tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| {
|
||||
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
|
||||
lint.primary_message(format!("unused import: `{snippet}`"));
|
||||
} else {
|
||||
lint.primary_message("unused import");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -317,8 +317,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
|
||||
param.hir_id,
|
||||
param.span,
|
||||
TYPE_DEFAULT_NOT_ALLOWED,
|
||||
|_| {},
|
||||
|lint| {
|
||||
lint.primary_message(TYPE_DEFAULT_NOT_ALLOWED);
|
||||
},
|
||||
);
|
||||
}
|
||||
Defaults::Deny => {
|
||||
|
|
|
@ -646,8 +646,9 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
|
|||
LATE_BOUND_LIFETIME_ARGUMENTS,
|
||||
args.args[0].hir_id(),
|
||||
multispan,
|
||||
msg,
|
||||
|_| {},
|
||||
|lint| {
|
||||
lint.primary_message(msg);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,8 +72,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
|
||||
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
|
||||
} 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, msg, |lint| {
|
||||
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| {
|
||||
lint.primary_message("trait objects without an explicit `dyn` are deprecated");
|
||||
if self_ty.span.can_be_used_for_suggestions() {
|
||||
lint.multipart_suggestion_verbose(
|
||||
"if this is an object-safe trait, use `dyn`",
|
||||
|
|
|
@ -1164,33 +1164,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let ty = self.lower_assoc_ty(span, assoc_ty_did, assoc_segment, bound);
|
||||
|
||||
if let Some(variant_def_id) = variant_resolution {
|
||||
tcx.node_span_lint(
|
||||
AMBIGUOUS_ASSOCIATED_ITEMS,
|
||||
hir_ref_id,
|
||||
span,
|
||||
"ambiguous associated item",
|
||||
|lint| {
|
||||
let mut could_refer_to = |kind: DefKind, def_id, also| {
|
||||
let note_msg = format!(
|
||||
"`{}` could{} refer to the {} defined here",
|
||||
assoc_ident,
|
||||
also,
|
||||
tcx.def_kind_descr(kind, def_id)
|
||||
);
|
||||
lint.span_note(tcx.def_span(def_id), note_msg);
|
||||
};
|
||||
|
||||
could_refer_to(DefKind::Variant, variant_def_id, "");
|
||||
could_refer_to(DefKind::AssocTy, assoc_ty_did, " also");
|
||||
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"use fully-qualified syntax",
|
||||
format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
|
||||
Applicability::MachineApplicable,
|
||||
tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| {
|
||||
lint.primary_message("ambiguous associated item");
|
||||
let mut could_refer_to = |kind: DefKind, def_id, also| {
|
||||
let note_msg = format!(
|
||||
"`{}` could{} refer to the {} defined here",
|
||||
assoc_ident,
|
||||
also,
|
||||
tcx.def_kind_descr(kind, def_id)
|
||||
);
|
||||
},
|
||||
);
|
||||
lint.span_note(tcx.def_span(def_id), note_msg);
|
||||
};
|
||||
|
||||
could_refer_to(DefKind::Variant, variant_def_id, "");
|
||||
could_refer_to(DefKind::AssocTy, assoc_ty_did, " also");
|
||||
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"use fully-qualified syntax",
|
||||
format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
});
|
||||
}
|
||||
Ok((ty, DefKind::AssocTy, assoc_ty_did))
|
||||
}
|
||||
|
|
|
@ -63,19 +63,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
|
||||
|
||||
let msg = format!("unreachable {kind}");
|
||||
self.tcx().node_span_lint(
|
||||
lint::builtin::UNREACHABLE_CODE,
|
||||
id,
|
||||
span,
|
||||
msg.clone(),
|
||||
|lint| {
|
||||
lint.span_label(span, msg).span_label(
|
||||
orig_span,
|
||||
custom_note
|
||||
.unwrap_or("any code following this expression is unreachable"),
|
||||
);
|
||||
},
|
||||
)
|
||||
self.tcx().node_span_lint(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
|
||||
lint.primary_message(msg.clone());
|
||||
lint.span_label(span, msg).span_label(
|
||||
orig_span,
|
||||
custom_note.unwrap_or("any code following this expression is unreachable"),
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,11 +91,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
prelude_or_array_lint,
|
||||
self_expr.hir_id,
|
||||
self_expr.span,
|
||||
format!(
|
||||
"trait method `{}` will become ambiguous in Rust {edition}",
|
||||
segment.ident.name
|
||||
),
|
||||
|lint| {
|
||||
lint.primary_message(format!(
|
||||
"trait method `{}` will become ambiguous in Rust {edition}",
|
||||
segment.ident.name
|
||||
));
|
||||
|
||||
let sp = self_expr.span;
|
||||
|
||||
let derefs = "*".repeat(pick.autoderefs);
|
||||
|
@ -144,11 +145,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
prelude_or_array_lint,
|
||||
call_expr.hir_id,
|
||||
call_expr.span,
|
||||
format!(
|
||||
"trait method `{}` will become ambiguous in Rust {edition}",
|
||||
segment.ident.name
|
||||
),
|
||||
|lint| {
|
||||
lint.primary_message(format!(
|
||||
"trait method `{}` will become ambiguous in Rust {edition}",
|
||||
segment.ident.name
|
||||
));
|
||||
|
||||
let sp = call_expr.span;
|
||||
let trait_name = self.trait_path_or_bare_name(
|
||||
span,
|
||||
|
@ -251,73 +253,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
self.tcx.node_span_lint(
|
||||
RUST_2021_PRELUDE_COLLISIONS,
|
||||
expr_id,
|
||||
span,
|
||||
format!(
|
||||
self.tcx.node_span_lint(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| {
|
||||
lint.primary_message(format!(
|
||||
"trait-associated function `{}` will become ambiguous in Rust 2021",
|
||||
method_name.name
|
||||
),
|
||||
|lint| {
|
||||
// "type" refers to either a type or, more likely, a trait from which
|
||||
// the associated function or method is from.
|
||||
let container_id = pick.item.container_id(self.tcx);
|
||||
let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id);
|
||||
let trait_generics = self.tcx.generics_of(container_id);
|
||||
));
|
||||
|
||||
let trait_name =
|
||||
if trait_generics.own_params.len() <= trait_generics.has_self as usize {
|
||||
trait_path
|
||||
} else {
|
||||
let counts = trait_generics.own_counts();
|
||||
format!(
|
||||
"{}<{}>",
|
||||
trait_path,
|
||||
// "type" refers to either a type or, more likely, a trait from which
|
||||
// the associated function or method is from.
|
||||
let container_id = pick.item.container_id(self.tcx);
|
||||
let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id);
|
||||
let trait_generics = self.tcx.generics_of(container_id);
|
||||
|
||||
let trait_name =
|
||||
if trait_generics.own_params.len() <= trait_generics.has_self as usize {
|
||||
trait_path
|
||||
} else {
|
||||
let counts = trait_generics.own_counts();
|
||||
format!(
|
||||
"{}<{}>",
|
||||
trait_path,
|
||||
std::iter::repeat("'_")
|
||||
.take(counts.lifetimes)
|
||||
.chain(std::iter::repeat("_").take(
|
||||
counts.types + counts.consts - trait_generics.has_self as usize
|
||||
))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
};
|
||||
|
||||
let mut self_ty_name = self_ty_span
|
||||
.find_ancestor_inside(span)
|
||||
.and_then(|span| self.sess().source_map().span_to_snippet(span).ok())
|
||||
.unwrap_or_else(|| self_ty.to_string());
|
||||
|
||||
// Get the number of generics the self type has (if an Adt) unless we can determine that
|
||||
// the user has written the self type with generics already which we (naively) do by looking
|
||||
// for a "<" in `self_ty_name`.
|
||||
if !self_ty_name.contains('<') {
|
||||
if let ty::Adt(def, _) = self_ty.kind() {
|
||||
let generics = self.tcx.generics_of(def.did());
|
||||
if !generics.is_own_empty() {
|
||||
let counts = generics.own_counts();
|
||||
self_ty_name += &format!(
|
||||
"<{}>",
|
||||
std::iter::repeat("'_")
|
||||
.take(counts.lifetimes)
|
||||
.chain(std::iter::repeat("_").take(
|
||||
counts.types + counts.consts - trait_generics.has_self as usize
|
||||
))
|
||||
.chain(std::iter::repeat("_").take(counts.types + counts.consts))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
};
|
||||
|
||||
let mut self_ty_name = self_ty_span
|
||||
.find_ancestor_inside(span)
|
||||
.and_then(|span| self.sess().source_map().span_to_snippet(span).ok())
|
||||
.unwrap_or_else(|| self_ty.to_string());
|
||||
|
||||
// Get the number of generics the self type has (if an Adt) unless we can determine that
|
||||
// the user has written the self type with generics already which we (naively) do by looking
|
||||
// for a "<" in `self_ty_name`.
|
||||
if !self_ty_name.contains('<') {
|
||||
if let ty::Adt(def, _) = self_ty.kind() {
|
||||
let generics = self.tcx.generics_of(def.did());
|
||||
if !generics.is_own_empty() {
|
||||
let counts = generics.own_counts();
|
||||
self_ty_name += &format!(
|
||||
"<{}>",
|
||||
std::iter::repeat("'_")
|
||||
.take(counts.lifetimes)
|
||||
.chain(
|
||||
std::iter::repeat("_").take(counts.types + counts.consts)
|
||||
)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"disambiguate the associated function",
|
||||
format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"disambiguate the associated function",
|
||||
format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn trait_path_or_bare_name(
|
||||
|
|
|
@ -408,8 +408,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
lint::builtin::TYVAR_BEHIND_RAW_POINTER,
|
||||
scope_expr_id,
|
||||
span,
|
||||
"type annotations needed",
|
||||
|_| {},
|
||||
|lint| {
|
||||
lint.primary_message("type annotations needed");
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// Ended up encountering a type variable when doing autoderef,
|
||||
|
@ -1279,53 +1280,49 @@ impl<'tcx> Pick<'tcx> {
|
|||
return;
|
||||
}
|
||||
let def_kind = self.item.kind.as_def_kind();
|
||||
tcx.node_span_lint(
|
||||
lint::builtin::UNSTABLE_NAME_COLLISIONS,
|
||||
scope_expr_id,
|
||||
span,
|
||||
format!(
|
||||
tcx.node_span_lint(lint::builtin::UNSTABLE_NAME_COLLISIONS, scope_expr_id, span, |lint| {
|
||||
lint.primary_message(format!(
|
||||
"{} {} 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(def_kind, self.item.def_id),
|
||||
),
|
||||
|lint| {
|
||||
match (self.item.kind, self.item.container) {
|
||||
(ty::AssocKind::Fn, _) => {
|
||||
// FIXME: This should be a `span_suggestion` instead of `help`
|
||||
// However `self.span` only
|
||||
// highlights the method name, so we can't use it. Also consider reusing
|
||||
// the code from `report_method_error()`.
|
||||
lint.help(format!(
|
||||
"call with fully qualified syntax `{}(...)` to keep using the current \
|
||||
));
|
||||
|
||||
match (self.item.kind, self.item.container) {
|
||||
(ty::AssocKind::Fn, _) => {
|
||||
// FIXME: This should be a `span_suggestion` instead of `help`
|
||||
// However `self.span` only
|
||||
// highlights the method name, so we can't use it. Also consider reusing
|
||||
// the code from `report_method_error()`.
|
||||
lint.help(format!(
|
||||
"call with fully qualified syntax `{}(...)` to keep using the current \
|
||||
method",
|
||||
tcx.def_path_str(self.item.def_id),
|
||||
));
|
||||
}
|
||||
(ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => {
|
||||
let def_id = self.item.container_id(tcx);
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"use the fully qualified path to the associated const",
|
||||
format!(
|
||||
"<{} as {}>::{}",
|
||||
self.self_ty,
|
||||
tcx.def_path_str(def_id),
|
||||
self.item.name
|
||||
),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
tcx.def_path_str(self.item.def_id),
|
||||
));
|
||||
}
|
||||
tcx.disabled_nightly_features(
|
||||
lint,
|
||||
Some(scope_expr_id),
|
||||
self.unstable_candidates.iter().map(|(candidate, feature)| {
|
||||
(format!(" `{}`", tcx.def_path_str(candidate.item.def_id)), *feature)
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
(ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => {
|
||||
let def_id = self.item.container_id(tcx);
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"use the fully qualified path to the associated const",
|
||||
format!(
|
||||
"<{} as {}>::{}",
|
||||
self.self_ty,
|
||||
tcx.def_path_str(def_id),
|
||||
self.item.name
|
||||
),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
tcx.disabled_nightly_features(
|
||||
lint,
|
||||
Some(scope_expr_id),
|
||||
self.unstable_candidates.iter().map(|(candidate, feature)| {
|
||||
(format!(" `{}`", tcx.def_path_str(candidate.item.def_id)), *feature)
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1950,15 +1950,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&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| {
|
||||
lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns));
|
||||
lint.help(
|
||||
"ensure that all fields are mentioned explicitly by adding the suggested fields",
|
||||
);
|
||||
lint.note(format!(
|
||||
"the pattern is of type `{ty}` and the `non_exhaustive_omitted_patterns` attribute was found",
|
||||
));
|
||||
});
|
||||
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.help(
|
||||
"ensure that all fields are mentioned explicitly by adding the suggested fields",
|
||||
);
|
||||
lint.note(format!(
|
||||
"the pattern is of type `{ty}` and the `non_exhaustive_omitted_patterns` attribute was found",
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns a diagnostic reporting a struct pattern which does not mention some fields.
|
||||
|
|
|
@ -928,8 +928,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
|
||||
closure_hir_id,
|
||||
closure_head_span,
|
||||
reasons.migration_message(),
|
||||
|lint| {
|
||||
lint.primary_message(reasons.migration_message());
|
||||
|
||||
for NeededMigration { var_hir_id, diagnostics_info } in &need_migrations {
|
||||
// Labels all the usage of the captured variable and why they are responsible
|
||||
// for migration being needed
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::passes::{EarlyLintPassObject, LateLintPassObject};
|
|||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::sync;
|
||||
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_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
|
@ -556,7 +556,6 @@ pub trait LintContext {
|
|||
&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<S>,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
|
||||
);
|
||||
|
||||
|
@ -568,8 +567,8 @@ pub trait LintContext {
|
|||
span: S,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
) {
|
||||
self.opt_span_lint(lint, Some(span), decorator.msg(), |diag| {
|
||||
decorator.decorate_lint(diag);
|
||||
self.opt_span_lint(lint, Some(span), |lint| {
|
||||
decorator.decorate_lint(lint);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -581,17 +580,16 @@ pub trait LintContext {
|
|||
&self,
|
||||
lint: &'static Lint,
|
||||
span: S,
|
||||
msg: impl Into<DiagMessage>,
|
||||
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
|
||||
/// generated by `#[derive(LintDiagnostic)]`).
|
||||
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| {
|
||||
decorator.decorate_lint(diag);
|
||||
self.opt_span_lint(lint, None as Option<Span>, |lint| {
|
||||
decorator.decorate_lint(lint);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -599,13 +597,8 @@ pub trait LintContext {
|
|||
///
|
||||
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
|
||||
#[rustc_lint_diagnostics]
|
||||
fn lint(
|
||||
&self,
|
||||
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);
|
||||
fn lint(&self, lint: &'static Lint, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)) {
|
||||
self.opt_span_lint(lint, None as Option<Span>, decorate);
|
||||
}
|
||||
|
||||
/// This returns the lint level for the given lint at the current location.
|
||||
|
@ -668,14 +661,13 @@ impl<'tcx> LintContext for LateContext<'tcx> {
|
|||
&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<S>,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
|
||||
) {
|
||||
let hir_id = self.last_node_with_lint_attrs;
|
||||
|
||||
match span {
|
||||
Some(s) => self.tcx.node_span_lint(lint, hir_id, s, msg, decorate),
|
||||
None => self.tcx.node_lint(lint, hir_id, msg, decorate),
|
||||
Some(s) => self.tcx.node_span_lint(lint, hir_id, s, decorate),
|
||||
None => self.tcx.node_lint(lint, hir_id, decorate),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -695,10 +687,9 @@ impl LintContext for EarlyContext<'_> {
|
|||
&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<S>,
|
||||
msg: impl Into<DiagMessage>,
|
||||
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 {
|
||||
|
|
|
@ -369,6 +369,7 @@ struct ImplTraitOvercapturesLint<'tcx> {
|
|||
|
||||
impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> {
|
||||
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())
|
||||
.arg("num_captured", self.num_captured)
|
||||
.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)]
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
|||
use rustc_ast as ast;
|
||||
use rustc_ast_pretty::pprust;
|
||||
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_hir as hir;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
|
@ -1063,26 +1063,19 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||
// FIXME: make this translatable
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
lint_level(
|
||||
self.sess,
|
||||
lint,
|
||||
level,
|
||||
src,
|
||||
Some(span.into()),
|
||||
fluent::lint_unknown_gated_lint,
|
||||
|lint| {
|
||||
lint.arg("name", lint_id.lint.name_lower());
|
||||
lint.note(fluent::lint_note);
|
||||
rustc_session::parse::add_feature_diagnostics_for_issue(
|
||||
lint,
|
||||
&self.sess,
|
||||
feature,
|
||||
GateIssue::Language,
|
||||
lint_from_cli,
|
||||
None,
|
||||
);
|
||||
},
|
||||
);
|
||||
lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
|
||||
lint.primary_message(fluent::lint_unknown_gated_lint);
|
||||
lint.arg("name", lint_id.lint.name_lower());
|
||||
lint.note(fluent::lint_note);
|
||||
rustc_session::parse::add_feature_diagnostics_for_issue(
|
||||
lint,
|
||||
&self.sess,
|
||||
feature,
|
||||
GateIssue::Language,
|
||||
lint_from_cli,
|
||||
None,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
false
|
||||
|
@ -1103,11 +1096,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||
&self,
|
||||
lint: &'static Lint,
|
||||
span: Option<MultiSpan>,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
|
||||
) {
|
||||
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]
|
||||
|
@ -1118,7 +1110,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||
decorate: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
) {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
@ -1126,7 +1118,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||
#[track_caller]
|
||||
pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> LintDiagnostic<'a, ()>) {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -145,12 +145,9 @@ pub struct BuiltinMissingDebugImpl<'a> {
|
|||
// Needed for def_path_str
|
||||
impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> {
|
||||
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));
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
fluent::lint_builtin_missing_debug_impl
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
|
@ -250,6 +247,7 @@ pub struct BuiltinUngatedAsyncFnTrackCaller<'a> {
|
|||
|
||||
impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
|
||||
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);
|
||||
rustc_session::parse::add_feature_diagnostics(
|
||||
diag,
|
||||
|
@ -257,10 +255,6 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
|
|||
sym::async_fn_track_caller,
|
||||
);
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
fluent::lint_ungated_async_fn_track_caller
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
|
@ -432,6 +426,7 @@ pub struct BuiltinUnpermittedTypeInit<'a> {
|
|||
|
||||
impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(self.msg);
|
||||
diag.arg("ty", self.ty);
|
||||
diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label);
|
||||
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);
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
self.msg.clone()
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(davidtwco): make translatable
|
||||
|
@ -1168,6 +1159,7 @@ pub struct NonFmtPanicUnused {
|
|||
// Used because of two suggestions based on one Option<Span>
|
||||
impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused {
|
||||
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.note(fluent::lint_note);
|
||||
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)]
|
||||
|
@ -1410,13 +1398,10 @@ pub struct DropTraitConstraintsDiag<'a> {
|
|||
// Needed for def_path_str
|
||||
impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> {
|
||||
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("needs_drop", self.tcx.def_path_str(self.def_id));
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
fluent::lint_drop_trait_constraints
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DropGlue<'a> {
|
||||
|
@ -1427,12 +1412,9 @@ pub struct DropGlue<'a> {
|
|||
// Needed for def_path_str
|
||||
impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> {
|
||||
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));
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
fluent::lint_drop_glue
|
||||
}
|
||||
}
|
||||
|
||||
// types.rs
|
||||
|
@ -1710,6 +1692,7 @@ pub struct ImproperCTypes<'a> {
|
|||
// Used because of the complexity of Option<DiagMessage>, DiagMessage, and Option<Span>
|
||||
impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(fluent::lint_improper_ctypes);
|
||||
diag.arg("ty", self.ty);
|
||||
diag.arg("desc", self.desc);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
fluent::lint_improper_ctypes
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
|
@ -1853,6 +1832,7 @@ pub enum UnusedDefSuggestion {
|
|||
// Needed because of def_path_str
|
||||
impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(fluent::lint_unused_def);
|
||||
diag.arg("pre", self.pre);
|
||||
diag.arg("post", self.post);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
fluent::lint_unused_def
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
|
@ -1936,15 +1912,12 @@ pub struct AsyncFnInTraitDiag {
|
|||
|
||||
impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(fluent::lint_async_fn_in_trait);
|
||||
diag.note(fluent::lint_note);
|
||||
if let Some(sugg) = self.sugg {
|
||||
diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect);
|
||||
}
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
fluent::lint_async_fn_in_trait
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
|
@ -2260,10 +2233,8 @@ pub struct UnstableFeature {
|
|||
}
|
||||
|
||||
impl<'a> LintDiagnostic<'a, ()> for UnstableFeature {
|
||||
fn decorate_lint<'b>(self, _diag: &'b mut Diag<'a, ()>) {}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
self.msg.clone()
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||
diag.primary_message(self.msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2725,12 +2696,9 @@ pub struct AmbiguousGlobImports {
|
|||
|
||||
impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports {
|
||||
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);
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
DiagMessage::Str(self.ambiguity.msg.clone().into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
|
|
|
@ -123,7 +123,8 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
|||
}
|
||||
|
||||
#[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.note(fluent::lint_note);
|
||||
lint.note(fluent::lint_more_info_note);
|
||||
|
|
|
@ -105,25 +105,12 @@ impl<'a> LintDiagnosticDerive<'a> {
|
|||
pub(crate) fn into_tokens(self) -> TokenStream {
|
||||
let LintDiagnosticDerive { mut structure } = self;
|
||||
let kind = DiagnosticDeriveKind::LintDiagnostic;
|
||||
let slugs = RefCell::new(Vec::new());
|
||||
let implementation = kind.each_variant(&mut structure, |mut builder, variant| {
|
||||
let preamble = builder.preamble(variant);
|
||||
let body = builder.body(variant);
|
||||
|
||||
let formatting_init = &builder.formatting_init;
|
||||
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() {
|
||||
let primary_message = match builder.slug.value_ref() {
|
||||
None => {
|
||||
span_err(builder.span, "diagnostic slug not specified")
|
||||
.help(
|
||||
|
@ -146,9 +133,18 @@ impl<'a> LintDiagnosticDerive<'a> {
|
|||
Some(slug) => {
|
||||
slugs.borrow_mut().push(slug.clone());
|
||||
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;
|
||||
}
|
||||
|
||||
fn msg(&self) -> rustc_errors::DiagMessage {
|
||||
#msg
|
||||
}
|
||||
}
|
||||
});
|
||||
for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) {
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::cmp;
|
|||
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
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_macros::HashStable;
|
||||
use rustc_session::lint::{
|
||||
|
@ -269,7 +269,6 @@ pub fn lint_level(
|
|||
level: Level,
|
||||
src: LintLevelSource,
|
||||
span: Option<MultiSpan>,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
|
||||
) {
|
||||
// Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to
|
||||
|
@ -281,7 +280,6 @@ pub fn lint_level(
|
|||
level: Level,
|
||||
src: LintLevelSource,
|
||||
span: Option<MultiSpan>,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: Box<dyn '_ + for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)>,
|
||||
) {
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
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.
|
||||
|
|
|
@ -156,6 +156,13 @@ pub struct Deprecated {
|
|||
|
||||
impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated {
|
||||
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("path", self.path);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -597,7 +594,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
unmarked: impl FnOnce(Span, DefId),
|
||||
) -> bool {
|
||||
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 =
|
||||
self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
|
||||
|
|
|
@ -112,8 +112,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
|
||||
self.local_def_id_to_hir_id(local_def_id),
|
||||
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"); },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,9 +48,7 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, RwLock, Work
|
|||
#[cfg(parallel_compiler)]
|
||||
use rustc_data_structures::sync::{DynSend, DynSync};
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::{
|
||||
Applicability, Diag, DiagCtxt, DiagMessage, ErrorGuaranteed, LintDiagnostic, MultiSpan,
|
||||
};
|
||||
use rustc_errors::{Applicability, Diag, DiagCtxt, ErrorGuaranteed, LintDiagnostic, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||
|
@ -2475,10 +2473,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
span: impl Into<MultiSpan>,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
) {
|
||||
let msg = decorator.msg();
|
||||
let (level, src) = self.lint_level_at_node(lint, hir_id);
|
||||
lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| {
|
||||
decorator.decorate_lint(diag);
|
||||
lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
|
||||
decorator.decorate_lint(lint);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2492,11 +2489,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
lint: &'static Lint,
|
||||
hir_id: HirId,
|
||||
span: impl Into<MultiSpan>,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
|
||||
) {
|
||||
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
|
||||
|
@ -2547,8 +2543,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
id: HirId,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
) {
|
||||
self.node_lint(lint, id, decorator.msg(), |diag| {
|
||||
decorator.decorate_lint(diag);
|
||||
self.node_lint(lint, id, |lint| {
|
||||
decorator.decorate_lint(lint);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2561,11 +2557,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
self,
|
||||
lint: &'static Lint,
|
||||
id: HirId,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
|
||||
) {
|
||||
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]> {
|
||||
|
|
|
@ -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_middle::mir::AssertKind;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
@ -50,18 +50,15 @@ pub(crate) enum AssertLintKind {
|
|||
|
||||
impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint<P> {
|
||||
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| {
|
||||
diag.arg(name, value);
|
||||
});
|
||||
diag.span_label(self.span, message);
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagMessage {
|
||||
match self.lint_kind {
|
||||
AssertLintKind::ArithmeticOverflow => fluent::mir_transform_arithmetic_overflow,
|
||||
AssertLintKind::UnconditionalPanic => fluent::mir_transform_operation_will_panic,
|
||||
}
|
||||
diag.span_label(self.span, label);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,6 +101,7 @@ pub(crate) struct MustNotSupend<'tcx, 'a> {
|
|||
// Needed for def_path_str
|
||||
impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> {
|
||||
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);
|
||||
if let Some(reason) = self.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("post", self.post);
|
||||
}
|
||||
|
||||
fn msg(&self) -> rustc_errors::DiagMessage {
|
||||
fluent::mir_transform_must_not_suspend
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
|
|
|
@ -99,7 +99,6 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>(
|
|||
|
||||
use rustc_errors::LintDiagnostic;
|
||||
let mut err = rcx.tcx.dcx().struct_span_warn(arm.pat.data().span, "");
|
||||
err.primary_message(decorator.msg());
|
||||
decorator.decorate_lint(&mut err);
|
||||
err.emit();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use super::elaborate;
|
|||
use crate::infer::TyCtxtInferExt;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
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::def_id::DefId;
|
||||
use rustc_middle::query::Providers;
|
||||
|
@ -162,41 +162,36 @@ fn lint_object_unsafe_trait(
|
|||
) {
|
||||
// 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.
|
||||
tcx.node_span_lint(
|
||||
WHERE_CLAUSES_OBJECT_SAFETY,
|
||||
hir::CRATE_HIR_ID,
|
||||
span,
|
||||
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 mut spans = MultiSpan::from_span(span);
|
||||
if let Some(hir::Node::Item(item)) = node {
|
||||
spans.push_span_label(
|
||||
item.ident.span,
|
||||
"this trait cannot be made into an object...",
|
||||
);
|
||||
spans.push_span_label(span, format!("...because {}", violation.error_msg()));
|
||||
} else {
|
||||
spans.push_span_label(
|
||||
span,
|
||||
format!(
|
||||
"the trait cannot be made into an object because {}",
|
||||
violation.error_msg()
|
||||
),
|
||||
);
|
||||
};
|
||||
err.span_note(
|
||||
spans,
|
||||
"for a trait to be \"object safe\" it needs to allow building a vtable to allow the \
|
||||
tcx.node_span_lint(WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, span, |err| {
|
||||
err.primary_message(format!(
|
||||
"the trait `{}` cannot be made into an object",
|
||||
tcx.def_path_str(trait_def_id)
|
||||
));
|
||||
let node = tcx.hir().get_if_local(trait_def_id);
|
||||
let mut spans = MultiSpan::from_span(span);
|
||||
if let Some(hir::Node::Item(item)) = node {
|
||||
spans.push_span_label(item.ident.span, "this trait cannot be made into an object...");
|
||||
spans.push_span_label(span, format!("...because {}", violation.error_msg()));
|
||||
} else {
|
||||
spans.push_span_label(
|
||||
span,
|
||||
format!(
|
||||
"the trait cannot be made into an object because {}",
|
||||
violation.error_msg()
|
||||
),
|
||||
);
|
||||
};
|
||||
err.span_note(
|
||||
spans,
|
||||
"for a trait to be \"object safe\" it needs to allow building a vtable to allow the \
|
||||
call to be resolvable dynamically; for more information visit \
|
||||
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
|
||||
);
|
||||
if node.is_some() {
|
||||
// Only provide the help if its a local trait, otherwise it's not
|
||||
violation.solution().add_to(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
);
|
||||
if node.is_some() {
|
||||
// Only provide the help if its a local trait, otherwise it's not
|
||||
violation.solution().add_to(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn sized_trait_bound_spans<'tcx>(
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::traits::{
|
|||
self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt,
|
||||
};
|
||||
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_middle::bug;
|
||||
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
|
||||
|
@ -449,7 +449,7 @@ fn report_conflicting_impls<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
let msg = DelayDm(|| {
|
||||
let msg = || {
|
||||
format!(
|
||||
"conflicting implementations of trait `{}`{}{}",
|
||||
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
|
||||
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()
|
||||
|| 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);
|
||||
decorate(tcx, &overlap, impl_span, &mut err);
|
||||
err.emit()
|
||||
|
@ -485,15 +485,10 @@ fn report_conflicting_impls<'tcx>(
|
|||
FutureCompatOverlapErrorKind::OrderDepTraitObjects => ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||
FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
|
||||
};
|
||||
tcx.node_span_lint(
|
||||
lint,
|
||||
tcx.local_def_id_to_hir_id(impl_def_id),
|
||||
impl_span,
|
||||
msg,
|
||||
|err| {
|
||||
decorate(tcx, &overlap, impl_span, err);
|
||||
},
|
||||
);
|
||||
tcx.node_span_lint(lint, tcx.local_def_id_to_hir_id(impl_def_id), impl_span, |err| {
|
||||
err.primary_message(msg());
|
||||
decorate(tcx, &overlap, impl_span, err);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue