From e7724a2e319f112ee6a97999976d8225b009456e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 18 Dec 2023 14:12:39 +1100 Subject: [PATCH] Add `level` arg to `into_diagnostic`. And make all hand-written `IntoDiagnostic` impls generic, by using `DiagnosticBuilder::new(dcx, level, ...)` instead of e.g. `dcx.struct_err(...)`. This means the `create_*` functions are the source of the error level. This change will let us remove `struct_diagnostic`. Note: `#[rustc_lint_diagnostics]` is added to `DiagnosticBuilder::new`, it's necessary to pass diagnostics tests now that it's used in `into_diagnostic` functions. --- .../rustc_attr/src/session_diagnostics.rs | 27 +++--- compiler/rustc_builtin_macros/src/errors.rs | 20 ++-- compiler/rustc_codegen_gcc/src/errors.rs | 14 ++- compiler/rustc_codegen_llvm/src/errors.rs | 27 +++--- compiler/rustc_codegen_ssa/src/errors.rs | 95 ++++++++++--------- compiler/rustc_const_eval/src/errors.rs | 7 +- .../rustc_errors/src/diagnostic_builder.rs | 28 +++--- compiler/rustc_errors/src/diagnostic_impls.rs | 39 +++++--- compiler/rustc_errors/src/lib.rs | 12 +-- compiler/rustc_hir_analysis/src/errors.rs | 16 ++-- .../src/diagnostics/diagnostic.rs | 9 +- compiler/rustc_metadata/src/errors.rs | 31 +++--- compiler/rustc_middle/src/ty/layout.rs | 11 ++- compiler/rustc_mir_build/src/errors.rs | 17 ++-- compiler/rustc_mir_transform/src/errors.rs | 8 +- compiler/rustc_monomorphize/src/errors.rs | 13 +-- compiler/rustc_parse/src/errors.rs | 80 +++++++++------- compiler/rustc_passes/src/errors.rs | 74 ++++++--------- compiler/rustc_session/src/errors.rs | 12 ++- compiler/rustc_session/src/parse.rs | 10 +- compiler/rustc_symbol_mangling/src/errors.rs | 11 +-- compiler/rustc_trait_selection/src/errors.rs | 12 ++- .../ui-fulldeps/internal-lints/diagnostics.rs | 16 ++-- .../internal-lints/diagnostics.stderr | 6 +- 24 files changed, 307 insertions(+), 288 deletions(-) diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index ce8e04defb2..fd2b0866867 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -2,7 +2,8 @@ use rustc_ast as ast; use rustc_errors::{ - error_code, Applicability, DiagCtxt, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, + error_code, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, + Level, }; use rustc_macros::Diagnostic; use rustc_span::{Span, Symbol}; @@ -50,14 +51,12 @@ pub(crate) struct UnknownMetaItem<'a> { } // Manual implementation to be able to format `expected` items correctly. -impl<'a> IntoDiagnostic<'a> for UnknownMetaItem<'_> { - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnknownMetaItem<'_> { + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::>(); - let mut diag = dcx.struct_span_err_with_code( - self.span, - fluent::attr_unknown_meta_item, - error_code!(E0541), - ); + let mut diag = DiagnosticBuilder::new(dcx, level, fluent::attr_unknown_meta_item); + diag.set_span(self.span); + diag.code(error_code!(E0541)); diag.set_arg("item", self.item); diag.set_arg("expected", expected.join(", ")); diag.span_label(self.span, fluent::attr_label); @@ -200,10 +199,11 @@ pub(crate) struct UnsupportedLiteral { pub start_point_span: Span, } -impl<'a> IntoDiagnostic<'a> for UnsupportedLiteral { - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - let mut diag = dcx.struct_span_err_with_code( - self.span, +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnsupportedLiteral { + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { + let mut diag = DiagnosticBuilder::new( + dcx, + level, match self.reason { UnsupportedLiteralReason::Generic => fluent::attr_unsupported_literal_generic, UnsupportedLiteralReason::CfgString => fluent::attr_unsupported_literal_cfg_string, @@ -214,8 +214,9 @@ fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaran fluent::attr_unsupported_literal_deprecated_kv_pair } }, - error_code!(E0565), ); + diag.set_span(self.span); + diag.code(error_code!(E0565)); if self.is_bytestr { diag.span_suggestion( self.start_point_span, diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 6ffeb401453..e07eb2e490b 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -1,6 +1,6 @@ use rustc_errors::{ - AddToDiagnostic, DiagCtxt, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, MultiSpan, - SingleLabelManySpans, + AddToDiagnostic, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level, + MultiSpan, SingleLabelManySpans, }; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{symbol::Ident, Span, Symbol}; @@ -446,14 +446,14 @@ pub(crate) struct EnvNotDefinedWithUserMessage { } // Hand-written implementation to support custom user messages. -impl<'a> IntoDiagnostic<'a> for EnvNotDefinedWithUserMessage { +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for EnvNotDefinedWithUserMessage { #[track_caller] - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { #[expect( rustc::untranslatable_diagnostic, reason = "cannot translate user-provided messages" )] - let mut diag = dcx.struct_err(self.msg_from_user.to_string()); + let mut diag = DiagnosticBuilder::new(dcx, level, self.msg_from_user.to_string()); diag.set_span(self.span); diag } @@ -801,9 +801,13 @@ pub(crate) struct AsmClobberNoReg { pub(crate) clobbers: Vec, } -impl<'a> IntoDiagnostic<'a> for AsmClobberNoReg { - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - let mut diag = dcx.struct_err(crate::fluent_generated::builtin_macros_asm_clobber_no_reg); +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for AsmClobberNoReg { + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { + let mut diag = DiagnosticBuilder::new( + dcx, + level, + crate::fluent_generated::builtin_macros_asm_clobber_no_reg, + ); diag.set_span(self.spans.clone()); // eager translation as `span_labels` takes `AsRef` let lbl1 = dcx.eagerly_translate_to_string( diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs index 766d90cf724..1b1ed0b411c 100644 --- a/compiler/rustc_codegen_gcc/src/errors.rs +++ b/compiler/rustc_codegen_gcc/src/errors.rs @@ -1,6 +1,6 @@ use rustc_errors::{ - DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, - IntoDiagnosticArg, + DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, + IntoDiagnosticArg, Level, }; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; @@ -111,9 +111,13 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> { #[help(codegen_gcc_missing_features)] pub(crate) struct MissingFeatures; -impl IntoDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> { - fn into_diagnostic(self, dcx: &'_ DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_err(fluent::codegen_gcc_target_feature_disable_or_enable); +impl IntoDiagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> { + fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = DiagnosticBuilder::new( + dcx, + level, + fluent::codegen_gcc_target_feature_disable_or_enable + ); if let Some(span) = self.span { diag.set_span(span); }; diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 671a225259a..6b7e38a6cb1 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -4,9 +4,7 @@ use crate::fluent_generated as fluent; use rustc_data_structures::small_c_str::SmallCStr; -use rustc_errors::{ - DiagCtxt, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, FatalError, IntoDiagnostic, -}; +use rustc_errors::{DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; @@ -101,13 +99,14 @@ pub(crate) struct DlltoolFailImportLibrary<'a> { pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'a>); -impl IntoDiagnostic<'_, FatalError> for ParseTargetMachineConfig<'_> { - fn into_diagnostic(self, dcx: &'_ DiagCtxt) -> DiagnosticBuilder<'_, FatalError> { - let diag: DiagnosticBuilder<'_, FatalError> = self.0.into_diagnostic(dcx); +impl IntoDiagnostic<'_, G> for ParseTargetMachineConfig<'_> { + fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let diag: DiagnosticBuilder<'_, G> = self.0.into_diagnostic(dcx, level); let (message, _) = diag.styled_message().first().expect("`LlvmError` with no message"); let message = dcx.eagerly_translate_to_string(message.clone(), diag.args()); - let mut diag = dcx.struct_almost_fatal(fluent::codegen_llvm_parse_target_machine_config); + let mut diag = + DiagnosticBuilder::new(dcx, level, fluent::codegen_llvm_parse_target_machine_config); diag.set_arg("error", message); diag } @@ -123,9 +122,13 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> { #[help(codegen_llvm_missing_features)] pub(crate) struct MissingFeatures; -impl IntoDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> { - fn into_diagnostic(self, dcx: &'_ DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable); +impl IntoDiagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> { + fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = DiagnosticBuilder::new( + dcx, + level, + fluent::codegen_llvm_target_feature_disable_or_enable, + ); if let Some(span) = self.span { diag.set_span(span); }; @@ -184,7 +187,7 @@ pub enum LlvmError<'a> { pub(crate) struct WithLlvmError<'a>(pub LlvmError<'a>, pub String); impl IntoDiagnostic<'_, G> for WithLlvmError<'_> { - fn into_diagnostic(self, dcx: &'_ DiagCtxt) -> DiagnosticBuilder<'_, G> { + fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { use LlvmError::*; let msg_with_llvm_err = match &self.0 { WriteOutput { .. } => fluent::codegen_llvm_write_output_with_llvm_err, @@ -201,7 +204,7 @@ fn into_diagnostic(self, dcx: &'_ DiagCtxt) -> DiagnosticBuilder<'_, G> { PrepareThinLtoModule => fluent::codegen_llvm_prepare_thin_lto_module_with_llvm_err, ParseBitcode => fluent::codegen_llvm_parse_bitcode_with_llvm_err, }; - let mut diag = self.0.into_diagnostic(dcx); + let mut diag = self.0.into_diagnostic(dcx, level); diag.set_primary_message(msg_with_llvm_err); diag.set_arg("llvm_err", self.1); diag diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 668d39afbda..2b628d2aa69 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -4,8 +4,8 @@ use crate::back::command::Command; use crate::fluent_generated as fluent; use rustc_errors::{ - DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, - IntoDiagnosticArg, + DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, + IntoDiagnosticArg, Level, }; use rustc_macros::Diagnostic; use rustc_middle::ty::layout::LayoutError; @@ -209,192 +209,193 @@ pub enum LinkRlibError { pub struct ThorinErrorWrapper(pub thorin::Error); -impl IntoDiagnostic<'_> for ThorinErrorWrapper { - fn into_diagnostic(self, dcx: &DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> { +impl IntoDiagnostic<'_, G> for ThorinErrorWrapper { + fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let build = |msg| DiagnosticBuilder::new(dcx, level, msg); let mut diag; match self.0 { thorin::Error::ReadInput(_) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_read_input_failure); + diag = build(fluent::codegen_ssa_thorin_read_input_failure); diag } thorin::Error::ParseFileKind(_) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_input_file_kind); + diag = build(fluent::codegen_ssa_thorin_parse_input_file_kind); diag } thorin::Error::ParseObjectFile(_) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_input_object_file); + diag = build(fluent::codegen_ssa_thorin_parse_input_object_file); diag } thorin::Error::ParseArchiveFile(_) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_input_archive_file); + diag = build(fluent::codegen_ssa_thorin_parse_input_archive_file); diag } thorin::Error::ParseArchiveMember(_) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_archive_member); + diag = build(fluent::codegen_ssa_thorin_parse_archive_member); diag } thorin::Error::InvalidInputKind => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_invalid_input_kind); + diag = build(fluent::codegen_ssa_thorin_invalid_input_kind); diag } thorin::Error::DecompressData(_) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_decompress_data); + diag = build(fluent::codegen_ssa_thorin_decompress_data); diag } thorin::Error::NamelessSection(_, offset) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_section_without_name); + diag = build(fluent::codegen_ssa_thorin_section_without_name); diag.set_arg("offset", format!("0x{offset:08x}")); diag } thorin::Error::RelocationWithInvalidSymbol(section, offset) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol); + diag = build(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol); diag.set_arg("section", section); diag.set_arg("offset", format!("0x{offset:08x}")); diag } thorin::Error::MultipleRelocations(section, offset) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_multiple_relocations); + diag = build(fluent::codegen_ssa_thorin_multiple_relocations); diag.set_arg("section", section); diag.set_arg("offset", format!("0x{offset:08x}")); diag } thorin::Error::UnsupportedRelocation(section, offset) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_unsupported_relocation); + diag = build(fluent::codegen_ssa_thorin_unsupported_relocation); diag.set_arg("section", section); diag.set_arg("offset", format!("0x{offset:08x}")); diag } thorin::Error::MissingDwoName(id) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_missing_dwo_name); + diag = build(fluent::codegen_ssa_thorin_missing_dwo_name); diag.set_arg("id", format!("0x{id:08x}")); diag } thorin::Error::NoCompilationUnits => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_no_compilation_units); + diag = build(fluent::codegen_ssa_thorin_no_compilation_units); diag } thorin::Error::NoDie => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_no_die); + diag = build(fluent::codegen_ssa_thorin_no_die); diag } thorin::Error::TopLevelDieNotUnit => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_top_level_die_not_unit); + diag = build(fluent::codegen_ssa_thorin_top_level_die_not_unit); diag } thorin::Error::MissingRequiredSection(section) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_missing_required_section); + diag = build(fluent::codegen_ssa_thorin_missing_required_section); diag.set_arg("section", section); diag } thorin::Error::ParseUnitAbbreviations(_) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_unit_abbreviations); + diag = build(fluent::codegen_ssa_thorin_parse_unit_abbreviations); diag } thorin::Error::ParseUnitAttribute(_) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_unit_attribute); + diag = build(fluent::codegen_ssa_thorin_parse_unit_attribute); diag } thorin::Error::ParseUnitHeader(_) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_unit_header); + diag = build(fluent::codegen_ssa_thorin_parse_unit_header); diag } thorin::Error::ParseUnit(_) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_unit); + diag = build(fluent::codegen_ssa_thorin_parse_unit); diag } thorin::Error::IncompatibleIndexVersion(section, format, actual) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_incompatible_index_version); + diag = build(fluent::codegen_ssa_thorin_incompatible_index_version); diag.set_arg("section", section); diag.set_arg("actual", actual); diag.set_arg("format", format); diag } thorin::Error::OffsetAtIndex(_, index) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_offset_at_index); + diag = build(fluent::codegen_ssa_thorin_offset_at_index); diag.set_arg("index", index); diag } thorin::Error::StrAtOffset(_, offset) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_str_at_offset); + diag = build(fluent::codegen_ssa_thorin_str_at_offset); diag.set_arg("offset", format!("0x{offset:08x}")); diag } thorin::Error::ParseIndex(_, section) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_parse_index); + diag = build(fluent::codegen_ssa_thorin_parse_index); diag.set_arg("section", section); diag } thorin::Error::UnitNotInIndex(unit) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_unit_not_in_index); + diag = build(fluent::codegen_ssa_thorin_unit_not_in_index); diag.set_arg("unit", format!("0x{unit:08x}")); diag } thorin::Error::RowNotInIndex(_, row) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_row_not_in_index); + diag = build(fluent::codegen_ssa_thorin_row_not_in_index); diag.set_arg("row", row); diag } thorin::Error::SectionNotInRow => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_section_not_in_row); + diag = build(fluent::codegen_ssa_thorin_section_not_in_row); diag } thorin::Error::EmptyUnit(unit) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_empty_unit); + diag = build(fluent::codegen_ssa_thorin_empty_unit); diag.set_arg("unit", format!("0x{unit:08x}")); diag } thorin::Error::MultipleDebugInfoSection => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_multiple_debug_info_section); + diag = build(fluent::codegen_ssa_thorin_multiple_debug_info_section); diag } thorin::Error::MultipleDebugTypesSection => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_multiple_debug_types_section); + diag = build(fluent::codegen_ssa_thorin_multiple_debug_types_section); diag } thorin::Error::NotSplitUnit => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_not_split_unit); + diag = build(fluent::codegen_ssa_thorin_not_split_unit); diag } thorin::Error::DuplicateUnit(unit) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_duplicate_unit); + diag = build(fluent::codegen_ssa_thorin_duplicate_unit); diag.set_arg("unit", format!("0x{unit:08x}")); diag } thorin::Error::MissingReferencedUnit(unit) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_missing_referenced_unit); + diag = build(fluent::codegen_ssa_thorin_missing_referenced_unit); diag.set_arg("unit", format!("0x{unit:08x}")); diag } thorin::Error::NoOutputObjectCreated => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_not_output_object_created); + diag = build(fluent::codegen_ssa_thorin_not_output_object_created); diag } thorin::Error::MixedInputEncodings => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_mixed_input_encodings); + diag = build(fluent::codegen_ssa_thorin_mixed_input_encodings); diag } thorin::Error::Io(e) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_io); + diag = build(fluent::codegen_ssa_thorin_io); diag.set_arg("error", format!("{e}")); diag } thorin::Error::ObjectRead(e) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_object_read); + diag = build(fluent::codegen_ssa_thorin_object_read); diag.set_arg("error", format!("{e}")); diag } thorin::Error::ObjectWrite(e) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_object_write); + diag = build(fluent::codegen_ssa_thorin_object_write); diag.set_arg("error", format!("{e}")); diag } thorin::Error::GimliRead(e) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_gimli_read); + diag = build(fluent::codegen_ssa_thorin_gimli_read); diag.set_arg("error", format!("{e}")); diag } thorin::Error::GimliWrite(e) => { - diag = dcx.struct_err(fluent::codegen_ssa_thorin_gimli_write); + diag = build(fluent::codegen_ssa_thorin_gimli_write); diag.set_arg("error", format!("{e}")); diag } @@ -410,9 +411,9 @@ pub struct LinkingFailed<'a> { pub escaped_output: String, } -impl IntoDiagnostic<'_> for LinkingFailed<'_> { - fn into_diagnostic(self, dcx: &DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_err(fluent::codegen_ssa_linking_failed); +impl IntoDiagnostic<'_, G> for LinkingFailed<'_> { + fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = DiagnosticBuilder::new(dcx, level, fluent::codegen_ssa_linking_failed); diag.set_arg("linker_path", format!("{}", self.linker_path.display())); diag.set_arg("exit_status", format!("{}", self.exit_status)); diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index adce1f5430f..eb9bf52676a 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -1,6 +1,6 @@ use rustc_errors::{ DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, - IntoDiagnostic, + IntoDiagnostic, Level, }; use rustc_hir::ConstContext; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -875,7 +875,10 @@ fn add_args( | InvalidProgramInfo::AlreadyReported(_) | InvalidProgramInfo::ConstPropNonsense => {} InvalidProgramInfo::Layout(e) => { - let diag: DiagnosticBuilder<'_, ()> = e.into_diagnostic().into_diagnostic(dcx); + // The level doesn't matter, `diag` is consumed without it being used. + let dummy_level = Level::Bug; + let diag: DiagnosticBuilder<'_, ()> = + e.into_diagnostic().into_diagnostic(dcx, dummy_level); for (name, val) in diag.args() { builder.set_arg(name.clone(), val.clone()); } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 3f66af1fcff..0079fa8b995 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -21,7 +21,7 @@ pub trait IntoDiagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> { /// Write out as a diagnostic out of `DiagCtxt`. #[must_use] - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, G>; + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G>; } impl<'a, T, G> IntoDiagnostic<'a, G> for Spanned @@ -29,8 +29,8 @@ impl<'a, T, G> IntoDiagnostic<'a, G> for Spanned T: IntoDiagnostic<'a, G>, G: EmissionGuarantee, { - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, G> { - let mut diag = self.node.into_diagnostic(dcx); + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { + let mut diag = self.node.into_diagnostic(dcx, level); diag.set_span(self.span); diag } @@ -339,16 +339,10 @@ fn deref_mut(&mut self) -> &mut Diagnostic { } impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { - /// Convenience function for internal use, clients should use one of the - /// `struct_*` methods on [`DiagCtxt`]. + #[rustc_lint_diagnostics] #[track_caller] - pub(crate) fn new>( - dcx: &'a DiagCtxt, - level: Level, - message: M, - ) -> Self { - let diagnostic = Diagnostic::new(level, message); - Self::new_diagnostic(dcx, diagnostic) + pub fn new>(dcx: &'a DiagCtxt, level: Level, message: M) -> Self { + Self::new_diagnostic(dcx, Diagnostic::new(level, message)) } /// Creates a new `DiagnosticBuilder` with an already constructed @@ -400,15 +394,15 @@ pub fn cancel(mut self) { /// later stage of the compiler. The diagnostic can be accessed with /// the provided `span` and `key` through [`DiagCtxt::steal_diagnostic()`]. /// - /// As with `buffer`, this is unless the handler has disabled such buffering. + /// As with `buffer`, this is unless the dcx has disabled such buffering. pub fn stash(self, span: Span, key: StashKey) { - if let Some((diag, handler)) = self.into_diagnostic() { - handler.stash_diagnostic(span, key, diag); + if let Some((diag, dcx)) = self.into_diagnostic() { + dcx.stash_diagnostic(span, key, diag); } } /// Converts the builder to a `Diagnostic` for later emission, - /// unless handler has disabled such buffering, or `.emit()` was called. + /// unless dcx has disabled such buffering, or `.emit()` was called. pub fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a DiagCtxt)> { let dcx = match self.inner.state { // No `.emit()` calls, the `&DiagCtxt` is still available. @@ -449,7 +443,7 @@ pub fn dcx(&self) -> Option<&DiagCtxt> { } /// Buffers the diagnostic for later emission, - /// unless handler has disabled such buffering. + /// unless dcx has disabled such buffering. pub fn buffer(self, buffered_diagnostics: &mut Vec) { buffered_diagnostics.extend(self.into_diagnostic().map(|(diag, _)| diag)); } diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 3e4b3ee758a..ccc951543d8 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -1,10 +1,12 @@ use crate::diagnostic::DiagnosticLocation; use crate::{fluent_generated as fluent, AddToDiagnostic}; -use crate::{DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, IntoDiagnostic, IntoDiagnosticArg}; +use crate::{ + DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, + IntoDiagnosticArg, Level, +}; use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_hir as hir; -use rustc_lint_defs::Level; use rustc_span::edition::Edition; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol}; use rustc_span::Span; @@ -216,7 +218,7 @@ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { } } -impl IntoDiagnosticArg for Level { +impl IntoDiagnosticArg for rustc_lint_defs::Level { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(Cow::Borrowed(self.to_cmd_flag())) } @@ -245,19 +247,20 @@ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { } } -impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> { - fn into_diagnostic(self, dcx: &DiagCtxt) -> DiagnosticBuilder<'_, !> { +impl IntoDiagnostic<'_, G> for TargetDataLayoutErrors<'_> { + fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { let mut diag; match self { TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => { - diag = dcx.struct_fatal(fluent::errors_target_invalid_address_space); + diag = + DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_address_space); diag.set_arg("addr_space", addr_space); diag.set_arg("cause", cause); diag.set_arg("err", err); diag } TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => { - diag = dcx.struct_fatal(fluent::errors_target_invalid_bits); + diag = DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_bits); diag.set_arg("kind", kind); diag.set_arg("bit", bit); diag.set_arg("cause", cause); @@ -265,31 +268,39 @@ fn into_diagnostic(self, dcx: &DiagCtxt) -> DiagnosticBuilder<'_, !> { diag } TargetDataLayoutErrors::MissingAlignment { cause } => { - diag = dcx.struct_fatal(fluent::errors_target_missing_alignment); + diag = DiagnosticBuilder::new(dcx, level, fluent::errors_target_missing_alignment); diag.set_arg("cause", cause); diag } TargetDataLayoutErrors::InvalidAlignment { cause, err } => { - diag = dcx.struct_fatal(fluent::errors_target_invalid_alignment); + diag = DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_alignment); diag.set_arg("cause", cause); diag.set_arg("err_kind", err.diag_ident()); diag.set_arg("align", err.align()); diag } TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => { - diag = dcx.struct_fatal(fluent::errors_target_inconsistent_architecture); + diag = DiagnosticBuilder::new( + dcx, + level, + fluent::errors_target_inconsistent_architecture, + ); diag.set_arg("dl", dl); diag.set_arg("target", target); diag } TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => { - diag = dcx.struct_fatal(fluent::errors_target_inconsistent_pointer_width); + diag = DiagnosticBuilder::new( + dcx, + level, + fluent::errors_target_inconsistent_pointer_width, + ); diag.set_arg("pointer_size", pointer_size); diag.set_arg("target", target); diag } TargetDataLayoutErrors::InvalidBitsSize { err } => { - diag = dcx.struct_fatal(fluent::errors_target_invalid_bits_size); + diag = DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_bits_size); diag.set_arg("err", err); diag } @@ -362,9 +373,9 @@ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { pub struct InvalidFlushedDelayedDiagnosticLevel { #[primary_span] pub span: Span, - pub level: rustc_errors::Level, + pub level: Level, } -impl IntoDiagnosticArg for rustc_errors::Level { +impl IntoDiagnosticArg for Level { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(Cow::from(self.to_string())) } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 763de78451e..5027f63a970 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1279,14 +1279,14 @@ pub fn create_err<'a>( &'a self, err: impl IntoDiagnostic<'a>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - err.into_diagnostic(self) + err.into_diagnostic(self, Level::Error { lint: false }) } pub fn create_warning<'a>( &'a self, warning: impl IntoDiagnostic<'a, ()>, ) -> DiagnosticBuilder<'a, ()> { - warning.into_diagnostic(self) + warning.into_diagnostic(self, Level::Warning(None)) } pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { @@ -1297,7 +1297,7 @@ pub fn create_almost_fatal<'a>( &'a self, fatal: impl IntoDiagnostic<'a, FatalError>, ) -> DiagnosticBuilder<'a, FatalError> { - fatal.into_diagnostic(self) + fatal.into_diagnostic(self, Level::Fatal) } pub fn emit_almost_fatal<'a>( @@ -1311,7 +1311,7 @@ pub fn create_fatal<'a>( &'a self, fatal: impl IntoDiagnostic<'a, !>, ) -> DiagnosticBuilder<'a, !> { - fatal.into_diagnostic(self) + fatal.into_diagnostic(self, Level::Fatal) } pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, !>) -> ! { @@ -1322,7 +1322,7 @@ pub fn create_bug<'a>( &'a self, bug: impl IntoDiagnostic<'a, diagnostic_builder::Bug>, ) -> DiagnosticBuilder<'a, diagnostic_builder::Bug> { - bug.into_diagnostic(self) + bug.into_diagnostic(self, Level::Bug) } pub fn emit_bug<'a>( @@ -1340,7 +1340,7 @@ pub fn create_note<'a>( &'a self, note: impl IntoDiagnostic<'a, Noted>, ) -> DiagnosticBuilder<'a, Noted> { - note.into_diagnostic(self) + note.into_diagnostic(self, Level::Note) } pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index f461b6a94ec..41f30057902 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -2,8 +2,8 @@ use crate::fluent_generated as fluent; use rustc_errors::{ - error_code, Applicability, DiagCtxt, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, - MultiSpan, + error_code, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, + Level, MultiSpan, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::Ty; @@ -315,14 +315,12 @@ pub struct MissingTypeParams { } // Manual implementation of `IntoDiagnostic` to be able to call `span_to_snippet`. -impl<'a> IntoDiagnostic<'a> for MissingTypeParams { +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for MissingTypeParams { #[track_caller] - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - let mut err = dcx.struct_span_err_with_code( - self.span, - fluent::hir_analysis_missing_type_params, - error_code!(E0393), - ); + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { + let mut err = DiagnosticBuilder::new(dcx, level, fluent::hir_analysis_missing_type_params); + err.set_span(self.span); + err.code(error_code!(E0393)); err.set_arg("parameterCount", self.missing_type_params.len()); err.set_arg( "parameters", diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index be8582d0ba0..027c97330b1 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -51,7 +51,11 @@ pub(crate) fn into_tokens(self) -> TokenStream { Some(slug) => { slugs.borrow_mut().push(slug.clone()); quote! { - let mut diag = dcx.struct_diagnostic(crate::fluent_generated::#slug); + let mut diag = rustc_errors::DiagnosticBuilder::new( + dcx, + level, + crate::fluent_generated::#slug + ); } } }; @@ -77,7 +81,8 @@ pub(crate) fn into_tokens(self) -> TokenStream { #[track_caller] fn into_diagnostic( self, - dcx: &'_sess rustc_errors::DiagCtxt + dcx: &'_sess rustc_errors::DiagCtxt, + level: rustc_errors::Level ) -> rustc_errors::DiagnosticBuilder<'_sess, G> { #implementation } diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 206c15edd78..e13068cb6f9 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -3,7 +3,9 @@ path::{Path, PathBuf}, }; -use rustc_errors::{error_code, ErrorGuaranteed, IntoDiagnostic}; +use rustc_errors::{ + error_code, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level, +}; use rustc_macros::Diagnostic; use rustc_session::config; use rustc_span::{sym, Span, Symbol}; @@ -495,12 +497,9 @@ pub(crate) struct MultipleCandidates { pub candidates: Vec, } -impl IntoDiagnostic<'_> for MultipleCandidates { - fn into_diagnostic( - self, - dcx: &'_ rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_err(fluent::metadata_multiple_candidates); +impl IntoDiagnostic<'_, G> for MultipleCandidates { + fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = DiagnosticBuilder::new(dcx, level, fluent::metadata_multiple_candidates); diag.set_arg("crate_name", self.crate_name); diag.set_arg("flavor", self.flavor); diag.code(error_code!(E0464)); @@ -593,13 +592,10 @@ pub struct InvalidMetadataFiles { pub crate_rejections: Vec, } -impl IntoDiagnostic<'_> for InvalidMetadataFiles { +impl IntoDiagnostic<'_, G> for InvalidMetadataFiles { #[track_caller] - fn into_diagnostic( - self, - dcx: &'_ rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_err(fluent::metadata_invalid_meta_files); + fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = DiagnosticBuilder::new(dcx, level, fluent::metadata_invalid_meta_files); diag.set_arg("crate_name", self.crate_name); diag.set_arg("add_info", self.add_info); diag.code(error_code!(E0786)); @@ -623,13 +619,10 @@ pub struct CannotFindCrate { pub is_ui_testing: bool, } -impl IntoDiagnostic<'_> for CannotFindCrate { +impl IntoDiagnostic<'_, G> for CannotFindCrate { #[track_caller] - fn into_diagnostic( - self, - dcx: &'_ rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_err(fluent::metadata_cannot_find_crate); + fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = DiagnosticBuilder::new(dcx, level, fluent::metadata_cannot_find_crate); diag.set_arg("crate_name", self.crate_name); diag.set_arg("current_crate", self.current_crate); diag.set_arg("add_info", self.add_info); diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 225dd217807..5ae758edfa3 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -5,7 +5,8 @@ use crate::ty::{self, ConstKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_error_messages::DiagnosticMessage; use rustc_errors::{ - DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, IntoDiagnostic, IntoDiagnosticArg, + DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, + IntoDiagnosticArg, Level, }; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -1272,14 +1273,14 @@ pub enum FnAbiError<'tcx> { AdjustForForeignAbi(call::AdjustForForeignAbiError), } -impl<'a, 'b> IntoDiagnostic<'a, !> for FnAbiError<'b> { - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, !> { +impl<'a, 'b, G: EmissionGuarantee> IntoDiagnostic<'a, G> for FnAbiError<'b> { + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { match self { - Self::Layout(e) => e.into_diagnostic().into_diagnostic(dcx), + Self::Layout(e) => e.into_diagnostic().into_diagnostic(dcx, level), Self::AdjustForForeignAbi(call::AdjustForForeignAbiError::Unsupported { arch, abi, - }) => UnsupportedFnAbi { arch, abi: abi.name() }.into_diagnostic(dcx), + }) => UnsupportedFnAbi { arch, abi: abi.name() }.into_diagnostic(dcx, level), } } } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index db2624cac02..0f6d8c36203 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -2,7 +2,7 @@ use rustc_errors::DiagnosticArgValue; use rustc_errors::{ error_code, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, - ErrorGuaranteed, IntoDiagnostic, MultiSpan, SubdiagnosticMessage, + ErrorGuaranteed, IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessage, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{self, Ty}; @@ -461,13 +461,18 @@ pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> { } impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_span_err_with_code( - self.span, + fn into_diagnostic( + self, + dcx: &'a DiagCtxt, + level: Level, + ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = DiagnosticBuilder::new( + dcx, + level, fluent::mir_build_non_exhaustive_patterns_type_not_empty, - error_code!(E0004), ); - + diag.set_span(self.span); + diag.code(error_code!(E0004)); let peeled_ty = self.ty.peel_refs(); diag.set_arg("ty", self.ty); diag.set_arg("peeled_ty", peeled_ty); diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index fd4af31501c..17916e16daf 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -2,7 +2,7 @@ use rustc_errors::{ Applicability, DecorateLint, DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, - DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, + DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, Level, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails}; @@ -62,10 +62,10 @@ pub(crate) struct RequiresUnsafe { // so we need to eagerly translate the label here, which isn't supported by the derive API // We could also exhaustively list out the primary messages for all unsafe violations, // but this would result in a lot of duplication. -impl<'sess> IntoDiagnostic<'sess> for RequiresUnsafe { +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for RequiresUnsafe { #[track_caller] - fn into_diagnostic(self, dcx: &'sess DiagCtxt) -> DiagnosticBuilder<'sess, ErrorGuaranteed> { - let mut diag = dcx.struct_err(fluent::mir_transform_requires_unsafe); + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { + let mut diag = DiagnosticBuilder::new(dcx, level, fluent::mir_transform_requires_unsafe); diag.code(rustc_errors::DiagnosticId::Error("E0133".to_string())); diag.set_span(self.span); diag.span_label(self.span, self.details.label()); diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 247b2245583..592e71251b8 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -1,8 +1,7 @@ use std::path::PathBuf; use crate::fluent_generated as fluent; -use rustc_errors::ErrorGuaranteed; -use rustc_errors::IntoDiagnostic; +use rustc_errors::{DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level}; use rustc_macros::{Diagnostic, LintDiagnostic}; use rustc_span::{Span, Symbol}; @@ -47,13 +46,11 @@ pub struct UnusedGenericParamsHint { pub param_names: Vec, } -impl IntoDiagnostic<'_> for UnusedGenericParamsHint { +impl IntoDiagnostic<'_, G> for UnusedGenericParamsHint { #[track_caller] - fn into_diagnostic( - self, - dcx: &'_ rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_err(fluent::monomorphize_unused_generic_params); + fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = + DiagnosticBuilder::new(dcx, level, fluent::monomorphize_unused_generic_params); diag.set_span(self.span); for (span, name) in self.param_spans.into_iter().zip(self.param_names) { // FIXME: I can figure out how to do a label with a fluent string with a fixed message, diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 008adcc83d0..8ccfcb625a6 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2,7 +2,10 @@ use rustc_ast::token::Token; use rustc_ast::{Path, Visibility}; -use rustc_errors::{AddToDiagnostic, Applicability, ErrorGuaranteed, IntoDiagnostic}; +use rustc_errors::{ + AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, + Level, SubdiagnosticMessage, +}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; @@ -1042,23 +1045,30 @@ impl<'a> IntoDiagnostic<'a> for ExpectedIdentifier { #[track_caller] fn into_diagnostic( self, - dcx: &'a rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { + dcx: &'a DiagCtxt, + level: Level, + ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let token_descr = TokenDescription::from_token(&self.token); - let mut diag = dcx.struct_err(match token_descr { - Some(TokenDescription::ReservedIdentifier) => { - fluent::parse_expected_identifier_found_reserved_identifier_str - } - Some(TokenDescription::Keyword) => fluent::parse_expected_identifier_found_keyword_str, - Some(TokenDescription::ReservedKeyword) => { - fluent::parse_expected_identifier_found_reserved_keyword_str - } - Some(TokenDescription::DocComment) => { - fluent::parse_expected_identifier_found_doc_comment_str - } - None => fluent::parse_expected_identifier_found_str, - }); + let mut diag = DiagnosticBuilder::new( + dcx, + level, + match token_descr { + Some(TokenDescription::ReservedIdentifier) => { + fluent::parse_expected_identifier_found_reserved_identifier_str + } + Some(TokenDescription::Keyword) => { + fluent::parse_expected_identifier_found_keyword_str + } + Some(TokenDescription::ReservedKeyword) => { + fluent::parse_expected_identifier_found_reserved_keyword_str + } + Some(TokenDescription::DocComment) => { + fluent::parse_expected_identifier_found_doc_comment_str + } + None => fluent::parse_expected_identifier_found_str, + }, + ); diag.set_span(self.span); diag.set_arg("token", self.token); @@ -1099,21 +1109,28 @@ impl<'a> IntoDiagnostic<'a> for ExpectedSemi { #[track_caller] fn into_diagnostic( self, - dcx: &'a rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { + dcx: &'a DiagCtxt, + level: Level, + ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let token_descr = TokenDescription::from_token(&self.token); - let mut diag = dcx.struct_err(match token_descr { - Some(TokenDescription::ReservedIdentifier) => { - fluent::parse_expected_semi_found_reserved_identifier_str - } - Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str, - Some(TokenDescription::ReservedKeyword) => { - fluent::parse_expected_semi_found_reserved_keyword_str - } - Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str, - None => fluent::parse_expected_semi_found_str, - }); + let mut diag = DiagnosticBuilder::new( + dcx, + level, + match token_descr { + Some(TokenDescription::ReservedIdentifier) => { + fluent::parse_expected_semi_found_reserved_identifier_str + } + Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str, + Some(TokenDescription::ReservedKeyword) => { + fluent::parse_expected_semi_found_reserved_keyword_str + } + Some(TokenDescription::DocComment) => { + fluent::parse_expected_semi_found_doc_comment_str + } + None => fluent::parse_expected_semi_found_str, + }, + ); diag.set_span(self.span); diag.set_arg("token", self.token); @@ -1436,10 +1453,7 @@ pub(crate) struct FnTraitMissingParen { impl AddToDiagnostic for FnTraitMissingParen { fn add_to_diagnostic_with(self, diag: &mut rustc_errors::Diagnostic, _: F) where - F: Fn( - &mut rustc_errors::Diagnostic, - rustc_errors::SubdiagnosticMessage, - ) -> rustc_errors::SubdiagnosticMessage, + F: Fn(&mut rustc_errors::Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, { diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren); let applicability = if self.machine_applicable { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 8f8da211d31..856256a0641 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -6,8 +6,8 @@ use crate::fluent_generated as fluent; use rustc_ast::Label; use rustc_errors::{ - error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticSymbolList, ErrorGuaranteed, - IntoDiagnostic, MultiSpan, + error_code, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, + DiagnosticSymbolList, EmissionGuarantee, IntoDiagnostic, Level, MultiSpan, }; use rustc_hir::{self as hir, ExprKind, Target}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -863,13 +863,11 @@ pub struct ItemFollowingInnerAttr { pub kind: &'static str, } -impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel { +impl IntoDiagnostic<'_, G> for InvalidAttrAtCrateLevel { #[track_caller] - fn into_diagnostic( - self, - dcx: &'_ rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_err(fluent::passes_invalid_attr_at_crate_level); + fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = + DiagnosticBuilder::new(dcx, level, fluent::passes_invalid_attr_at_crate_level); diag.set_span(self.span); diag.set_arg("name", self.name); // Only emit an error with a suggestion if we can create a string out @@ -879,7 +877,7 @@ fn into_diagnostic( span, fluent::passes_suggestion, String::new(), - rustc_errors::Applicability::MachineApplicable, + Applicability::MachineApplicable, ); } if let Some(item) = self.item { @@ -1016,17 +1014,12 @@ pub struct BreakNonLoop<'a> { pub break_expr_span: Span, } -impl<'a> IntoDiagnostic<'_> for BreakNonLoop<'a> { +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'_, G> for BreakNonLoop<'a> { #[track_caller] - fn into_diagnostic( - self, - dcx: &rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_span_err_with_code( - self.span, - fluent::passes_break_non_loop, - error_code!(E0571), - ); + fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = DiagnosticBuilder::new(dcx, level, fluent::passes_break_non_loop); + diag.set_span(self.span); + diag.code(error_code!(E0571)); diag.set_arg("kind", self.kind); diag.span_label(self.span, fluent::passes_label); if let Some(head) = self.head { @@ -1165,17 +1158,12 @@ pub struct NakedFunctionsAsmBlock { pub non_asms: Vec, } -impl IntoDiagnostic<'_> for NakedFunctionsAsmBlock { +impl IntoDiagnostic<'_, G> for NakedFunctionsAsmBlock { #[track_caller] - fn into_diagnostic( - self, - dcx: &rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_span_err_with_code( - self.span, - fluent::passes_naked_functions_asm_block, - error_code!(E0787), - ); + fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = DiagnosticBuilder::new(dcx, level, fluent::passes_naked_functions_asm_block); + diag.set_span(self.span); + diag.code(error_code!(E0787)); for span in self.multiple_asms.iter() { diag.span_label(*span, fluent::passes_label_multiple_asm); } @@ -1281,17 +1269,12 @@ pub struct NoMainErr { pub add_teach_note: bool, } -impl<'a> IntoDiagnostic<'a> for NoMainErr { +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for NoMainErr { #[track_caller] - fn into_diagnostic( - self, - dcx: &'a rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { - let mut diag = dcx.struct_span_err_with_code( - DUMMY_SP, - fluent::passes_no_main_function, - error_code!(E0601), - ); + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { + let mut diag = DiagnosticBuilder::new(dcx, level, fluent::passes_no_main_function); + diag.set_span(DUMMY_SP); + diag.code(error_code!(E0601)); diag.set_arg("crate_name", self.crate_name); diag.set_arg("filename", self.filename); diag.set_arg("has_filename", self.has_filename); @@ -1344,20 +1327,19 @@ pub struct DuplicateLangItem { pub(crate) duplicate: Duplicate, } -impl IntoDiagnostic<'_> for DuplicateLangItem { +impl IntoDiagnostic<'_, G> for DuplicateLangItem { #[track_caller] - fn into_diagnostic( - self, - dcx: &rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_err_with_code( + fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { + let mut diag = DiagnosticBuilder::new( + dcx, + level, match self.duplicate { Duplicate::Plain => fluent::passes_duplicate_lang_item, Duplicate::Crate => fluent::passes_duplicate_lang_item_crate, Duplicate::CrateDepends => fluent::passes_duplicate_lang_item_crate_depends, }, - error_code!(E0152), ); + diag.code(error_code!(E0152)); diag.set_arg("lang_item_name", self.lang_item_name); diag.set_arg("crate_name", self.crate_name); diag.set_arg("dependency_of", self.dependency_of); diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index c3360815ac9..8ab31f6f382 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -3,7 +3,10 @@ use crate::parse::ParseSess; use rustc_ast::token; use rustc_ast::util::literal::LitError; -use rustc_errors::{error_code, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic, MultiSpan}; +use rustc_errors::{ + error_code, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic, + Level, MultiSpan, +}; use rustc_macros::Diagnostic; use rustc_span::{BytePos, Span, Symbol}; use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple}; @@ -17,9 +20,10 @@ impl<'a> IntoDiagnostic<'a> for FeatureGateError { #[track_caller] fn into_diagnostic( self, - dcx: &'a rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { - let mut diag = dcx.struct_err(self.explain); + dcx: &'a DiagCtxt, + level: Level, + ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + let mut diag = DiagnosticBuilder::new(dcx, level, self.explain); diag.set_span(self.span); diag.code(error_code!(E0658)); diag diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 2cb47e3a932..8e8b420df13 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -14,7 +14,7 @@ use rustc_errors::{emitter::SilentEmitter, DiagCtxt}; use rustc_errors::{ fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, - ErrorGuaranteed, IntoDiagnostic, MultiSpan, Noted, StashKey, + ErrorGuaranteed, IntoDiagnostic, Level, MultiSpan, Noted, StashKey, }; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; @@ -322,7 +322,7 @@ pub fn create_err<'a>( &'a self, err: impl IntoDiagnostic<'a>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - err.into_diagnostic(&self.dcx) + err.into_diagnostic(&self.dcx, Level::Error { lint: false }) } #[track_caller] @@ -335,7 +335,7 @@ pub fn create_warning<'a>( &'a self, warning: impl IntoDiagnostic<'a, ()>, ) -> DiagnosticBuilder<'a, ()> { - warning.into_diagnostic(&self.dcx) + warning.into_diagnostic(&self.dcx, Level::Warning(None)) } #[track_caller] @@ -348,7 +348,7 @@ pub fn create_note<'a>( &'a self, note: impl IntoDiagnostic<'a, Noted>, ) -> DiagnosticBuilder<'a, Noted> { - note.into_diagnostic(&self.dcx) + note.into_diagnostic(&self.dcx, Level::Note) } #[track_caller] @@ -361,7 +361,7 @@ pub fn create_fatal<'a>( &'a self, fatal: impl IntoDiagnostic<'a, !>, ) -> DiagnosticBuilder<'a, !> { - fatal.into_diagnostic(&self.dcx) + fatal.into_diagnostic(&self.dcx, Level::Fatal) } #[track_caller] diff --git a/compiler/rustc_symbol_mangling/src/errors.rs b/compiler/rustc_symbol_mangling/src/errors.rs index ff253b6f467..06a2b3ca9c4 100644 --- a/compiler/rustc_symbol_mangling/src/errors.rs +++ b/compiler/rustc_symbol_mangling/src/errors.rs @@ -1,6 +1,6 @@ //! Errors emitted by symbol_mangling. -use rustc_errors::{ErrorGuaranteed, IntoDiagnostic}; +use rustc_errors::{DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level}; use rustc_span::Span; use std::fmt; @@ -13,15 +13,12 @@ pub struct TestOutput { // This diagnostic doesn't need translation because (a) it doesn't contain any // natural language, and (b) it's only used in tests. So we construct it // manually and avoid the fluent machinery. -impl IntoDiagnostic<'_> for TestOutput { - fn into_diagnostic( - self, - dcx: &'_ rustc_errors::DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { +impl IntoDiagnostic<'_, G> for TestOutput { + fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { let TestOutput { span, kind, content } = self; #[allow(rustc::untranslatable_diagnostic)] - let mut diag = dcx.struct_err(format!("{kind}({content})")); + let mut diag = DiagnosticBuilder::new(dcx, level, format!("{kind}({content})")); diag.set_span(span); diag } diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index b0ec8b3a4fa..bea6fbd6ac5 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -1,7 +1,7 @@ use crate::fluent_generated as fluent; use rustc_errors::{ - AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, ErrorGuaranteed, IntoDiagnostic, - SubdiagnosticMessage, + AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, EmissionGuarantee, + IntoDiagnostic, Level, SubdiagnosticMessage, }; use rustc_macros::Diagnostic; use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty}; @@ -57,13 +57,15 @@ pub struct NegativePositiveConflict<'tcx> { pub positive_impl_span: Result, } -impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> { +impl IntoDiagnostic<'_, G> for NegativePositiveConflict<'_> { #[track_caller] fn into_diagnostic( self, dcx: &DiagCtxt, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = dcx.struct_err(fluent::trait_selection_negative_positive_conflict); + level: Level, + ) -> rustc_errors::DiagnosticBuilder<'_, G> { + let mut diag = + DiagnosticBuilder::new(dcx, level, fluent::trait_selection_negative_positive_conflict); diag.set_arg("trait_desc", self.trait_desc.print_only_trait_path().to_string()); diag.set_arg( "self_desc", diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs index 4b006151c64..ab42d3b8c1e 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.rs +++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs @@ -13,8 +13,8 @@ extern crate rustc_span; use rustc_errors::{ - AddToDiagnostic, DiagCtxt, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, - IntoDiagnostic, SubdiagnosticMessage, + AddToDiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, DiagCtxt, + IntoDiagnostic, Level, SubdiagnosticMessage, }; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; @@ -37,18 +37,18 @@ struct Note { pub struct UntranslatableInIntoDiagnostic; -impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for UntranslatableInIntoDiagnostic { - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - dcx.struct_err("untranslatable diagnostic") +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UntranslatableInIntoDiagnostic { + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { + DiagnosticBuilder::new(dcx, level, "untranslatable diagnostic") //~^ ERROR diagnostics should be created using translatable messages } } pub struct TranslatableInIntoDiagnostic; -impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for TranslatableInIntoDiagnostic { - fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - dcx.struct_err(crate::fluent_generated::no_crate_example) +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for TranslatableInIntoDiagnostic { + fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { + DiagnosticBuilder::new(dcx, level, crate::fluent_generated::no_crate_example) } } diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr index d18db3cbbd3..f70240ecf17 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr @@ -1,8 +1,8 @@ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:42:13 + --> $DIR/diagnostics.rs:42:9 | -LL | dcx.struct_err("untranslatable diagnostic") - | ^^^^^^^^^^ +LL | DiagnosticBuilder::new(dcx, level, "untranslatable diagnostic") + | ^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/diagnostics.rs:6:9