diff options
| author | bors <bors@rust-lang.org> | 2024-05-27 08:44:12 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-05-27 08:44:12 +0000 |
| commit | b582f807fae230b22ac126ff1d8a13262bb099ba (patch) | |
| tree | 861b8cb9ffe0461d39a824e74a44cc36c2ffa5c2 /compiler | |
| parent | fec98b3bbc94b54a0b3085d004708aabcc48081a (diff) | |
| parent | 37bf2d2dabdbdce9473b0fed1708fcbf31ba9c1a (diff) | |
| download | rust-b582f807fae230b22ac126ff1d8a13262bb099ba.tar.gz rust-b582f807fae230b22ac126ff1d8a13262bb099ba.zip | |
Auto merge of #125410 - fmease:adj-lint-diag-api, r=nnethercote
[perf] Delay the construction of early lint diag structs Attacks some of the perf regressions from https://github.com/rust-lang/rust/pull/124417#issuecomment-2123700666. See individual commits for details. The first three commits are not strictly necessary. However, the 2nd one (06bc4fc67145e3a7be9b5a2cf2b5968cef36e587, *Remove `LintDiagnostic::msg`*) makes the main change way nicer to implement. It's also pretty sweet on its own if I may say so myself.
Diffstat (limited to 'compiler')
34 files changed, 458 insertions, 657 deletions
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index e3e513084ea..5d7257b15c4 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -576,8 +576,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"); }, ) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 08388c5a58e..4eb4e77d69c 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -364,17 +364,6 @@ impl From<Cow<'static, str>> for DiagMessage { } } -/// A workaround for must_produce_diag ICEs when formatting types in disabled lints. -/// -/// Delays formatting until `.into(): DiagMessage` is used. -pub struct DelayDm<F>(pub F); - -impl<F: FnOnce() -> String> From<DelayDm<F>> for DiagMessage { - fn from(DelayDm(f): DelayDm<F>) -> Self { - DiagMessage::from(f()) - } -} - /// Translating *into* a subdiagnostic message from a diagnostic message is a little strange - but /// the subdiagnostic functions (e.g. `span_label`) take a `SubdiagMessage` and the /// subdiagnostic derive refers to typed identifiers that are `DiagMessage`s, so need to be diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 18bb71bd99f..34b569c4206 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -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)] diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 3b884ff864a..4dc5d84b318 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -39,7 +39,7 @@ pub use diagnostic_impls::{ }; pub use emitter::ColorConfig; pub use rustc_error_messages::{ - fallback_fluent_bundle, fluent_bundle, DelayDm, DiagMessage, FluentBundle, LanguageIdentifier, + fallback_fluent_bundle, fluent_bundle, DiagMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagMessage, }; pub use rustc_lint_defs::{pluralize, Applicability}; @@ -572,8 +572,8 @@ impl Drop for DiagCtxtInner { if let Some(backtrace) = &self.must_produce_diag { panic!( "must_produce_diag: `trimmed_def_paths` called but no diagnostics emitted; \ - use `DelayDm` for lints or `with_no_trimmed_paths` for debugging. \ - called at: {backtrace}" + `with_no_trimmed_paths` for debugging. \ + called at: {backtrace}" ); } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8f21d826925..3904f14b0f6 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -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"); }, @@ -1310,9 +1306,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 { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index b09de1a4a09..2672614a895 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -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)", diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index aa5db4f6aa7..ed23dc2a827 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -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"); + } + }); } } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 6b41f79cf1e..abdf85ad707 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -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 => { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 749f78e7920..7b67030836d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -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); + }, ); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index d9d36f5299b..997db338a43 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -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`", diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 83a23de1654..3f66f971b17 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1165,33 +1165,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); - }; + 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"); + 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, - ); - }, - ); + 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)) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 074aca78933..b40bb74d7be 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -64,19 +64,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"), + ); + }) } } } diff --git a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs index e9eab6969b3..3ee10f74d98 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs @@ -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( diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 820fe97afb5..97a74b55c53 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -415,8 +415,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, @@ -1286,53 +1287,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) + }), + ); + }); } } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index b9b220d5af8..b37aba38619 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -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. diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index e29a410e2e5..466397817da 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -955,8 +955,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 diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index c23a67f6131..56f07a2b5e9 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -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; @@ -539,7 +539,9 @@ impl EarlyContext<'_> { span: MultiSpan, diagnostic: BuiltinLintDiag, ) { - diagnostics::emit_buffered_lint(self, lint, span, diagnostic) + self.opt_span_lint(lint, Some(span), |diag| { + diagnostics::decorate_lint(self.sess(), diagnostic, diag); + }); } } @@ -556,7 +558,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 +569,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 +582,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 +599,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 +663,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 +689,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 { diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 23c5e0a9f5f..26f34486a3d 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -4,24 +4,19 @@ use std::borrow::Cow; use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; -use rustc_errors::Applicability; -use rustc_errors::{elided_lifetime_in_path_suggestion, DiagArgValue, MultiSpan}; +use rustc_errors::elided_lifetime_in_path_suggestion; +use rustc_errors::{Applicability, Diag, DiagArgValue, LintDiagnostic}; use rustc_middle::middle::stability; -use rustc_session::lint::{BuiltinLintDiag, Lint}; +use rustc_session::lint::BuiltinLintDiag; +use rustc_session::Session; use rustc_span::BytePos; use tracing::debug; -use crate::{lints, EarlyContext, LintContext as _}; +use crate::lints; mod check_cfg; -pub(super) fn emit_buffered_lint( - ctx: &EarlyContext<'_>, - lint: &'static Lint, - span: MultiSpan, - diagnostic: BuiltinLintDiag, -) { - let sess = ctx.sess(); +pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) { match diagnostic { BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => { let spans: Vec<_> = content @@ -40,16 +35,14 @@ pub(super) fn emit_buffered_lint( let suggestions = (!spans.is_empty()).then_some(lints::UnicodeTextFlowSuggestion { spans: spans.iter().map(|(_c, span)| *span).collect(), }); - ctx.emit_span_lint( - lint, - span, - lints::UnicodeTextFlow { - comment_span, - characters, - suggestions, - num_codepoints: spans.len(), - }, - ) + + lints::UnicodeTextFlow { + comment_span, + characters, + suggestions, + num_codepoints: spans.len(), + } + .decorate_lint(diag); } BuiltinLintDiag::AbsPathWithModule(mod_span) => { let (replacement, applicability) = match sess.source_map().span_to_snippet(mod_span) { @@ -62,48 +55,35 @@ pub(super) fn emit_buffered_lint( } Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders), }; - ctx.emit_span_lint( - lint, - span, - lints::AbsPathWithModule { - sugg: lints::AbsPathWithModuleSugg { - span: mod_span, - applicability, - replacement, - }, - }, - ); - } - BuiltinLintDiag::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident } => ctx - .emit_span_lint( - lint, - span, - lints::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident }, - ), - BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => ctx - .emit_span_lint( - lint, - span, - lints::MacroExpandedMacroExportsAccessedByAbsolutePaths { definition: span_def }, - ), + lints::AbsPathWithModule { + sugg: lints::AbsPathWithModuleSugg { span: mod_span, applicability, replacement }, + } + .decorate_lint(diag); + } + BuiltinLintDiag::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident } => { + lints::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident } + .decorate_lint(diag) + } + BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => { + lints::MacroExpandedMacroExportsAccessedByAbsolutePaths { definition: span_def } + .decorate_lint(diag) + } + BuiltinLintDiag::ElidedLifetimesInPaths(n, path_span, incl_angl_brckt, insertion_span) => { - ctx.emit_span_lint( - lint, - span, - lints::ElidedLifetimesInPaths { - subdiag: elided_lifetime_in_path_suggestion( - sess.source_map(), - n, - path_span, - incl_angl_brckt, - insertion_span, - ), - }, - ); + lints::ElidedLifetimesInPaths { + subdiag: elided_lifetime_in_path_suggestion( + sess.source_map(), + n, + path_span, + incl_angl_brckt, + insertion_span, + ), + } + .decorate_lint(diag); } BuiltinLintDiag::UnknownCrateTypes { span, candidate } => { let sugg = candidate.map(|candidate| lints::UnknownCrateTypesSub { span, candidate }); - ctx.emit_span_lint(lint, span, lints::UnknownCrateTypes { sugg }); + lints::UnknownCrateTypes { sugg }.decorate_lint(diag); } BuiltinLintDiag::UnusedImports { remove_whole_use, @@ -120,18 +100,15 @@ pub(super) fn emit_buffered_lint( let test_module_span = test_module_span.map(|span| sess.source_map().guess_head_span(span)); - ctx.emit_span_lint( - lint, - span, - lints::UnusedImports { - sugg, - test_module_span, - num_snippets: span_snippets.len(), - span_snippets: DiagArgValue::StrListSepByAnd( - span_snippets.into_iter().map(Cow::Owned).collect(), - ), - }, - ); + lints::UnusedImports { + sugg, + test_module_span, + num_snippets: span_snippets.len(), + span_snippets: DiagArgValue::StrListSepByAnd( + span_snippets.into_iter().map(Cow::Owned).collect(), + ), + } + .decorate_lint(diag); } BuiltinLintDiag::RedundantImport(spans, ident) => { let subs = spans @@ -145,7 +122,7 @@ pub(super) fn emit_buffered_lint( })(span) }) .collect(); - ctx.emit_span_lint(lint, span, lints::RedundantImport { subs, ident }); + lints::RedundantImport { subs, ident }.decorate_lint(diag); } BuiltinLintDiag::DeprecatedMacro { suggestion, @@ -159,90 +136,63 @@ pub(super) fn emit_buffered_lint( kind: "macro".to_owned(), suggestion, }); - ctx.emit_span_lint( - lint, - span, - stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind }, - ); + + stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind } + .decorate_lint(diag); } BuiltinLintDiag::UnusedDocComment(attr_span) => { - ctx.emit_span_lint(lint, span, lints::UnusedDocComment { span: attr_span }); + lints::UnusedDocComment { span: attr_span }.decorate_lint(diag); } BuiltinLintDiag::PatternsInFnsWithoutBody { span: remove_span, ident, is_foreign } => { let sub = lints::PatternsInFnsWithoutBodySub { ident, span: remove_span }; - - ctx.emit_span_lint( - lint, - span, - if is_foreign { - lints::PatternsInFnsWithoutBody::Foreign { sub } - } else { - lints::PatternsInFnsWithoutBody::Bodiless { sub } - }, - ); + if is_foreign { + lints::PatternsInFnsWithoutBody::Foreign { sub } + } else { + lints::PatternsInFnsWithoutBody::Bodiless { sub } + } + .decorate_lint(diag); } BuiltinLintDiag::MissingAbi(label_span, default_abi) => { - ctx.emit_span_lint( - lint, - span, - lints::MissingAbi { span: label_span, default_abi: default_abi.name() }, - ); + lints::MissingAbi { span: label_span, default_abi: default_abi.name() } + .decorate_lint(diag); } BuiltinLintDiag::LegacyDeriveHelpers(label_span) => { - ctx.emit_span_lint(lint, span, lints::LegacyDeriveHelpers { span: label_span }); + lints::LegacyDeriveHelpers { span: label_span }.decorate_lint(diag); } BuiltinLintDiag::ProcMacroBackCompat { crate_name, fixed_version } => { - ctx.emit_span_lint( - lint, - span, - lints::ProcMacroBackCompat { crate_name, fixed_version }, - ); + lints::ProcMacroBackCompat { crate_name, fixed_version }.decorate_lint(diag); } BuiltinLintDiag::OrPatternsBackCompat(suggestion_span, suggestion) => { - ctx.emit_span_lint( - lint, - span, - lints::OrPatternsBackCompat { span: suggestion_span, suggestion }, - ); + lints::OrPatternsBackCompat { span: suggestion_span, suggestion }.decorate_lint(diag); } BuiltinLintDiag::ReservedPrefix(label_span, prefix) => { - ctx.emit_span_lint( - lint, - span, - lints::ReservedPrefix { - label: label_span, - suggestion: label_span.shrink_to_hi(), - prefix, - }, - ); + lints::ReservedPrefix { + label: label_span, + suggestion: label_span.shrink_to_hi(), + prefix, + } + .decorate_lint(diag); } BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name, invoc_span } => { - ctx.emit_span_lint( - lint, - span, - lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }, - ); + lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }.decorate_lint(diag); } BuiltinLintDiag::TrailingMacro(is_trailing, name) => { - ctx.emit_span_lint(lint, span, lints::TrailingMacro { is_trailing, name }); + lints::TrailingMacro { is_trailing, name }.decorate_lint(diag); } BuiltinLintDiag::BreakWithLabelAndLoop(sugg_span) => { - ctx.emit_span_lint( - lint, - span, - lints::BreakWithLabelAndLoop { - sub: lints::BreakWithLabelAndLoopSub { - left: sugg_span.shrink_to_lo(), - right: sugg_span.shrink_to_hi(), - }, + lints::BreakWithLabelAndLoop { + sub: lints::BreakWithLabelAndLoopSub { + left: sugg_span.shrink_to_lo(), + right: sugg_span.shrink_to_hi(), }, - ); + } + .decorate_lint(diag); } BuiltinLintDiag::UnexpectedCfgName(name, value) => { - ctx.emit_span_lint(lint, span, check_cfg::unexpected_cfg_name(sess, name, value)); + check_cfg::unexpected_cfg_name(sess, name, value).decorate_lint(diag); } BuiltinLintDiag::UnexpectedCfgValue(name, value) => { - ctx.emit_span_lint(lint, span, check_cfg::unexpected_cfg_value(sess, name, value)); + check_cfg::unexpected_cfg_value(sess, name, value).decorate_lint(diag); } BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { let suggestion = match sugg { @@ -253,7 +203,7 @@ pub(super) fn emit_buffered_lint( }, None => lints::DeprecatedWhereClauseLocationSugg::RemoveWhere { span: left_sp }, }; - ctx.emit_span_lint(lint, span, lints::DeprecatedWhereClauseLocation { suggestion }); + lints::DeprecatedWhereClauseLocation { suggestion }.decorate_lint(diag); } BuiltinLintDiag::SingleUseLifetime { param_span, @@ -280,15 +230,12 @@ pub(super) fn emit_buffered_lint( None }; - ctx.emit_span_lint( - lint, - span, - lints::SingleUseLifetime { suggestion, param_span, use_span, ident }, - ); + lints::SingleUseLifetime { suggestion, param_span, use_span, ident } + .decorate_lint(diag); } BuiltinLintDiag::SingleUseLifetime { use_span: None, deletion_span, ident, .. } => { debug!(?deletion_span); - ctx.emit_span_lint(lint, span, lints::UnusedLifetime { deletion_span, ident }); + lints::UnusedLifetime { deletion_span, ident }.decorate_lint(diag); } BuiltinLintDiag::NamedArgumentUsedPositionally { position_sp_to_replace, @@ -316,35 +263,29 @@ pub(super) fn emit_buffered_lint( (None, String::new()) }; - ctx.emit_span_lint( - lint, - span, - lints::NamedArgumentUsedPositionally { - named_arg_sp, - position_label_sp: position_sp_for_msg, - suggestion, - name, - named_arg_name, - }, - ) + lints::NamedArgumentUsedPositionally { + named_arg_sp, + position_label_sp: position_sp_for_msg, + suggestion, + name, + named_arg_name, + } + .decorate_lint(diag); } BuiltinLintDiag::ByteSliceInPackedStructWithDerive { ty } => { - ctx.emit_span_lint(lint, span, lints::ByteSliceInPackedStructWithDerive { ty }) + lints::ByteSliceInPackedStructWithDerive { ty }.decorate_lint(diag); } BuiltinLintDiag::UnusedExternCrate { removal_span } => { - ctx.emit_span_lint(lint, span, lints::UnusedExternCrate { removal_span }) + lints::UnusedExternCrate { removal_span }.decorate_lint(diag); } BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span } => { let suggestion_span = vis_span.between(ident_span); let code = if vis_span.is_empty() { "use " } else { " use " }; - ctx.emit_span_lint( - lint, - span, - lints::ExternCrateNotIdiomatic { span: suggestion_span, code }, - ); + + lints::ExternCrateNotIdiomatic { span: suggestion_span, code }.decorate_lint(diag); } BuiltinLintDiag::AmbiguousGlobImports { diag: ambiguity } => { - ctx.emit_span_lint(lint, span, lints::AmbiguousGlobImports { ambiguity }); + lints::AmbiguousGlobImports { ambiguity }.decorate_lint(diag); } BuiltinLintDiag::AmbiguousGlobReexports { name, @@ -352,16 +293,13 @@ pub(super) fn emit_buffered_lint( first_reexport_span, duplicate_reexport_span, } => { - ctx.emit_span_lint( - lint, - span, - lints::AmbiguousGlobReexports { - first_reexport: first_reexport_span, - duplicate_reexport: duplicate_reexport_span, - name, - namespace, - }, - ); + lints::AmbiguousGlobReexports { + first_reexport: first_reexport_span, + duplicate_reexport: duplicate_reexport_span, + name, + namespace, + } + .decorate_lint(diag); } BuiltinLintDiag::HiddenGlobReexports { name, @@ -369,127 +307,112 @@ pub(super) fn emit_buffered_lint( glob_reexport_span, private_item_span, } => { - ctx.emit_span_lint( - lint, - span, - lints::HiddenGlobReexports { - glob_reexport: glob_reexport_span, - private_item: private_item_span, + lints::HiddenGlobReexports { + glob_reexport: glob_reexport_span, + private_item: private_item_span, - name, - namespace, - }, - ); + name, + namespace, + } + .decorate_lint(diag); } BuiltinLintDiag::UnusedQualifications { removal_span } => { - ctx.emit_span_lint(lint, span, lints::UnusedQualifications { removal_span }); + lints::UnusedQualifications { removal_span }.decorate_lint(diag); } BuiltinLintDiag::AssociatedConstElidedLifetime { elided, span: lt_span } => { let lt_span = if elided { lt_span.shrink_to_hi() } else { lt_span }; let code = if elided { "'static " } else { "'static" }; - ctx.emit_span_lint( - lint, - span, - lints::AssociatedConstElidedLifetime { span: lt_span, code, elided }, - ); + lints::AssociatedConstElidedLifetime { span: lt_span, code, elided } + .decorate_lint(diag); } BuiltinLintDiag::RedundantImportVisibility { max_vis, span: vis_span, import_vis } => { - ctx.emit_span_lint( - lint, - span, - lints::RedundantImportVisibility { span: vis_span, help: (), max_vis, import_vis }, - ); + lints::RedundantImportVisibility { span: vis_span, help: (), max_vis, import_vis } + .decorate_lint(diag); } BuiltinLintDiag::UnknownDiagnosticAttribute { span: typo_span, typo_name } => { let typo = typo_name.map(|typo_name| lints::UnknownDiagnosticAttributeTypoSugg { span: typo_span, typo_name, }); - ctx.emit_span_lint(lint, span, lints::UnknownDiagnosticAttribute { typo }); + lints::UnknownDiagnosticAttribute { typo }.decorate_lint(diag); } BuiltinLintDiag::MacroUseDeprecated => { - ctx.emit_span_lint(lint, span, lints::MacroUseDeprecated) + lints::MacroUseDeprecated.decorate_lint(diag); } - BuiltinLintDiag::UnusedMacroUse => ctx.emit_span_lint(lint, span, lints::UnusedMacroUse), + BuiltinLintDiag::UnusedMacroUse => lints::UnusedMacroUse.decorate_lint(diag), BuiltinLintDiag::PrivateExternCrateReexport(ident) => { - ctx.emit_span_lint(lint, span, lints::PrivateExternCrateReexport { ident }) + lints::PrivateExternCrateReexport { ident }.decorate_lint(diag); } - BuiltinLintDiag::UnusedLabel => ctx.emit_span_lint(lint, span, lints::UnusedLabel), + BuiltinLintDiag::UnusedLabel => lints::UnusedLabel.decorate_lint(diag), BuiltinLintDiag::MacroIsPrivate(ident) => { - ctx.emit_span_lint(lint, span, lints::MacroIsPrivate { ident }) + lints::MacroIsPrivate { ident }.decorate_lint(diag); } BuiltinLintDiag::UnusedMacroDefinition(name) => { - ctx.emit_span_lint(lint, span, lints::UnusedMacroDefinition { name }) + lints::UnusedMacroDefinition { name }.decorate_lint(diag); } BuiltinLintDiag::MacroRuleNeverUsed(n, name) => { - ctx.emit_span_lint(lint, span, lints::MacroRuleNeverUsed { n: n + 1, name }) + lints::MacroRuleNeverUsed { n: n + 1, name }.decorate_lint(diag); } BuiltinLintDiag::UnstableFeature(msg) => { - ctx.emit_span_lint(lint, span, lints::UnstableFeature { msg }) + lints::UnstableFeature { msg }.decorate_lint(diag); } BuiltinLintDiag::AvoidUsingIntelSyntax => { - ctx.emit_span_lint(lint, span, lints::AvoidIntelSyntax) + lints::AvoidIntelSyntax.decorate_lint(diag); } BuiltinLintDiag::AvoidUsingAttSyntax => { - ctx.emit_span_lint(lint, span, lints::AvoidAttSyntax) + lints::AvoidAttSyntax.decorate_lint(diag); } BuiltinLintDiag::IncompleteInclude => { - ctx.emit_span_lint(lint, span, lints::IncompleteInclude) + lints::IncompleteInclude.decorate_lint(diag); } BuiltinLintDiag::UnnameableTestItems => { - ctx.emit_span_lint(lint, span, lints::UnnameableTestItems) + lints::UnnameableTestItems.decorate_lint(diag); } BuiltinLintDiag::DuplicateMacroAttribute => { - ctx.emit_span_lint(lint, span, lints::DuplicateMacroAttribute) + lints::DuplicateMacroAttribute.decorate_lint(diag); } BuiltinLintDiag::CfgAttrNoAttributes => { - ctx.emit_span_lint(lint, span, lints::CfgAttrNoAttributes) + lints::CfgAttrNoAttributes.decorate_lint(diag); } BuiltinLintDiag::CrateTypeInCfgAttr => { - ctx.emit_span_lint(lint, span, lints::CrateTypeInCfgAttr) + lints::CrateTypeInCfgAttr.decorate_lint(diag); } BuiltinLintDiag::CrateNameInCfgAttr => { - ctx.emit_span_lint(lint, span, lints::CrateNameInCfgAttr) + lints::CrateNameInCfgAttr.decorate_lint(diag); } BuiltinLintDiag::MissingFragmentSpecifier => { - ctx.emit_span_lint(lint, span, lints::MissingFragmentSpecifier) + lints::MissingFragmentSpecifier.decorate_lint(diag); } BuiltinLintDiag::MetaVariableStillRepeating(name) => { - ctx.emit_span_lint(lint, span, lints::MetaVariableStillRepeating { name }) + lints::MetaVariableStillRepeating { name }.decorate_lint(diag); } BuiltinLintDiag::MetaVariableWrongOperator => { - ctx.emit_span_lint(lint, span, lints::MetaVariableWrongOperator) + lints::MetaVariableWrongOperator.decorate_lint(diag); } BuiltinLintDiag::DuplicateMatcherBinding => { - ctx.emit_span_lint(lint, span, lints::DuplicateMatcherBinding) + lints::DuplicateMatcherBinding.decorate_lint(diag); } BuiltinLintDiag::UnknownMacroVariable(name) => { - ctx.emit_span_lint(lint, span, lints::UnknownMacroVariable { name }) - } - BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => ctx.emit_span_lint( - lint, - span, - lints::UnusedCrateDependency { extern_crate, local_crate }, - ), - BuiltinLintDiag::WasmCAbi => ctx.emit_span_lint(lint, span, lints::WasmCAbi), - BuiltinLintDiag::IllFormedAttributeInput { suggestions } => ctx.emit_span_lint( - lint, - span, + lints::UnknownMacroVariable { name }.decorate_lint(diag); + } + BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { + lints::UnusedCrateDependency { extern_crate, local_crate }.decorate_lint(diag) + } + BuiltinLintDiag::WasmCAbi => lints::WasmCAbi.decorate_lint(diag), + BuiltinLintDiag::IllFormedAttributeInput { suggestions } => { lints::IllFormedAttributeInput { num_suggestions: suggestions.len(), suggestions: DiagArgValue::StrListSepByAnd( suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), ), - }, - ), - BuiltinLintDiag::InnerAttributeUnstable { is_macro } => ctx.emit_span_lint( - lint, - span, - if is_macro { - lints::InnerAttributeUnstable::InnerMacroAttribute - } else { - lints::InnerAttributeUnstable::CustomInnerAttribute - }, - ), + } + .decorate_lint(diag) + } + BuiltinLintDiag::InnerAttributeUnstable { is_macro } => if is_macro { + lints::InnerAttributeUnstable::InnerMacroAttribute + } else { + lints::InnerAttributeUnstable::CustomInnerAttribute + } + .decorate_lint(diag), } } diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index c473b74b410..a311c274a6b 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -361,6 +361,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) @@ -374,10 +375,6 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { ); } } - - fn msg(&self) -> rustc_errors::DiagMessage { - fluent::lint_impl_trait_overcaptures - } } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 98e321076c5..84645e0ce7f 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -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}; @@ -1064,26 +1064,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 @@ -1104,11 +1097,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] @@ -1119,7 +1111,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); }); } @@ -1127,7 +1119,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); }); } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 2f44bc4764e..42963a11f71 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -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 @@ -1169,6 +1160,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 { @@ -1186,10 +1178,6 @@ impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused { ); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_non_fmt_panic_unused - } } #[derive(LintDiagnostic)] @@ -1411,13 +1399,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> { @@ -1428,12 +1413,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 @@ -1711,6 +1693,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); @@ -1722,10 +1705,6 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { diag.span_note(note, fluent::lint_note); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_improper_ctypes - } } #[derive(LintDiagnostic)] @@ -1854,6 +1833,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)); @@ -1865,10 +1845,6 @@ impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> { diag.subdiagnostic(diag.dcx, sugg); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_unused_def - } } #[derive(LintDiagnostic)] @@ -1937,15 +1913,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)] @@ -2273,10 +2246,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); } } @@ -2738,12 +2709,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)] diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index a6057afcbd6..c9d67854112 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -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); diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 1941b0b1264..c8a9fb02bf2 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -764,19 +764,7 @@ pub struct LintBuffer { impl LintBuffer { pub fn add_early_lint(&mut self, early_lint: BufferedEarlyLint) { - let arr = self.map.entry(early_lint.node_id).or_default(); - arr.push(early_lint); - } - - pub fn add_lint( - &mut self, - lint: &'static Lint, - node_id: NodeId, - span: MultiSpan, - diagnostic: BuiltinLintDiag, - ) { - let lint_id = LintId::of(lint); - self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, diagnostic }); + self.map.entry(early_lint.node_id).or_default().push(early_lint); } pub fn take(&mut self, id: NodeId) -> Vec<BufferedEarlyLint> { @@ -787,11 +775,16 @@ impl LintBuffer { pub fn buffer_lint( &mut self, lint: &'static Lint, - id: NodeId, - sp: impl Into<MultiSpan>, + node_id: NodeId, + span: impl Into<MultiSpan>, diagnostic: BuiltinLintDiag, ) { - self.add_lint(lint, id, sp.into(), diagnostic) + self.add_early_lint(BufferedEarlyLint { + lint_id: LintId::of(lint), + node_id, + span: span.into(), + diagnostic, + }); } } diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 9d21d88165e..ef6005283d6 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -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)) { diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 389d88bebc7..134045d0644 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -91,7 +91,7 @@ pub fn diagnostic_derive(mut s: Structure<'_>) -> TokenStream { /// Then, later, to emit the error: /// /// ```ignore (rust) -/// cx.span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint { +/// cx.emit_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint { /// method, /// success_ordering, /// fail_ordering, diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index d82d23d62af..4e655ca2027 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -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::{ @@ -270,7 +270,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 @@ -282,7 +281,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. @@ -351,10 +349,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 @@ -419,7 +413,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. diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index a377e35b2e9..8cf1bedf0da 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -157,6 +157,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 { @@ -172,16 +179,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 { @@ -598,7 +595,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); diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index a8518195469..fe743fa4aac 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -113,8 +113,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"); }, ) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 33ce08991bb..e618323c810 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -47,9 +47,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}; @@ -2471,10 +2469,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); }) } @@ -2488,11 +2485,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 @@ -2543,8 +2539,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); }) } @@ -2557,11 +2553,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]> { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 0bcd02aaa3a..3c0f2578284 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3314,7 +3314,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N /// /// The implementation uses similar import discovery logic to that of 'use' suggestions. /// -/// See also [`DelayDm`](rustc_error_messages::DelayDm) and [`with_no_trimmed_paths!`]. +/// See also [`with_no_trimmed_paths!`]. // this is pub to be able to intra-doc-link it pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap<Symbol> { // Trimming paths is expensive and not optimized, since we expect it to only be used for error diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 0634e321ea3..b28dcb38cb6 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -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)] diff --git a/compiler/rustc_pattern_analysis/src/lints.rs b/compiler/rustc_pattern_analysis/src/lints.rs index 1d10c9df4ab..892aacd7ac5 100644 --- a/compiler/rustc_pattern_analysis/src/lints.rs +++ b/compiler/rustc_pattern_analysis/src/lints.rs @@ -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(); } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 8ce1271fc17..f4051561dae 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -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>( diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 826bb706f48..c2727ae6bfd 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -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(()) } } |
