mirror of https://github.com/rust-lang/rust.git
Auto merge of #119097 - nnethercote:fix-EmissionGuarantee, r=compiler-errors
Fix `EmissionGuarantee` There are some problems with the `DiagCtxt` API related to `EmissionGuarantee`. This PR fixes them. r? `@compiler-errors`
This commit is contained in:
commit
cee794ee98
|
@ -2,7 +2,8 @@ use std::num::IntErrorKind;
|
|||
|
||||
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::<Vec<_>>();
|
||||
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 @@ impl<'a> IntoDiagnostic<'a> for UnsupportedLiteral {
|
|||
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,
|
||||
|
|
|
@ -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<Span>,
|
||||
}
|
||||
|
||||
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<str>`
|
||||
let lbl1 = dcx.eagerly_translate_to_string(
|
||||
|
|
|
@ -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<G: EmissionGuarantee> 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);
|
||||
};
|
||||
|
|
|
@ -4,9 +4,7 @@ use std::path::Path;
|
|||
|
||||
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 DynamicLinkingWithLTO;
|
|||
|
||||
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<G: EmissionGuarantee> 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<G: EmissionGuarantee> 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<G: EmissionGuarantee> 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 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for WithLlvmError<'_> {
|
|||
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
|
||||
|
|
|
@ -4,8 +4,8 @@ use crate::assert_module_sources::CguReuse;
|
|||
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<G: EmissionGuarantee> 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<G: EmissionGuarantee> 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));
|
||||
|
||||
|
|
|
@ -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 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
|
|||
| 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());
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ use std::thread::panicking;
|
|||
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<T>
|
||||
|
@ -29,8 +29,8 @@ where
|
|||
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
|
||||
}
|
||||
|
@ -101,18 +101,31 @@ rustc_data_structures::static_assert_size!(
|
|||
/// Trait for types that `DiagnosticBuilder::emit` can return as a "guarantee"
|
||||
/// (or "proof") token that the emission happened.
|
||||
pub trait EmissionGuarantee: Sized {
|
||||
/// This exists so that bugs and fatal errors can both result in `!` (an
|
||||
/// abort) when emitted, but have different aborting behaviour.
|
||||
type EmitResult = Self;
|
||||
|
||||
/// Implementation of `DiagnosticBuilder::emit`, fully controlled by each
|
||||
/// `impl` of `EmissionGuarantee`, to make it impossible to create a value
|
||||
/// of `Self` without actually performing the emission.
|
||||
/// of `Self::EmitResult` without actually performing the emission.
|
||||
#[track_caller]
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self;
|
||||
fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult;
|
||||
}
|
||||
|
||||
/// Creates a new `DiagnosticBuilder` that will return this type of guarantee.
|
||||
#[track_caller]
|
||||
fn make_diagnostic_builder(
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self>;
|
||||
impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
||||
/// Most `emit_producing_guarantee` functions use this as a starting point.
|
||||
fn emit_producing_nothing(&mut self) {
|
||||
match self.inner.state {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
self.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
|
||||
dcx.emit_diagnostic_without_consuming(&mut self.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
|
@ -126,7 +139,8 @@ impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
|||
|
||||
// FIXME(eddyb) make `ErrorGuaranteed` impossible to create outside `.emit()`.
|
||||
impl EmissionGuarantee for ErrorGuaranteed {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
|
||||
// Contrast this with `emit_producing_nothing`.
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
|
@ -163,142 +177,48 @@ impl EmissionGuarantee for ErrorGuaranteed {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn make_diagnostic_builder(
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(dcx, Level::Error { lint: false }, msg)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(eddyb) should there be a `Option<ErrorGuaranteed>` impl as well?
|
||||
impl EmissionGuarantee for () {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
|
||||
dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(dcx, Level::Warning(None), msg)
|
||||
}
|
||||
}
|
||||
|
||||
/// Marker type which enables implementation of `create_note` and `emit_note` functions for
|
||||
/// note-without-error struct diagnostics.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Noted;
|
||||
|
||||
impl EmissionGuarantee for Noted {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
}
|
||||
|
||||
Noted
|
||||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(dcx, Level::Note, msg)
|
||||
fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
|
||||
db.emit_producing_nothing();
|
||||
}
|
||||
}
|
||||
|
||||
/// Marker type which enables implementation of `create_bug` and `emit_bug` functions for
|
||||
/// bug struct diagnostics.
|
||||
/// bug diagnostics.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Bug;
|
||||
pub struct BugAbort;
|
||||
|
||||
impl EmissionGuarantee for Bug {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
impl EmissionGuarantee for BugAbort {
|
||||
type EmitResult = !;
|
||||
|
||||
dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
}
|
||||
// Then panic. No need to return the marker type.
|
||||
fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
|
||||
db.emit_producing_nothing();
|
||||
panic::panic_any(ExplicitBug);
|
||||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(dcx, Level::Bug, msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl EmissionGuarantee for ! {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
/// Marker type which enables implementation of `create_fatal` and `emit_fatal` functions for
|
||||
/// fatal diagnostics.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct FatalAbort;
|
||||
|
||||
dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
}
|
||||
// Then fatally error, returning `!`
|
||||
impl EmissionGuarantee for FatalAbort {
|
||||
type EmitResult = !;
|
||||
|
||||
fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
|
||||
db.emit_producing_nothing();
|
||||
crate::FatalError.raise()
|
||||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(dcx, Level::Fatal, msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
|
||||
fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self {
|
||||
match db.inner.state {
|
||||
// First `.emit()` call, the `&DiagCtxt` is still available.
|
||||
DiagnosticBuilderState::Emittable(dcx) => {
|
||||
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
|
||||
|
||||
dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
|
||||
}
|
||||
// `.emit()` was previously called, disallowed from repeating it.
|
||||
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
|
||||
}
|
||||
// Then fatally error..
|
||||
fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
|
||||
db.emit_producing_nothing();
|
||||
rustc_span::fatal_error::FatalError
|
||||
}
|
||||
|
||||
fn make_diagnostic_builder(
|
||||
dcx: &DiagCtxt,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new(dcx, Level::Fatal, msg)
|
||||
}
|
||||
}
|
||||
|
||||
/// In general, the `DiagnosticBuilder` uses deref to allow access to
|
||||
|
@ -339,16 +259,10 @@ impl<G: EmissionGuarantee> DerefMut for DiagnosticBuilder<'_, G> {
|
|||
}
|
||||
|
||||
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<M: Into<DiagnosticMessage>>(
|
||||
dcx: &'a DiagCtxt,
|
||||
level: Level,
|
||||
message: M,
|
||||
) -> Self {
|
||||
let diagnostic = Diagnostic::new(level, message);
|
||||
Self::new_diagnostic(dcx, diagnostic)
|
||||
pub fn new<M: Into<DiagnosticMessage>>(dcx: &'a DiagCtxt, level: Level, message: M) -> Self {
|
||||
Self::new_diagnostic(dcx, Diagnostic::new(level, message))
|
||||
}
|
||||
|
||||
/// Creates a new `DiagnosticBuilder` with an already constructed
|
||||
|
@ -369,8 +283,8 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
|||
/// but there are various places that rely on continuing to use `self`
|
||||
/// after calling `emit`.
|
||||
#[track_caller]
|
||||
pub fn emit(&mut self) -> G {
|
||||
G::diagnostic_builder_emit_producing_guarantee(self)
|
||||
pub fn emit(&mut self) -> G::EmitResult {
|
||||
G::emit_producing_guarantee(self)
|
||||
}
|
||||
|
||||
/// Emit the diagnostic unless `delay` is true,
|
||||
|
@ -378,7 +292,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
|||
///
|
||||
/// See `emit` and `delay_as_bug` for details.
|
||||
#[track_caller]
|
||||
pub fn emit_unless(&mut self, delay: bool) -> G {
|
||||
pub fn emit_unless(&mut self, delay: bool) -> G::EmitResult {
|
||||
if delay {
|
||||
self.downgrade_to_delayed_bug();
|
||||
}
|
||||
|
@ -400,15 +314,15 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
|||
/// 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 +363,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
|||
}
|
||||
|
||||
/// 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<Diagnostic>) {
|
||||
buffered_diagnostics.extend(self.into_diagnostic().map(|(diag, _)| diag));
|
||||
}
|
||||
|
@ -465,7 +379,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
|||
/// In the meantime, though, callsites are required to deal with the "bug"
|
||||
/// locally in whichever way makes the most sense.
|
||||
#[track_caller]
|
||||
pub fn delay_as_bug(&mut self) -> G {
|
||||
pub fn delay_as_bug(&mut self) -> G::EmitResult {
|
||||
self.downgrade_to_delayed_bug();
|
||||
self.emit()
|
||||
}
|
||||
|
|
|
@ -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 @@ impl IntoDiagnosticArg for ast::Visibility {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ impl<Id> IntoDiagnosticArg for hir::def::Res<Id> {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
|
||||
fn into_diagnostic(self, dcx: &DiagCtxt) -> DiagnosticBuilder<'_, !> {
|
||||
impl<G: EmissionGuarantee> 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 @@ impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
|
|||
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 @@ impl IntoDiagnosticArg for Backtrace {
|
|||
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()))
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#![doc(rust_logo)]
|
||||
#![feature(rustdoc_internals)]
|
||||
#![feature(array_windows)]
|
||||
#![feature(associated_type_defaults)]
|
||||
#![feature(extract_if)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(let_chains)]
|
||||
|
@ -401,7 +402,7 @@ pub use diagnostic::{
|
|||
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
|
||||
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
|
||||
};
|
||||
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
|
||||
pub use diagnostic_builder::{BugAbort, DiagnosticBuilder, EmissionGuarantee, FatalAbort};
|
||||
pub use diagnostic_impls::{
|
||||
DiagnosticArgFromDisplay, DiagnosticSymbolList, ExpectedLifetimeParameter,
|
||||
IndicateAnonymousLifetime, InvalidFlushedDelayedDiagnosticLevel, LabelKind,
|
||||
|
@ -722,21 +723,6 @@ impl DiagCtxt {
|
|||
self.inner.borrow_mut().emit_stashed_diagnostics()
|
||||
}
|
||||
|
||||
/// Construct a builder with the `msg` at the level appropriate for the
|
||||
/// specific `EmissionGuarantee`.
|
||||
///
|
||||
/// Note: this is necessary for `derive(Diagnostic)`, but shouldn't be used
|
||||
/// outside of that. Instead use `struct_err`, `struct_warn`, etc., which
|
||||
/// make the diagnostic kind clearer.
|
||||
#[rustc_lint_diagnostics]
|
||||
#[track_caller]
|
||||
pub fn struct_diagnostic<G: EmissionGuarantee>(
|
||||
&self,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, G> {
|
||||
G::make_diagnostic_builder(self, msg)
|
||||
}
|
||||
|
||||
/// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
|
||||
///
|
||||
/// Attempting to `.emit()` the builder will only emit if either:
|
||||
|
@ -922,7 +908,7 @@ impl DiagCtxt {
|
|||
&self,
|
||||
span: impl Into<MultiSpan>,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, !> {
|
||||
) -> DiagnosticBuilder<'_, FatalAbort> {
|
||||
let mut result = self.struct_fatal(msg);
|
||||
result.set_span(span);
|
||||
result
|
||||
|
@ -936,7 +922,7 @@ impl DiagCtxt {
|
|||
span: impl Into<MultiSpan>,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
code: DiagnosticId,
|
||||
) -> DiagnosticBuilder<'_, !> {
|
||||
) -> DiagnosticBuilder<'_, FatalAbort> {
|
||||
let mut result = self.struct_span_fatal(span, msg);
|
||||
result.code(code);
|
||||
result
|
||||
|
@ -945,7 +931,10 @@ impl DiagCtxt {
|
|||
/// Construct a builder at the `Fatal` level with the `msg`.
|
||||
#[rustc_lint_diagnostics]
|
||||
#[track_caller]
|
||||
pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
|
||||
pub fn struct_fatal(
|
||||
&self,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, FatalAbort> {
|
||||
DiagnosticBuilder::new(self, Level::Fatal, msg)
|
||||
}
|
||||
|
||||
|
@ -972,6 +961,26 @@ impl DiagCtxt {
|
|||
DiagnosticBuilder::new(self, Level::Note, msg)
|
||||
}
|
||||
|
||||
/// Construct a builder at the `Bug` level with the `msg`.
|
||||
#[rustc_lint_diagnostics]
|
||||
#[track_caller]
|
||||
pub fn struct_bug(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, BugAbort> {
|
||||
DiagnosticBuilder::new(self, Level::Bug, msg)
|
||||
}
|
||||
|
||||
/// Construct a builder at the `Bug` level at the given `span` with the `msg`.
|
||||
#[rustc_lint_diagnostics]
|
||||
#[track_caller]
|
||||
pub fn struct_span_bug(
|
||||
&self,
|
||||
span: impl Into<MultiSpan>,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, BugAbort> {
|
||||
let mut result = self.struct_bug(msg);
|
||||
result.set_span(span);
|
||||
result
|
||||
}
|
||||
|
||||
#[rustc_lint_diagnostics]
|
||||
#[track_caller]
|
||||
pub fn span_fatal(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
|
||||
|
@ -1070,13 +1079,6 @@ impl DiagCtxt {
|
|||
inner.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn span_bug_no_panic(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) {
|
||||
let mut diag = Diagnostic::new(Bug, msg);
|
||||
diag.set_span(span);
|
||||
self.emit_diagnostic(diag);
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[rustc_lint_diagnostics]
|
||||
pub fn span_note(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) {
|
||||
|
@ -1115,9 +1117,9 @@ impl DiagCtxt {
|
|||
self.struct_note(msg).emit()
|
||||
}
|
||||
|
||||
#[rustc_lint_diagnostics]
|
||||
pub fn bug(&self, msg: impl Into<DiagnosticMessage>) -> ! {
|
||||
DiagnosticBuilder::<diagnostic_builder::Bug>::new(self, Bug, msg).emit();
|
||||
panic::panic_any(ExplicitBug);
|
||||
self.struct_bug(msg).emit()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1274,18 +1276,19 @@ impl DiagCtxt {
|
|||
self.create_err(err).emit()
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
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, ()>) {
|
||||
|
@ -1296,7 +1299,7 @@ impl DiagCtxt {
|
|||
&'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>(
|
||||
|
@ -1308,38 +1311,35 @@ impl DiagCtxt {
|
|||
|
||||
pub fn create_fatal<'a>(
|
||||
&'a self,
|
||||
fatal: impl IntoDiagnostic<'a, !>,
|
||||
) -> DiagnosticBuilder<'a, !> {
|
||||
fatal.into_diagnostic(self)
|
||||
fatal: impl IntoDiagnostic<'a, FatalAbort>,
|
||||
) -> DiagnosticBuilder<'a, FatalAbort> {
|
||||
fatal.into_diagnostic(self, Level::Fatal)
|
||||
}
|
||||
|
||||
pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, !>) -> ! {
|
||||
pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, FatalAbort>) -> ! {
|
||||
self.create_fatal(fatal).emit()
|
||||
}
|
||||
|
||||
pub fn create_bug<'a>(
|
||||
&'a self,
|
||||
bug: impl IntoDiagnostic<'a, diagnostic_builder::Bug>,
|
||||
) -> DiagnosticBuilder<'a, diagnostic_builder::Bug> {
|
||||
bug.into_diagnostic(self)
|
||||
bug: impl IntoDiagnostic<'a, BugAbort>,
|
||||
) -> DiagnosticBuilder<'a, BugAbort> {
|
||||
bug.into_diagnostic(self, Level::Bug)
|
||||
}
|
||||
|
||||
pub fn emit_bug<'a>(
|
||||
&'a self,
|
||||
bug: impl IntoDiagnostic<'a, diagnostic_builder::Bug>,
|
||||
) -> diagnostic_builder::Bug {
|
||||
pub fn emit_bug<'a>(&'a self, bug: impl IntoDiagnostic<'a, BugAbort>) -> ! {
|
||||
self.create_bug(bug).emit()
|
||||
}
|
||||
|
||||
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
|
||||
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, ()>) {
|
||||
self.create_note(note).emit()
|
||||
}
|
||||
|
||||
pub fn create_note<'a>(
|
||||
&'a self,
|
||||
note: impl IntoDiagnostic<'a, Noted>,
|
||||
) -> DiagnosticBuilder<'a, Noted> {
|
||||
note.into_diagnostic(self)
|
||||
note: impl IntoDiagnostic<'a, ()>,
|
||||
) -> DiagnosticBuilder<'a, ()> {
|
||||
note.into_diagnostic(self, Level::Note)
|
||||
}
|
||||
|
||||
pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
|
||||
|
|
|
@ -1159,6 +1159,7 @@ impl<'a> ExtCtxt<'a> {
|
|||
// Fixme: does this result in errors?
|
||||
self.expansions.clear();
|
||||
}
|
||||
#[rustc_lint_diagnostics]
|
||||
pub fn bug(&self, msg: &'static str) -> ! {
|
||||
self.sess.dcx().bug(msg);
|
||||
}
|
||||
|
@ -1204,11 +1205,10 @@ pub fn resolve_path(
|
|||
.expect("attempting to resolve a file path in an external file"),
|
||||
FileName::DocTest(path, _) => path,
|
||||
other => {
|
||||
return Err(errors::ResolveRelativePath {
|
||||
return Err(parse_sess.dcx.create_err(errors::ResolveRelativePath {
|
||||
span,
|
||||
path: parse_sess.source_map().filename_for_diagnostics(&other).to_string(),
|
||||
}
|
||||
.into_diagnostic(&parse_sess.dcx));
|
||||
}));
|
||||
}
|
||||
};
|
||||
result.pop();
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -722,7 +722,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if let [segment] = path.segments
|
||||
&& segment.ident.name == sym::rust
|
||||
{
|
||||
fatally_break_rust(self.tcx);
|
||||
fatally_break_rust(self.tcx, expr.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ use crate::expectation::Expectation;
|
|||
use crate::fn_ctxt::RawTy;
|
||||
use crate::gather_locals::GatherLocalsVisitor;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::{struct_span_err, DiagnosticId, ErrorGuaranteed, MultiSpan};
|
||||
use rustc_errors::{struct_span_err, DiagnosticId, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
|
@ -412,24 +412,25 @@ enum TupleArgumentsFlag {
|
|||
TupleArguments,
|
||||
}
|
||||
|
||||
fn fatally_break_rust(tcx: TyCtxt<'_>) {
|
||||
fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! {
|
||||
let dcx = tcx.sess.dcx();
|
||||
dcx.span_bug_no_panic(
|
||||
MultiSpan::new(),
|
||||
let mut diag = dcx.struct_span_bug(
|
||||
span,
|
||||
"It looks like you're trying to break rust; would you like some ICE?",
|
||||
);
|
||||
dcx.note("the compiler expectedly panicked. this is a feature.");
|
||||
dcx.note(
|
||||
diag.note("the compiler expectedly panicked. this is a feature.");
|
||||
diag.note(
|
||||
"we would appreciate a joke overview: \
|
||||
https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
|
||||
);
|
||||
dcx.note(format!("rustc {} running on {}", tcx.sess.cfg_version, config::host_triple(),));
|
||||
diag.note(format!("rustc {} running on {}", tcx.sess.cfg_version, config::host_triple(),));
|
||||
if let Some((flags, excluded_cargo_defaults)) = rustc_session::utils::extra_compiler_flags() {
|
||||
dcx.note(format!("compiler flags: {}", flags.join(" ")));
|
||||
diag.note(format!("compiler flags: {}", flags.join(" ")));
|
||||
if excluded_cargo_defaults {
|
||||
dcx.note("some of the compiler flags provided by cargo are hidden");
|
||||
diag.note("some of the compiler flags provided by cargo are hidden");
|
||||
}
|
||||
}
|
||||
diag.emit()
|
||||
}
|
||||
|
||||
/// `expected` here is the expected number of explicit generic arguments on the trait.
|
||||
|
|
|
@ -5,7 +5,6 @@ use crate::errors::{
|
|||
use crate::infer::error_reporting::TypeErrCtxt;
|
||||
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use crate::infer::InferCtxt;
|
||||
use rustc_errors::IntoDiagnostic;
|
||||
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
|
@ -367,7 +366,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
let multi_suggestions = Vec::new();
|
||||
let bad_label = Some(arg_data.make_bad_error(span));
|
||||
match error_code {
|
||||
TypeAnnotationNeeded::E0282 => AnnotationRequired {
|
||||
TypeAnnotationNeeded::E0282 => self.tcx.sess.dcx().create_err(AnnotationRequired {
|
||||
span,
|
||||
source_kind,
|
||||
source_name,
|
||||
|
@ -375,9 +374,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label,
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx()),
|
||||
TypeAnnotationNeeded::E0283 => AmbiguousImpl {
|
||||
}),
|
||||
TypeAnnotationNeeded::E0283 => self.tcx.sess.dcx().create_err(AmbiguousImpl {
|
||||
span,
|
||||
source_kind,
|
||||
source_name,
|
||||
|
@ -385,9 +383,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label,
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx()),
|
||||
TypeAnnotationNeeded::E0284 => AmbiguousReturn {
|
||||
}),
|
||||
TypeAnnotationNeeded::E0284 => self.tcx.sess.dcx().create_err(AmbiguousReturn {
|
||||
span,
|
||||
source_kind,
|
||||
source_name,
|
||||
|
@ -395,8 +392,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label,
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx()),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -574,7 +570,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
match error_code {
|
||||
TypeAnnotationNeeded::E0282 => AnnotationRequired {
|
||||
TypeAnnotationNeeded::E0282 => self.tcx.sess.dcx().create_err(AnnotationRequired {
|
||||
span,
|
||||
source_kind,
|
||||
source_name: &name,
|
||||
|
@ -582,9 +578,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label: None,
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx()),
|
||||
TypeAnnotationNeeded::E0283 => AmbiguousImpl {
|
||||
}),
|
||||
TypeAnnotationNeeded::E0283 => self.tcx.sess.dcx().create_err(AmbiguousImpl {
|
||||
span,
|
||||
source_kind,
|
||||
source_name: &name,
|
||||
|
@ -592,9 +587,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label: None,
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx()),
|
||||
TypeAnnotationNeeded::E0284 => AmbiguousReturn {
|
||||
}),
|
||||
TypeAnnotationNeeded::E0284 => self.tcx.sess.dcx().create_err(AmbiguousReturn {
|
||||
span,
|
||||
source_kind,
|
||||
source_name: &name,
|
||||
|
@ -602,8 +596,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label: None,
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx()),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,7 @@ use crate::errors::{
|
|||
use crate::fluent_generated as fluent;
|
||||
use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt};
|
||||
use crate::infer::{self, SubregionOrigin};
|
||||
use rustc_errors::{
|
||||
AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
|
||||
};
|
||||
use rustc_errors::{AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::traits::ObligationCauseCode;
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
|
@ -136,11 +134,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
note_and_explain::PrefixKind::ContentValidFor,
|
||||
note_and_explain::SuffixKind::Empty,
|
||||
);
|
||||
OutlivesContent {
|
||||
self.tcx.sess.dcx().create_err(OutlivesContent {
|
||||
span,
|
||||
notes: reference_valid.into_iter().chain(content_valid).collect(),
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx())
|
||||
})
|
||||
}
|
||||
infer::RelateObjectBound(span) => {
|
||||
let object_valid = note_and_explain::RegionExplanation::new(
|
||||
|
@ -157,11 +154,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
note_and_explain::PrefixKind::SourcePointerValidFor,
|
||||
note_and_explain::SuffixKind::Empty,
|
||||
);
|
||||
OutlivesBound {
|
||||
self.tcx.sess.dcx().create_err(OutlivesBound {
|
||||
span,
|
||||
notes: object_valid.into_iter().chain(pointer_valid).collect(),
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx())
|
||||
})
|
||||
}
|
||||
infer::RelateParamBound(span, ty, opt_span) => {
|
||||
let prefix = match *sub {
|
||||
|
@ -176,8 +172,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
let note = note_and_explain::RegionExplanation::new(
|
||||
self.tcx, sub, opt_span, prefix, suffix,
|
||||
);
|
||||
FulfillReqLifetime { span, ty: self.resolve_vars_if_possible(ty), note }
|
||||
.into_diagnostic(self.tcx.sess.dcx())
|
||||
self.tcx.sess.dcx().create_err(FulfillReqLifetime {
|
||||
span,
|
||||
ty: self.resolve_vars_if_possible(ty),
|
||||
note,
|
||||
})
|
||||
}
|
||||
infer::RelateRegionParamBound(span) => {
|
||||
let param_instantiated = note_and_explain::RegionExplanation::new(
|
||||
|
@ -194,11 +193,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
note_and_explain::PrefixKind::LfParamMustOutlive,
|
||||
note_and_explain::SuffixKind::Empty,
|
||||
);
|
||||
LfBoundNotSatisfied {
|
||||
self.tcx.sess.dcx().create_err(LfBoundNotSatisfied {
|
||||
span,
|
||||
notes: param_instantiated.into_iter().chain(param_must_outlive).collect(),
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx())
|
||||
})
|
||||
}
|
||||
infer::ReferenceOutlivesReferent(ty, span) => {
|
||||
let pointer_valid = note_and_explain::RegionExplanation::new(
|
||||
|
@ -215,12 +213,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
note_and_explain::PrefixKind::DataValidFor,
|
||||
note_and_explain::SuffixKind::Empty,
|
||||
);
|
||||
RefLongerThanData {
|
||||
self.tcx.sess.dcx().create_err(RefLongerThanData {
|
||||
span,
|
||||
ty: self.resolve_vars_if_possible(ty),
|
||||
notes: pointer_valid.into_iter().chain(data_valid).collect(),
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx())
|
||||
})
|
||||
}
|
||||
infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => {
|
||||
let mut err = self.report_extra_impl_obligation(
|
||||
|
@ -277,11 +274,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
note_and_explain::PrefixKind::LfMustOutlive,
|
||||
note_and_explain::SuffixKind::Empty,
|
||||
);
|
||||
LfBoundNotSatisfied {
|
||||
self.tcx.sess.dcx().create_err(LfBoundNotSatisfied {
|
||||
span,
|
||||
notes: instantiated.into_iter().chain(must_outlive).collect(),
|
||||
}
|
||||
.into_diagnostic(self.tcx.sess.dcx())
|
||||
})
|
||||
}
|
||||
};
|
||||
if sub.is_error() || sup.is_error() {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::cell::RefCell;
|
||||
|
||||
use crate::diagnostics::diagnostic_builder::{DiagnosticDeriveBuilder, DiagnosticDeriveKind};
|
||||
use crate::diagnostics::diagnostic_builder::DiagnosticDeriveKind;
|
||||
use crate::diagnostics::error::{span_err, DiagnosticDeriveError};
|
||||
use crate::diagnostics::utils::SetOnce;
|
||||
use proc_macro2::TokenStream;
|
||||
|
@ -13,32 +13,21 @@ use synstructure::Structure;
|
|||
/// The central struct for constructing the `into_diagnostic` method from an annotated struct.
|
||||
pub(crate) struct DiagnosticDerive<'a> {
|
||||
structure: Structure<'a>,
|
||||
builder: DiagnosticDeriveBuilder,
|
||||
}
|
||||
|
||||
impl<'a> DiagnosticDerive<'a> {
|
||||
pub(crate) fn new(diag: syn::Ident, dcx: syn::Ident, structure: Structure<'a>) -> Self {
|
||||
Self {
|
||||
builder: DiagnosticDeriveBuilder {
|
||||
diag,
|
||||
kind: DiagnosticDeriveKind::Diagnostic { dcx },
|
||||
},
|
||||
structure,
|
||||
}
|
||||
pub(crate) fn new(structure: Structure<'a>) -> Self {
|
||||
Self { structure }
|
||||
}
|
||||
|
||||
pub(crate) fn into_tokens(self) -> TokenStream {
|
||||
let DiagnosticDerive { mut structure, mut builder } = self;
|
||||
|
||||
let DiagnosticDerive { mut structure } = self;
|
||||
let kind = DiagnosticDeriveKind::Diagnostic;
|
||||
let slugs = RefCell::new(Vec::new());
|
||||
let implementation = builder.each_variant(&mut structure, |mut builder, variant| {
|
||||
let implementation = kind.each_variant(&mut structure, |mut builder, variant| {
|
||||
let preamble = builder.preamble(variant);
|
||||
let body = builder.body(variant);
|
||||
|
||||
let diag = &builder.parent.diag;
|
||||
let DiagnosticDeriveKind::Diagnostic { dcx } = &builder.parent.kind else {
|
||||
unreachable!()
|
||||
};
|
||||
let init = match builder.slug.value_ref() {
|
||||
None => {
|
||||
span_err(builder.span, "diagnostic slug not specified")
|
||||
|
@ -62,7 +51,11 @@ impl<'a> DiagnosticDerive<'a> {
|
|||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -73,12 +66,10 @@ impl<'a> DiagnosticDerive<'a> {
|
|||
#formatting_init
|
||||
#preamble
|
||||
#body
|
||||
#diag
|
||||
diag
|
||||
}
|
||||
});
|
||||
|
||||
let DiagnosticDeriveKind::Diagnostic { dcx } = &builder.kind else { unreachable!() };
|
||||
|
||||
// A lifetime of `'a` causes conflicts, but `_sess` is fine.
|
||||
let mut imp = structure.gen_impl(quote! {
|
||||
gen impl<'_sess, G>
|
||||
|
@ -90,9 +81,9 @@ impl<'a> DiagnosticDerive<'a> {
|
|||
#[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> {
|
||||
use rustc_errors::IntoDiagnosticArg;
|
||||
#implementation
|
||||
}
|
||||
}
|
||||
|
@ -107,36 +98,31 @@ impl<'a> DiagnosticDerive<'a> {
|
|||
/// The central struct for constructing the `decorate_lint` method from an annotated struct.
|
||||
pub(crate) struct LintDiagnosticDerive<'a> {
|
||||
structure: Structure<'a>,
|
||||
builder: DiagnosticDeriveBuilder,
|
||||
}
|
||||
|
||||
impl<'a> LintDiagnosticDerive<'a> {
|
||||
pub(crate) fn new(diag: syn::Ident, structure: Structure<'a>) -> Self {
|
||||
Self {
|
||||
builder: DiagnosticDeriveBuilder { diag, kind: DiagnosticDeriveKind::LintDiagnostic },
|
||||
structure,
|
||||
}
|
||||
pub(crate) fn new(structure: Structure<'a>) -> Self {
|
||||
Self { structure }
|
||||
}
|
||||
|
||||
pub(crate) fn into_tokens(self) -> TokenStream {
|
||||
let LintDiagnosticDerive { mut structure, mut builder } = self;
|
||||
|
||||
let implementation = builder.each_variant(&mut structure, |mut builder, variant| {
|
||||
let LintDiagnosticDerive { mut structure } = self;
|
||||
let kind = DiagnosticDeriveKind::LintDiagnostic;
|
||||
let implementation = kind.each_variant(&mut structure, |mut builder, variant| {
|
||||
let preamble = builder.preamble(variant);
|
||||
let body = builder.body(variant);
|
||||
|
||||
let diag = &builder.parent.diag;
|
||||
let formatting_init = &builder.formatting_init;
|
||||
quote! {
|
||||
#preamble
|
||||
#formatting_init
|
||||
#body
|
||||
#diag
|
||||
diag
|
||||
}
|
||||
});
|
||||
|
||||
let slugs = RefCell::new(Vec::new());
|
||||
let msg = builder.each_variant(&mut structure, |mut builder, variant| {
|
||||
let msg = kind.each_variant(&mut structure, |mut builder, variant| {
|
||||
// Collect the slug by generating the preamble.
|
||||
let _ = builder.preamble(variant);
|
||||
|
||||
|
@ -169,15 +155,13 @@ impl<'a> LintDiagnosticDerive<'a> {
|
|||
}
|
||||
});
|
||||
|
||||
let diag = &builder.diag;
|
||||
let mut imp = structure.gen_impl(quote! {
|
||||
gen impl<'__a> rustc_errors::DecorateLint<'__a, ()> for @Self {
|
||||
#[track_caller]
|
||||
fn decorate_lint<'__b>(
|
||||
self,
|
||||
#diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()>
|
||||
diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()>
|
||||
) {
|
||||
use rustc_errors::IntoDiagnosticArg;
|
||||
#implementation;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,28 +17,18 @@ use synstructure::{BindingInfo, Structure, VariantInfo};
|
|||
use super::utils::SubdiagnosticVariant;
|
||||
|
||||
/// What kind of diagnostic is being derived - a fatal/error/warning or a lint?
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub(crate) enum DiagnosticDeriveKind {
|
||||
Diagnostic { dcx: syn::Ident },
|
||||
Diagnostic,
|
||||
LintDiagnostic,
|
||||
}
|
||||
|
||||
/// Tracks persistent information required for the entire type when building up individual calls to
|
||||
/// diagnostic methods for generated diagnostic derives - both `Diagnostic` for
|
||||
/// fatal/errors/warnings and `LintDiagnostic` for lints.
|
||||
pub(crate) struct DiagnosticDeriveBuilder {
|
||||
/// The identifier to use for the generated `DiagnosticBuilder` instance.
|
||||
pub diag: syn::Ident,
|
||||
/// Kind of diagnostic that should be derived.
|
||||
pub kind: DiagnosticDeriveKind,
|
||||
}
|
||||
|
||||
/// Tracks persistent information required for a specific variant when building up individual calls
|
||||
/// to diagnostic methods for generated diagnostic derives - both `Diagnostic` for
|
||||
/// fatal/errors/warnings and `LintDiagnostic` for lints.
|
||||
pub(crate) struct DiagnosticDeriveVariantBuilder<'parent> {
|
||||
/// The parent builder for the entire type.
|
||||
pub parent: &'parent DiagnosticDeriveBuilder,
|
||||
pub(crate) struct DiagnosticDeriveVariantBuilder {
|
||||
/// The kind for the entire type.
|
||||
pub kind: DiagnosticDeriveKind,
|
||||
|
||||
/// Initialization of format strings for code suggestions.
|
||||
pub formatting_init: TokenStream,
|
||||
|
@ -59,19 +49,19 @@ pub(crate) struct DiagnosticDeriveVariantBuilder<'parent> {
|
|||
pub code: SpannedOption<()>,
|
||||
}
|
||||
|
||||
impl<'a> HasFieldMap for DiagnosticDeriveVariantBuilder<'a> {
|
||||
impl HasFieldMap for DiagnosticDeriveVariantBuilder {
|
||||
fn get_field_binding(&self, field: &String) -> Option<&TokenStream> {
|
||||
self.field_map.get(field)
|
||||
}
|
||||
}
|
||||
|
||||
impl DiagnosticDeriveBuilder {
|
||||
impl DiagnosticDeriveKind {
|
||||
/// Call `f` for the struct or for each variant of the enum, returning a `TokenStream` with the
|
||||
/// tokens from `f` wrapped in an `match` expression. Emits errors for use of derive on unions
|
||||
/// or attributes on the type itself when input is an enum.
|
||||
pub(crate) fn each_variant<'s, F>(&mut self, structure: &mut Structure<'s>, f: F) -> TokenStream
|
||||
pub(crate) fn each_variant<'s, F>(self, structure: &mut Structure<'s>, f: F) -> TokenStream
|
||||
where
|
||||
F: for<'a, 'v> Fn(DiagnosticDeriveVariantBuilder<'a>, &VariantInfo<'v>) -> TokenStream,
|
||||
F: for<'v> Fn(DiagnosticDeriveVariantBuilder, &VariantInfo<'v>) -> TokenStream,
|
||||
{
|
||||
let ast = structure.ast();
|
||||
let span = ast.span().unwrap();
|
||||
|
@ -101,7 +91,7 @@ impl DiagnosticDeriveBuilder {
|
|||
_ => variant.ast().ident.span().unwrap(),
|
||||
};
|
||||
let builder = DiagnosticDeriveVariantBuilder {
|
||||
parent: self,
|
||||
kind: self,
|
||||
span,
|
||||
field_map: build_field_mapping(variant),
|
||||
formatting_init: TokenStream::new(),
|
||||
|
@ -119,7 +109,7 @@ impl DiagnosticDeriveBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
||||
impl DiagnosticDeriveVariantBuilder {
|
||||
/// Generates calls to `code` and similar functions based on the attributes on the type or
|
||||
/// variant.
|
||||
pub(crate) fn preamble(&mut self, variant: &VariantInfo<'_>) -> TokenStream {
|
||||
|
@ -184,8 +174,6 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
&mut self,
|
||||
attr: &Attribute,
|
||||
) -> Result<TokenStream, DiagnosticDeriveError> {
|
||||
let diag = &self.parent.diag;
|
||||
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
return Ok(quote! {});
|
||||
|
@ -223,7 +211,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
|
||||
let code = nested.parse::<syn::LitStr>()?;
|
||||
tokens.extend(quote! {
|
||||
#diag.code(rustc_errors::DiagnosticId::Error(#code.to_string()));
|
||||
diag.code(rustc_errors::DiagnosticId::Error(#code.to_string()));
|
||||
});
|
||||
} else {
|
||||
span_err(path.span().unwrap(), "unknown argument")
|
||||
|
@ -257,8 +245,6 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
}
|
||||
|
||||
fn generate_field_code(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream {
|
||||
let diag = &self.parent.diag;
|
||||
|
||||
let field = binding_info.ast();
|
||||
let mut field_binding = binding_info.binding.clone();
|
||||
field_binding.set_span(field.ty.span());
|
||||
|
@ -267,7 +253,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
let ident = format_ident!("{}", ident); // strip `r#` prefix, if present
|
||||
|
||||
quote! {
|
||||
#diag.set_arg(
|
||||
diag.set_arg(
|
||||
stringify!(#ident),
|
||||
#field_binding
|
||||
);
|
||||
|
@ -322,8 +308,6 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
info: FieldInfo<'_>,
|
||||
binding: TokenStream,
|
||||
) -> Result<TokenStream, DiagnosticDeriveError> {
|
||||
let diag = &self.parent.diag;
|
||||
|
||||
let ident = &attr.path().segments.last().unwrap().ident;
|
||||
let name = ident.to_string();
|
||||
match (&attr.meta, name.as_str()) {
|
||||
|
@ -331,12 +315,12 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
// `set_arg` call will not be generated.
|
||||
(Meta::Path(_), "skip_arg") => return Ok(quote! {}),
|
||||
(Meta::Path(_), "primary_span") => {
|
||||
match self.parent.kind {
|
||||
DiagnosticDeriveKind::Diagnostic { .. } => {
|
||||
match self.kind {
|
||||
DiagnosticDeriveKind::Diagnostic => {
|
||||
report_error_if_not_applied_to_span(attr, &info)?;
|
||||
|
||||
return Ok(quote! {
|
||||
#diag.set_span(#binding);
|
||||
diag.set_span(#binding);
|
||||
});
|
||||
}
|
||||
DiagnosticDeriveKind::LintDiagnostic => {
|
||||
|
@ -348,13 +332,13 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
}
|
||||
(Meta::Path(_), "subdiagnostic") => {
|
||||
if FieldInnerTy::from_type(&info.binding.ast().ty).will_iterate() {
|
||||
let DiagnosticDeriveKind::Diagnostic { dcx } = &self.parent.kind else {
|
||||
let DiagnosticDeriveKind::Diagnostic = self.kind else {
|
||||
// No eager translation for lints.
|
||||
return Ok(quote! { #diag.subdiagnostic(#binding); });
|
||||
return Ok(quote! { diag.subdiagnostic(#binding); });
|
||||
};
|
||||
return Ok(quote! { #diag.eager_subdiagnostic(#dcx, #binding); });
|
||||
return Ok(quote! { diag.eager_subdiagnostic(dcx, #binding); });
|
||||
} else {
|
||||
return Ok(quote! { #diag.subdiagnostic(#binding); });
|
||||
return Ok(quote! { diag.subdiagnostic(#binding); });
|
||||
}
|
||||
}
|
||||
(Meta::List(meta_list), "subdiagnostic") => {
|
||||
|
@ -376,15 +360,15 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
return Ok(quote! {});
|
||||
}
|
||||
|
||||
let dcx = match &self.parent.kind {
|
||||
DiagnosticDeriveKind::Diagnostic { dcx } => dcx,
|
||||
match &self.kind {
|
||||
DiagnosticDeriveKind::Diagnostic => {}
|
||||
DiagnosticDeriveKind::LintDiagnostic => {
|
||||
throw_invalid_attr!(attr, |diag| {
|
||||
diag.help("eager subdiagnostics are not supported on lints")
|
||||
})
|
||||
}
|
||||
};
|
||||
return Ok(quote! { #diag.eager_subdiagnostic(#dcx, #binding); });
|
||||
return Ok(quote! { diag.eager_subdiagnostic(dcx, #binding); });
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
@ -442,7 +426,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
|
||||
self.formatting_init.extend(code_init);
|
||||
Ok(quote! {
|
||||
#diag.span_suggestions_with_style(
|
||||
diag.span_suggestions_with_style(
|
||||
#span_field,
|
||||
crate::fluent_generated::#slug,
|
||||
#code_field,
|
||||
|
@ -463,10 +447,9 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
kind: &Ident,
|
||||
fluent_attr_identifier: Path,
|
||||
) -> TokenStream {
|
||||
let diag = &self.parent.diag;
|
||||
let fn_name = format_ident!("span_{}", kind);
|
||||
quote! {
|
||||
#diag.#fn_name(
|
||||
diag.#fn_name(
|
||||
#field_binding,
|
||||
crate::fluent_generated::#fluent_attr_identifier
|
||||
);
|
||||
|
@ -476,9 +459,8 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
/// Adds a subdiagnostic by generating a `diag.span_$kind` call with the current slug
|
||||
/// and `fluent_attr_identifier`.
|
||||
fn add_subdiagnostic(&self, kind: &Ident, fluent_attr_identifier: Path) -> TokenStream {
|
||||
let diag = &self.parent.diag;
|
||||
quote! {
|
||||
#diag.#kind(crate::fluent_generated::#fluent_attr_identifier);
|
||||
diag.#kind(crate::fluent_generated::#fluent_attr_identifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ mod utils;
|
|||
|
||||
use diagnostic::{DiagnosticDerive, LintDiagnosticDerive};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::format_ident;
|
||||
use subdiagnostic::SubdiagnosticDeriveBuilder;
|
||||
use synstructure::Structure;
|
||||
|
||||
|
@ -57,7 +56,7 @@ use synstructure::Structure;
|
|||
/// See rustc dev guide for more examples on using the `#[derive(Diagnostic)]`:
|
||||
/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html>
|
||||
pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
|
||||
DiagnosticDerive::new(format_ident!("diag"), format_ident!("handler"), s).into_tokens()
|
||||
DiagnosticDerive::new(s).into_tokens()
|
||||
}
|
||||
|
||||
/// Implements `#[derive(LintDiagnostic)]`, which allows for lints to be specified as a struct,
|
||||
|
@ -103,7 +102,7 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
|
|||
/// See rustc dev guide for more examples on using the `#[derive(LintDiagnostic)]`:
|
||||
/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html#reference>
|
||||
pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
|
||||
LintDiagnosticDerive::new(format_ident!("diag"), s).into_tokens()
|
||||
LintDiagnosticDerive::new(s).into_tokens()
|
||||
}
|
||||
|
||||
/// Implements `#[derive(Subdiagnostic)]`, which allows for labels, notes, helps and
|
||||
|
|
|
@ -94,7 +94,6 @@ impl SubdiagnosticDeriveBuilder {
|
|||
rustc_errors::SubdiagnosticMessage
|
||||
) -> rustc_errors::SubdiagnosticMessage,
|
||||
{
|
||||
use rustc_errors::{Applicability, IntoDiagnosticArg};
|
||||
#implementation
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ use std::{
|
|||
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<PathBuf>,
|
||||
}
|
||||
|
||||
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<G: EmissionGuarantee> 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<String>,
|
||||
}
|
||||
|
||||
impl IntoDiagnostic<'_> for InvalidMetadataFiles {
|
||||
impl<G: EmissionGuarantee> 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<G: EmissionGuarantee> 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);
|
||||
|
|
|
@ -5,7 +5,8 @@ use crate::ty::normalize_erasing_regions::NormalizationError;
|
|||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::fluent_generated as fluent;
|
|||
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);
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::borrow::Cow;
|
|||
|
||||
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());
|
||||
|
|
|
@ -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<String>,
|
||||
}
|
||||
|
||||
impl IntoDiagnostic<'_> for UnusedGenericParamsHint {
|
||||
impl<G: EmissionGuarantee> 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,
|
||||
|
|
|
@ -2,7 +2,10 @@ use std::borrow::Cow;
|
|||
|
||||
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<F>(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 {
|
||||
|
|
|
@ -7,7 +7,9 @@ use rustc_ast::ast::{self, AttrStyle};
|
|||
use rustc_ast::token::{self, CommentKind, Delimiter, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::util::unicode::contains_text_flow_control_chars;
|
||||
use rustc_errors::{error_code, Applicability, Diagnostic, DiagnosticBuilder, StashKey};
|
||||
use rustc_errors::{
|
||||
error_code, Applicability, Diagnostic, DiagnosticBuilder, FatalAbort, StashKey,
|
||||
};
|
||||
use rustc_lexer::unescape::{self, EscapeError, Mode};
|
||||
use rustc_lexer::{Base, DocStyle, RawStrError};
|
||||
use rustc_lexer::{Cursor, LiteralKind};
|
||||
|
@ -344,7 +346,7 @@ impl<'a> StringReader<'a> {
|
|||
to_pos: BytePos,
|
||||
m: &str,
|
||||
c: char,
|
||||
) -> DiagnosticBuilder<'a, !> {
|
||||
) -> DiagnosticBuilder<'a, FatalAbort> {
|
||||
self.sess
|
||||
.dcx
|
||||
.struct_span_fatal(self.mk_sp(from_pos, to_pos), format!("{}: {}", m, escaped_char(c)))
|
||||
|
|
|
@ -5,7 +5,7 @@ use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle
|
|||
use rustc_ast as ast;
|
||||
use rustc_ast::attr;
|
||||
use rustc_ast::token::{self, Delimiter, Nonterminal};
|
||||
use rustc_errors::{error_code, Diagnostic, IntoDiagnostic, PResult};
|
||||
use rustc_errors::{error_code, Diagnostic, PResult};
|
||||
use rustc_span::{sym, BytePos, Span};
|
||||
use thin_vec::ThinVec;
|
||||
use tracing::debug;
|
||||
|
@ -416,8 +416,9 @@ impl<'a> Parser<'a> {
|
|||
Err(err) => err.cancel(),
|
||||
}
|
||||
|
||||
Err(InvalidMetaItem { span: self.token.span, token: self.token.clone() }
|
||||
.into_diagnostic(self.dcx()))
|
||||
Err(self
|
||||
.dcx()
|
||||
.create_err(InvalidMetaItem { span: self.token.span, token: self.token.clone() }))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ use rustc_ast_pretty::pprust;
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{
|
||||
pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
|
||||
DiagnosticMessage, ErrorGuaranteed, FatalError, IntoDiagnostic, MultiSpan, PResult,
|
||||
DiagnosticMessage, ErrorGuaranteed, FatalError, MultiSpan, PResult,
|
||||
};
|
||||
use rustc_session::errors::ExprParenthesesNeeded;
|
||||
use rustc_span::source_map::Spanned;
|
||||
|
@ -280,11 +280,10 @@ impl<'a> Parser<'a> {
|
|||
recover: bool,
|
||||
) -> PResult<'a, (Ident, /* is_raw */ bool)> {
|
||||
if let TokenKind::DocComment(..) = self.prev_token.kind {
|
||||
return Err(DocCommentDoesNotDocumentAnything {
|
||||
return Err(self.dcx().create_err(DocCommentDoesNotDocumentAnything {
|
||||
span: self.prev_token.span,
|
||||
missing_comma: None,
|
||||
}
|
||||
.into_diagnostic(self.dcx()));
|
||||
}));
|
||||
}
|
||||
|
||||
let valid_follow = &[
|
||||
|
@ -347,7 +346,7 @@ impl<'a> Parser<'a> {
|
|||
suggest_remove_comma,
|
||||
help_cannot_start_number,
|
||||
};
|
||||
let mut err = err.into_diagnostic(self.dcx());
|
||||
let mut err = self.dcx().create_err(err);
|
||||
|
||||
// if the token we have is a `<`
|
||||
// it *might* be a misplaced generic
|
||||
|
@ -1432,7 +1431,7 @@ impl<'a> Parser<'a> {
|
|||
// Not entirely sure now, but we bubble the error up with the
|
||||
// suggestion.
|
||||
self.restore_snapshot(snapshot);
|
||||
Err(err.into_diagnostic(self.dcx()))
|
||||
Err(self.dcx().create_err(err))
|
||||
}
|
||||
}
|
||||
} else if token::OpenDelim(Delimiter::Parenthesis) == self.token.kind {
|
||||
|
@ -1447,7 +1446,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
// Consume the fn call arguments.
|
||||
match self.consume_fn_args() {
|
||||
Err(()) => Err(err.into_diagnostic(self.dcx())),
|
||||
Err(()) => Err(self.dcx().create_err(err)),
|
||||
Ok(()) => {
|
||||
self.sess.emit_err(err);
|
||||
// FIXME: actually check that the two expressions in the binop are
|
||||
|
@ -1473,7 +1472,7 @@ impl<'a> Parser<'a> {
|
|||
mk_err_expr(self, inner_op.span.to(self.prev_token.span))
|
||||
} else {
|
||||
// These cases cause too many knock-down errors, bail out (#61329).
|
||||
Err(err.into_diagnostic(self.dcx()))
|
||||
Err(self.dcx().create_err(err))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -2561,7 +2560,7 @@ impl<'a> Parser<'a> {
|
|||
Ok(Some(GenericArg::Const(self.parse_const_arg()?)))
|
||||
} else {
|
||||
let after_kw_const = self.token.span;
|
||||
self.recover_const_arg(after_kw_const, err.into_diagnostic(self.dcx())).map(Some)
|
||||
self.recover_const_arg(after_kw_const, self.dcx().create_err(err)).map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2915,11 +2914,10 @@ impl<'a> Parser<'a> {
|
|||
let (a_span, b_span) = (a.span(), b.span());
|
||||
let between_span = a_span.shrink_to_hi().to(b_span.shrink_to_lo());
|
||||
if self.span_to_snippet(between_span).as_deref() == Ok(":: ") {
|
||||
return Err(DoubleColonInBound {
|
||||
return Err(self.dcx().create_err(DoubleColonInBound {
|
||||
span: path.span.shrink_to_hi(),
|
||||
between: between_span,
|
||||
}
|
||||
.into_diagnostic(self.dcx()));
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
|
|||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_errors::{
|
||||
AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
|
||||
PResult, StashKey,
|
||||
AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, PResult,
|
||||
StashKey,
|
||||
};
|
||||
use rustc_macros::Subdiagnostic;
|
||||
use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
|
||||
|
@ -1255,21 +1255,21 @@ impl<'a> Parser<'a> {
|
|||
// that of the open delim in `TokenTreesReader::parse_token_tree`, even if they are different.
|
||||
self.span_to_snippet(close_paren).is_ok_and(|snippet| snippet == ")")
|
||||
{
|
||||
let mut replacement_err = errors::ParenthesesWithStructFields {
|
||||
span,
|
||||
r#type: path,
|
||||
braces_for_struct: errors::BracesForStructLiteral {
|
||||
first: open_paren,
|
||||
second: close_paren,
|
||||
},
|
||||
no_fields_for_fn: errors::NoFieldsForFnCall {
|
||||
fields: fields
|
||||
.into_iter()
|
||||
.map(|field| field.span.until(field.expr.span))
|
||||
.collect(),
|
||||
},
|
||||
}
|
||||
.into_diagnostic(self.dcx());
|
||||
let mut replacement_err =
|
||||
self.dcx().create_err(errors::ParenthesesWithStructFields {
|
||||
span,
|
||||
r#type: path,
|
||||
braces_for_struct: errors::BracesForStructLiteral {
|
||||
first: open_paren,
|
||||
second: close_paren,
|
||||
},
|
||||
no_fields_for_fn: errors::NoFieldsForFnCall {
|
||||
fields: fields
|
||||
.into_iter()
|
||||
.map(|field| field.span.until(field.expr.span))
|
||||
.collect(),
|
||||
},
|
||||
});
|
||||
replacement_err.emit();
|
||||
|
||||
let old_err = mem::replace(err, replacement_err);
|
||||
|
@ -1883,8 +1883,7 @@ impl<'a> Parser<'a> {
|
|||
self.bump(); // `#`
|
||||
|
||||
let Some((ident, false)) = self.token.ident() else {
|
||||
let err =
|
||||
errors::ExpectedBuiltinIdent { span: self.token.span }.into_diagnostic(self.dcx());
|
||||
let err = self.dcx().create_err(errors::ExpectedBuiltinIdent { span: self.token.span });
|
||||
return Err(err);
|
||||
};
|
||||
self.sess.gated_spans.gate(sym::builtin_syntax, ident.span);
|
||||
|
@ -1894,8 +1893,10 @@ impl<'a> Parser<'a> {
|
|||
let ret = if let Some(res) = parse(self, lo, ident)? {
|
||||
Ok(res)
|
||||
} else {
|
||||
let err = errors::UnknownBuiltinConstruct { span: lo.to(ident.span), name: ident.name }
|
||||
.into_diagnostic(self.dcx());
|
||||
let err = self.dcx().create_err(errors::UnknownBuiltinConstruct {
|
||||
span: lo.to(ident.span),
|
||||
name: ident.name,
|
||||
});
|
||||
return Err(err);
|
||||
};
|
||||
self.expect(&TokenKind::CloseDelim(Delimiter::Parenthesis))?;
|
||||
|
@ -1958,8 +1959,9 @@ impl<'a> Parser<'a> {
|
|||
&& let token::NtExpr(e) | token::NtLiteral(e) = &nt.0
|
||||
&& matches!(e.kind, ExprKind::Err)
|
||||
{
|
||||
let mut err = errors::InvalidInterpolatedExpression { span: self.token.span }
|
||||
.into_diagnostic(self.dcx());
|
||||
let mut err = self
|
||||
.dcx()
|
||||
.create_err(errors::InvalidInterpolatedExpression { span: self.token.span });
|
||||
err.downgrade_to_delayed_bug();
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -2168,10 +2170,10 @@ impl<'a> Parser<'a> {
|
|||
.span_to_snippet(snapshot.token.span)
|
||||
.is_ok_and(|snippet| snippet == "]") =>
|
||||
{
|
||||
return Err(errors::MissingSemicolonBeforeArray {
|
||||
return Err(self.dcx().create_err(errors::MissingSemicolonBeforeArray {
|
||||
open_delim: open_delim_span,
|
||||
semicolon: prev_span.shrink_to_hi(),
|
||||
}.into_diagnostic(self.dcx()));
|
||||
}));
|
||||
}
|
||||
Ok(_) => (),
|
||||
Err(err) => err.cancel(),
|
||||
|
@ -2318,8 +2320,9 @@ impl<'a> Parser<'a> {
|
|||
// Check for `move async` and recover
|
||||
if self.check_keyword(kw::Async) {
|
||||
let move_async_span = self.token.span.with_lo(self.prev_token.span.data().lo);
|
||||
Err(errors::AsyncMoveOrderIncorrect { span: move_async_span }
|
||||
.into_diagnostic(self.dcx()))
|
||||
Err(self
|
||||
.dcx()
|
||||
.create_err(errors::AsyncMoveOrderIncorrect { span: move_async_span }))
|
||||
} else {
|
||||
Ok(CaptureBy::Value { move_kw: move_kw_span })
|
||||
}
|
||||
|
@ -2509,7 +2512,7 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
if self.prev_token.kind == token::BinOp(token::Or) {
|
||||
// This was part of a closure, the that part of the parser recover.
|
||||
return Err(err.into_diagnostic(self.dcx()));
|
||||
return Err(self.dcx().create_err(err));
|
||||
} else {
|
||||
Some(self.sess.emit_err(err))
|
||||
}
|
||||
|
@ -3193,7 +3196,7 @@ impl<'a> Parser<'a> {
|
|||
fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P<Expr>> {
|
||||
let (attrs, body) = self.parse_inner_attrs_and_block()?;
|
||||
if self.eat_keyword(kw::Catch) {
|
||||
Err(errors::CatchAfterTry { span: self.prev_token.span }.into_diagnostic(self.dcx()))
|
||||
Err(self.dcx().create_err(errors::CatchAfterTry { span: self.prev_token.span }))
|
||||
} else {
|
||||
let span = span_lo.to(body.span);
|
||||
self.sess.gated_spans.gate(sym::try_blocks, span);
|
||||
|
@ -3530,12 +3533,11 @@ impl<'a> Parser<'a> {
|
|||
|| t == &token::CloseDelim(Delimiter::Parenthesis)
|
||||
});
|
||||
if is_wrong {
|
||||
return Err(errors::ExpectedStructField {
|
||||
return Err(this.dcx().create_err(errors::ExpectedStructField {
|
||||
span: this.look_ahead(1, |t| t.span),
|
||||
ident_span: this.token.span,
|
||||
token: this.look_ahead(1, |t| t.clone()),
|
||||
}
|
||||
.into_diagnostic(&self.sess.dcx));
|
||||
}));
|
||||
}
|
||||
let (ident, expr) = if is_shorthand {
|
||||
// Mimic `x: x` for the `x` field shorthand.
|
||||
|
|
|
@ -10,10 +10,7 @@ use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
|
|||
use rustc_ast::util::case::Case;
|
||||
use rustc_ast::{self as ast};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{
|
||||
struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult,
|
||||
StashKey,
|
||||
};
|
||||
use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
|
||||
use rustc_span::edit_distance::edit_distance;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map;
|
||||
|
@ -438,7 +435,7 @@ impl<'a> Parser<'a> {
|
|||
None
|
||||
};
|
||||
|
||||
if let Some(err) = err { Err(err.into_diagnostic(self.dcx())) } else { Ok(()) }
|
||||
if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) }
|
||||
}
|
||||
|
||||
fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> {
|
||||
|
@ -1373,8 +1370,7 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
|
||||
let span = self.prev_token.span.shrink_to_hi();
|
||||
let err: DiagnosticBuilder<'_, ErrorGuaranteed> =
|
||||
errors::MissingConstType { span, colon, kind }.into_diagnostic(self.dcx());
|
||||
let err = self.dcx().create_err(errors::MissingConstType { span, colon, kind });
|
||||
err.stash(span, StashKey::ItemNoType);
|
||||
|
||||
// The user intended that the type be inferred,
|
||||
|
@ -1391,7 +1387,7 @@ impl<'a> Parser<'a> {
|
|||
self.bump();
|
||||
self.sess.emit_err(err);
|
||||
} else {
|
||||
return Err(err.into_diagnostic(self.dcx()));
|
||||
return Err(self.dcx().create_err(err));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1591,7 +1587,7 @@ impl<'a> Parser<'a> {
|
|||
} else {
|
||||
let err =
|
||||
errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token.clone());
|
||||
return Err(err.into_diagnostic(self.dcx()));
|
||||
return Err(self.dcx().create_err(err));
|
||||
};
|
||||
|
||||
Ok((class_name, ItemKind::Struct(vdata, generics)))
|
||||
|
@ -1787,7 +1783,7 @@ impl<'a> Parser<'a> {
|
|||
let sp = previous_span.shrink_to_hi();
|
||||
err.missing_comma = Some(sp);
|
||||
}
|
||||
return Err(err.into_diagnostic(self.dcx()));
|
||||
return Err(self.dcx().create_err(err));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -32,9 +32,7 @@ use rustc_ast::{HasAttrs, HasTokens, Unsafe, Visibility, VisibilityKind};
|
|||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::PResult;
|
||||
use rustc_errors::{
|
||||
Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, IntoDiagnostic, MultiSpan,
|
||||
};
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, MultiSpan};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
@ -1500,14 +1498,13 @@ pub(crate) fn make_unclosed_delims_error(
|
|||
if let Some(sp) = unmatched.unclosed_span {
|
||||
spans.push(sp);
|
||||
};
|
||||
let err = MismatchedClosingDelimiter {
|
||||
let err = sess.dcx.create_err(MismatchedClosingDelimiter {
|
||||
spans,
|
||||
delimiter: pprust::token_kind_to_string(&token::CloseDelim(found_delim)).to_string(),
|
||||
unmatched: unmatched.found_span,
|
||||
opening_candidate: unmatched.candidate_span,
|
||||
unclosed: unmatched.unclosed_span,
|
||||
}
|
||||
.into_diagnostic(&sess.dcx);
|
||||
});
|
||||
Some(err)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::token::{self, Delimiter, Nonterminal::*, NonterminalKind, Token};
|
||||
use rustc_ast::HasTokens;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::IntoDiagnostic;
|
||||
use rustc_errors::PResult;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
|
||||
|
@ -114,9 +113,9 @@ impl<'a> Parser<'a> {
|
|||
NonterminalKind::Item => match self.parse_item(ForceCollect::Yes)? {
|
||||
Some(item) => NtItem(item),
|
||||
None => {
|
||||
return Err(
|
||||
UnexpectedNonterminal::Item(self.token.span).into_diagnostic(self.dcx())
|
||||
);
|
||||
return Err(self
|
||||
.dcx()
|
||||
.create_err(UnexpectedNonterminal::Item(self.token.span)));
|
||||
}
|
||||
},
|
||||
NonterminalKind::Block => {
|
||||
|
@ -127,8 +126,9 @@ impl<'a> Parser<'a> {
|
|||
NonterminalKind::Stmt => match self.parse_stmt(ForceCollect::Yes)? {
|
||||
Some(s) => NtStmt(P(s)),
|
||||
None => {
|
||||
return Err(UnexpectedNonterminal::Statement(self.token.span)
|
||||
.into_diagnostic(self.dcx()));
|
||||
return Err(self
|
||||
.dcx()
|
||||
.create_err(UnexpectedNonterminal::Statement(self.token.span)));
|
||||
}
|
||||
},
|
||||
NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => {
|
||||
|
@ -160,11 +160,10 @@ impl<'a> Parser<'a> {
|
|||
NtIdent(ident, is_raw)
|
||||
}
|
||||
NonterminalKind::Ident => {
|
||||
return Err(UnexpectedNonterminal::Ident {
|
||||
return Err(self.dcx().create_err(UnexpectedNonterminal::Ident {
|
||||
span: self.token.span,
|
||||
token: self.token.clone(),
|
||||
}
|
||||
.into_diagnostic(self.dcx()));
|
||||
}));
|
||||
}
|
||||
NonterminalKind::Path => {
|
||||
NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?))
|
||||
|
@ -178,11 +177,10 @@ impl<'a> Parser<'a> {
|
|||
if self.check_lifetime() {
|
||||
NtLifetime(self.expect_lifetime().ident)
|
||||
} else {
|
||||
return Err(UnexpectedNonterminal::Lifetime {
|
||||
return Err(self.dcx().create_err(UnexpectedNonterminal::Lifetime {
|
||||
span: self.token.span,
|
||||
token: self.token.clone(),
|
||||
}
|
||||
.into_diagnostic(self.dcx()));
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ use rustc_ast::{
|
|||
PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult};
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
|
||||
use rustc_session::errors::ExprParenthesesNeeded;
|
||||
use rustc_span::source_map::{respan, Spanned};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
|
@ -872,8 +872,9 @@ impl<'a> Parser<'a> {
|
|||
// binding mode then we do not end up here, because the lookahead
|
||||
// will direct us over to `parse_enum_variant()`.
|
||||
if self.token == token::OpenDelim(Delimiter::Parenthesis) {
|
||||
return Err(EnumPatternInsteadOfIdentifier { span: self.prev_token.span }
|
||||
.into_diagnostic(self.dcx()));
|
||||
return Err(self
|
||||
.dcx()
|
||||
.create_err(EnumPatternInsteadOfIdentifier { span: self.prev_token.span }));
|
||||
}
|
||||
|
||||
Ok(PatKind::Ident(binding_annotation, ident, sub))
|
||||
|
@ -986,8 +987,8 @@ impl<'a> Parser<'a> {
|
|||
|
||||
// check that a comma comes after every field
|
||||
if !ate_comma {
|
||||
let mut err = ExpectedCommaAfterPatternField { span: self.token.span }
|
||||
.into_diagnostic(self.dcx());
|
||||
let mut err =
|
||||
self.dcx().create_err(ExpectedCommaAfterPatternField { span: self.token.span });
|
||||
if let Some(mut delayed) = delayed_err {
|
||||
delayed.emit();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use rustc_ast::{
|
|||
AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
|
||||
Path, PathSegment, QSelf,
|
||||
};
|
||||
use rustc_errors::{Applicability, IntoDiagnostic, PResult};
|
||||
use rustc_errors::{Applicability, PResult};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{BytePos, Span};
|
||||
use std::mem;
|
||||
|
@ -318,15 +318,14 @@ impl<'a> Parser<'a> {
|
|||
})
|
||||
{
|
||||
err.cancel();
|
||||
err = PathSingleColon {
|
||||
err = self.dcx().create_err(PathSingleColon {
|
||||
span: self.token.span,
|
||||
type_ascription: self
|
||||
.sess
|
||||
.unstable_features
|
||||
.is_nightly_build()
|
||||
.then_some(()),
|
||||
}
|
||||
.into_diagnostic(self.dcx());
|
||||
});
|
||||
}
|
||||
// Attempt to find places where a missing `>` might belong.
|
||||
else if let Some(arg) = args
|
||||
|
|
|
@ -6,8 +6,8 @@ use std::{
|
|||
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<G: EmissionGuarantee> 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 @@ impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel {
|
|||
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<Span>,
|
||||
}
|
||||
|
||||
impl IntoDiagnostic<'_> for NakedFunctionsAsmBlock {
|
||||
impl<G: EmissionGuarantee> 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<G: EmissionGuarantee> 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);
|
||||
|
|
|
@ -4,9 +4,7 @@ use crate::query::plumbing::CycleError;
|
|||
use crate::query::DepKind;
|
||||
use crate::query::{QueryContext, QueryStackFrame};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{
|
||||
DiagCtxt, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, Level,
|
||||
};
|
||||
use rustc_errors::{DiagCtxt, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Level};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::Span;
|
||||
|
@ -604,7 +602,7 @@ pub(crate) fn report_cycle<'a>(
|
|||
note_span: (),
|
||||
};
|
||||
|
||||
cycle_diag.into_diagnostic(sess.dcx())
|
||||
sess.dcx().create_err(cycle_diag)
|
||||
}
|
||||
|
||||
pub fn print_query_stack<Qcx: QueryContext>(
|
||||
|
|
|
@ -3,7 +3,10 @@ use std::num::NonZeroU32;
|
|||
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
|
||||
|
|
|
@ -14,7 +14,7 @@ use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc};
|
|||
use rustc_errors::{emitter::SilentEmitter, DiagCtxt};
|
||||
use rustc_errors::{
|
||||
fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
|
||||
ErrorGuaranteed, IntoDiagnostic, MultiSpan, Noted, StashKey,
|
||||
ErrorGuaranteed, FatalAbort, IntoDiagnostic, Level, MultiSpan, StashKey,
|
||||
};
|
||||
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
|
||||
use rustc_span::edition::Edition;
|
||||
|
@ -322,7 +322,7 @@ impl ParseSess {
|
|||
&'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 @@ impl ParseSess {
|
|||
&'a self,
|
||||
warning: impl IntoDiagnostic<'a, ()>,
|
||||
) -> DiagnosticBuilder<'a, ()> {
|
||||
warning.into_diagnostic(&self.dcx)
|
||||
warning.into_diagnostic(&self.dcx, Level::Warning(None))
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
|
@ -346,26 +346,26 @@ impl ParseSess {
|
|||
#[track_caller]
|
||||
pub fn create_note<'a>(
|
||||
&'a self,
|
||||
note: impl IntoDiagnostic<'a, Noted>,
|
||||
) -> DiagnosticBuilder<'a, Noted> {
|
||||
note.into_diagnostic(&self.dcx)
|
||||
note: impl IntoDiagnostic<'a, ()>,
|
||||
) -> DiagnosticBuilder<'a, ()> {
|
||||
note.into_diagnostic(&self.dcx, Level::Note)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
|
||||
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, ()>) {
|
||||
self.create_note(note).emit()
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn create_fatal<'a>(
|
||||
&'a self,
|
||||
fatal: impl IntoDiagnostic<'a, !>,
|
||||
) -> DiagnosticBuilder<'a, !> {
|
||||
fatal.into_diagnostic(&self.dcx)
|
||||
fatal: impl IntoDiagnostic<'a, FatalAbort>,
|
||||
) -> DiagnosticBuilder<'a, FatalAbort> {
|
||||
fatal.into_diagnostic(&self.dcx, Level::Fatal)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, !>) -> ! {
|
||||
pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, FatalAbort>) -> ! {
|
||||
self.create_fatal(fatal).emit()
|
||||
}
|
||||
|
||||
|
@ -386,7 +386,10 @@ impl ParseSess {
|
|||
|
||||
#[rustc_lint_diagnostics]
|
||||
#[track_caller]
|
||||
pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
|
||||
pub fn struct_fatal(
|
||||
&self,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, FatalAbort> {
|
||||
self.dcx.struct_fatal(msg)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ use rustc_errors::json::JsonEmitter;
|
|||
use rustc_errors::registry::Registry;
|
||||
use rustc_errors::{
|
||||
error_code, fallback_fluent_bundle, DiagCtxt, DiagnosticBuilder, DiagnosticId,
|
||||
DiagnosticMessage, ErrorGuaranteed, FluentBundle, IntoDiagnostic, LazyFallbackBundle,
|
||||
MultiSpan, Noted, TerminalUrl,
|
||||
DiagnosticMessage, ErrorGuaranteed, FatalAbort, FluentBundle, IntoDiagnostic,
|
||||
LazyFallbackBundle, MultiSpan, TerminalUrl,
|
||||
};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
pub use rustc_span::def_id::StableCrateId;
|
||||
|
@ -428,7 +428,7 @@ impl Session {
|
|||
&self,
|
||||
sp: S,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, !> {
|
||||
) -> DiagnosticBuilder<'_, FatalAbort> {
|
||||
self.dcx().struct_span_fatal(sp, msg)
|
||||
}
|
||||
#[rustc_lint_diagnostics]
|
||||
|
@ -437,11 +437,14 @@ impl Session {
|
|||
sp: S,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
code: DiagnosticId,
|
||||
) -> DiagnosticBuilder<'_, !> {
|
||||
) -> DiagnosticBuilder<'_, FatalAbort> {
|
||||
self.dcx().struct_span_fatal_with_code(sp, msg, code)
|
||||
}
|
||||
#[rustc_lint_diagnostics]
|
||||
pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
|
||||
pub fn struct_fatal(
|
||||
&self,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, FatalAbort> {
|
||||
self.dcx().struct_fatal(msg)
|
||||
}
|
||||
|
||||
|
@ -525,23 +528,23 @@ impl Session {
|
|||
#[track_caller]
|
||||
pub fn create_note<'a>(
|
||||
&'a self,
|
||||
note: impl IntoDiagnostic<'a, Noted>,
|
||||
) -> DiagnosticBuilder<'a, Noted> {
|
||||
note: impl IntoDiagnostic<'a, ()>,
|
||||
) -> DiagnosticBuilder<'a, ()> {
|
||||
self.parse_sess.create_note(note)
|
||||
}
|
||||
#[track_caller]
|
||||
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
|
||||
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, ()>) {
|
||||
self.parse_sess.emit_note(note)
|
||||
}
|
||||
#[track_caller]
|
||||
pub fn create_fatal<'a>(
|
||||
&'a self,
|
||||
fatal: impl IntoDiagnostic<'a, !>,
|
||||
) -> DiagnosticBuilder<'a, !> {
|
||||
fatal: impl IntoDiagnostic<'a, FatalAbort>,
|
||||
) -> DiagnosticBuilder<'a, FatalAbort> {
|
||||
self.parse_sess.create_fatal(fatal)
|
||||
}
|
||||
#[track_caller]
|
||||
pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, !>) -> ! {
|
||||
pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, FatalAbort>) -> ! {
|
||||
self.parse_sess.emit_fatal(fatal)
|
||||
}
|
||||
#[inline]
|
||||
|
@ -1780,7 +1783,7 @@ impl EarlyDiagCtxt {
|
|||
pub fn early_struct_error(
|
||||
&self,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, !> {
|
||||
) -> DiagnosticBuilder<'_, FatalAbort> {
|
||||
self.dcx.struct_fatal(msg)
|
||||
}
|
||||
|
||||
|
|
|
@ -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<G: EmissionGuarantee> 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
|
||||
}
|
||||
|
|
|
@ -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<Span, Symbol>,
|
||||
}
|
||||
|
||||
impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> {
|
||||
impl<G: EmissionGuarantee> 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",
|
||||
|
|
|
@ -13,8 +13,8 @@ extern crate rustc_session;
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// compile-flags: -Z track-diagnostics
|
||||
// error-pattern: created at
|
||||
// rustc-env:RUST_BACKTRACE=0
|
||||
// failure-status: 101
|
||||
|
||||
// Normalize the emitted location so this doesn't need
|
||||
// updating everytime someone adds or removes a line.
|
||||
|
|
|
@ -13,15 +13,31 @@ LL | break rust
|
|||
-Ztrack-diagnostics: created at compiler/rustc_passes/src/loops.rs:LL:CC
|
||||
|
||||
error: internal compiler error: It looks like you're trying to break rust; would you like some ICE?
|
||||
--> $DIR/track.rs:LL:CC
|
||||
|
|
||||
LL | break rust
|
||||
| ^^^^^^^^^^
|
||||
-Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/lib.rs:LL:CC
|
||||
|
|
||||
= note: the compiler expectedly panicked. this is a feature.
|
||||
= note: we would appreciate a joke overview: https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675
|
||||
= note: rustc $VERSION running on $TARGET
|
||||
= note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics
|
||||
|
||||
note: the compiler expectedly panicked. this is a feature.
|
||||
thread 'rustc' panicked at compiler/rustc_hir_typeck/src/lib.rs:LL:CC:
|
||||
Box<dyn Any>
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
|
||||
note: we would appreciate a joke overview: https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675
|
||||
note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md
|
||||
|
||||
note: rustc $VERSION running on $TARGET
|
||||
|
||||
note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics
|
||||
|
||||
query stack during panic:
|
||||
#0 [typeck] type-checking `main`
|
||||
#1 [analysis] running analysis passes on this crate
|
||||
end of query stack
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0268, E0425.
|
||||
|
|
Loading…
Reference in New Issue