1#![allow(internal_features)]
7#![allow(rustc::direct_use_of_rustc_type_ir)]
8#![feature(assert_matches)]
9#![feature(associated_type_defaults)]
10#![feature(box_patterns)]
11#![feature(default_field_values)]
12#![feature(error_reporter)]
13#![feature(macro_metavar_expr_concat)]
14#![feature(negative_impls)]
15#![feature(never_type)]
16#![feature(rustc_attrs)]
17#![feature(try_blocks)]
18#![feature(yeet_expr)]
19extern crate self as rustc_errors;
22
23use std::backtrace::{Backtrace, BacktraceStatus};
24use std::borrow::Cow;
25use std::cell::Cell;
26use std::error::Report;
27use std::ffi::OsStr;
28use std::hash::Hash;
29use std::io::Write;
30use std::num::NonZero;
31use std::ops::DerefMut;
32use std::path::{Path, PathBuf};
33use std::{fmt, panic};
34
35use Level::*;
36pub use anstream::{AutoStream, ColorChoice};
39pub use anstyle::{
40 Ansi256Color, AnsiColor, Color, EffectIter, Effects, Reset, RgbColor, Style as Anstyle,
41};
42pub use codes::*;
43pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer};
44pub use diagnostic::{
45 BugAbort, Diag, DiagArgMap, DiagInner, DiagStyledString, Diagnostic, EmissionGuarantee,
46 FatalAbort, LintDiagnostic, LintDiagnosticBox, StringPart, Subdiag, Subdiagnostic,
47};
48pub use diagnostic_impls::{
49 DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
50 IndicateAnonymousLifetime, SingleLabelManySpans,
51};
52pub use emitter::ColorConfig;
53use emitter::{DynEmitter, Emitter};
54use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
55use rustc_data_structures::stable_hasher::StableHasher;
56use rustc_data_structures::sync::{DynSend, Lock};
57use rustc_data_structures::{AtomicRef, assert_matches};
58pub use rustc_error_messages::{
59 DiagArg, DiagArgFromDisplay, DiagArgName, DiagArgValue, DiagMessage, FluentBundle, IntoDiagArg,
60 LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagMessage,
61 fallback_fluent_bundle, fluent_bundle, into_diag_arg_using_display,
62};
63use rustc_hashes::Hash128;
64use rustc_lint_defs::LintExpectationId;
65pub use rustc_lint_defs::{Applicability, listify, pluralize};
66use rustc_macros::{Decodable, Encodable};
67pub use rustc_span::ErrorGuaranteed;
68pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker, catch_fatal_errors};
69use rustc_span::source_map::SourceMap;
70use rustc_span::{DUMMY_SP, Span};
71use tracing::debug;
72
73use crate::emitter::TimingEvent;
74use crate::registry::Registry;
75use crate::timings::TimingRecord;
76
77pub mod annotate_snippet_emitter_writer;
78pub mod codes;
79mod decorate_diag;
80mod diagnostic;
81mod diagnostic_impls;
82pub mod emitter;
83pub mod error;
84pub mod json;
85mod lock;
86pub mod markdown;
87pub mod registry;
88#[cfg(test)]
89mod tests;
90pub mod timings;
91pub mod translation;
92
93pub type PResult<'a, T> = Result<T, Diag<'a>>;
94
95#[allow(non_upper_case_globals)]
#[doc(hidden)]
#[doc =
r" Auto-generated constants for type-checked references to Fluent messages."]
pub(crate) mod fluent_generated {
#[doc =
"Constant referring to Fluent message `errors_delayed_at_with_newline` from `errors`"]
pub const errors_delayed_at_with_newline: rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_delayed_at_with_newline"),
None);
#[doc =
"Constant referring to Fluent message `errors_delayed_at_without_newline` from `errors`"]
pub const errors_delayed_at_without_newline: rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_delayed_at_without_newline"),
None);
#[doc =
"Constant referring to Fluent message `errors_expected_lifetime_parameter` from `errors`"]
pub const errors_expected_lifetime_parameter: rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_expected_lifetime_parameter"),
None);
#[doc =
"Constant referring to Fluent message `errors_indicate_anonymous_lifetime` from `errors`"]
pub const errors_indicate_anonymous_lifetime: rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_indicate_anonymous_lifetime"),
None);
#[doc =
"Constant referring to Fluent message `errors_invalid_flushed_delayed_diagnostic_level` from `errors`"]
pub const errors_invalid_flushed_delayed_diagnostic_level:
rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_invalid_flushed_delayed_diagnostic_level"),
None);
#[doc =
"Constant referring to Fluent message `errors_target_inconsistent_architecture` from `errors`"]
pub const errors_target_inconsistent_architecture:
rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_target_inconsistent_architecture"),
None);
#[doc =
"Constant referring to Fluent message `errors_target_inconsistent_pointer_width` from `errors`"]
pub const errors_target_inconsistent_pointer_width:
rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_target_inconsistent_pointer_width"),
None);
#[doc =
"Constant referring to Fluent message `errors_target_invalid_address_space` from `errors`"]
pub const errors_target_invalid_address_space: rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_target_invalid_address_space"),
None);
#[doc =
"Constant referring to Fluent message `errors_target_invalid_alignment` from `errors`"]
pub const errors_target_invalid_alignment: rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_target_invalid_alignment"),
None);
#[doc =
"Constant referring to Fluent message `errors_target_invalid_bits` from `errors`"]
pub const errors_target_invalid_bits: rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_target_invalid_bits"),
None);
#[doc =
"Constant referring to Fluent message `errors_target_invalid_bits_size` from `errors`"]
pub const errors_target_invalid_bits_size: rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_target_invalid_bits_size"),
None);
#[doc =
"Constant referring to Fluent message `errors_target_invalid_datalayout_pointer_spec` from `errors`"]
pub const errors_target_invalid_datalayout_pointer_spec:
rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_target_invalid_datalayout_pointer_spec"),
None);
#[doc =
"Constant referring to Fluent message `errors_target_missing_alignment` from `errors`"]
pub const errors_target_missing_alignment: rustc_errors::DiagMessage =
rustc_errors::DiagMessage::FluentIdentifier(std::borrow::Cow::Borrowed("errors_target_missing_alignment"),
None);
#[doc =
r" Constants expected to exist by the diagnostic derive macros to use as default Fluent"]
#[doc = r" identifiers for different subdiagnostic kinds."]
pub mod _subdiag {
#[doc = r" Default for `#[help]`"]
pub const help: rustc_errors::SubdiagMessage =
rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed("help"));
#[doc = r" Default for `#[note]`"]
pub const note: rustc_errors::SubdiagMessage =
rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed("note"));
#[doc = r" Default for `#[warn]`"]
pub const warn: rustc_errors::SubdiagMessage =
rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed("warn"));
#[doc = r" Default for `#[label]`"]
pub const label: rustc_errors::SubdiagMessage =
rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed("label"));
#[doc = r" Default for `#[suggestion]`"]
pub const suggestion: rustc_errors::SubdiagMessage =
rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion"));
}
}rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
96
97#[cfg(target_pointer_width = "64")]
99const _: [(); 24] = [(); ::std::mem::size_of::<PResult<'_, ()>>()];rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24);
100#[cfg(target_pointer_width = "64")]
101const _: [(); 24] = [(); ::std::mem::size_of::<PResult<'_, bool>>()];rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
102
103#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SuggestionStyle {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
SuggestionStyle::HideCodeInline => "HideCodeInline",
SuggestionStyle::HideCodeAlways => "HideCodeAlways",
SuggestionStyle::CompletelyHidden => "CompletelyHidden",
SuggestionStyle::ShowCode => "ShowCode",
SuggestionStyle::ShowAlways => "ShowAlways",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for SuggestionStyle {
#[inline]
fn eq(&self, other: &SuggestionStyle) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SuggestionStyle {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::clone::Clone for SuggestionStyle {
#[inline]
fn clone(&self) -> SuggestionStyle { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SuggestionStyle { }Copy, #[automatically_derived]
impl ::core::hash::Hash for SuggestionStyle {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for SuggestionStyle {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
SuggestionStyle::HideCodeInline => { 0usize }
SuggestionStyle::HideCodeAlways => { 1usize }
SuggestionStyle::CompletelyHidden => { 2usize }
SuggestionStyle::ShowCode => { 3usize }
SuggestionStyle::ShowAlways => { 4usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
SuggestionStyle::HideCodeInline => {}
SuggestionStyle::HideCodeAlways => {}
SuggestionStyle::CompletelyHidden => {}
SuggestionStyle::ShowCode => {}
SuggestionStyle::ShowAlways => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for SuggestionStyle {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { SuggestionStyle::HideCodeInline }
1usize => { SuggestionStyle::HideCodeAlways }
2usize => { SuggestionStyle::CompletelyHidden }
3usize => { SuggestionStyle::ShowCode }
4usize => { SuggestionStyle::ShowAlways }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `SuggestionStyle`, expected 0..5, actual {0}",
n));
}
}
}
}
};Decodable)]
104pub enum SuggestionStyle {
105 HideCodeInline,
107 HideCodeAlways,
109 CompletelyHidden,
111 ShowCode,
115 ShowAlways,
117}
118
119impl SuggestionStyle {
120 fn hide_inline(&self) -> bool {
121 !#[allow(non_exhaustive_omitted_patterns)] match *self {
SuggestionStyle::ShowCode => true,
_ => false,
}matches!(*self, SuggestionStyle::ShowCode)
122 }
123}
124
125#[derive(#[automatically_derived]
impl ::core::clone::Clone for Suggestions {
#[inline]
fn clone(&self) -> Suggestions {
match self {
Suggestions::Enabled(__self_0) =>
Suggestions::Enabled(::core::clone::Clone::clone(__self_0)),
Suggestions::Sealed(__self_0) =>
Suggestions::Sealed(::core::clone::Clone::clone(__self_0)),
Suggestions::Disabled => Suggestions::Disabled,
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Suggestions {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Suggestions::Enabled(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Enabled", &__self_0),
Suggestions::Sealed(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Sealed",
&__self_0),
Suggestions::Disabled =>
::core::fmt::Formatter::write_str(f, "Disabled"),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Suggestions {
#[inline]
fn eq(&self, other: &Suggestions) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(Suggestions::Enabled(__self_0),
Suggestions::Enabled(__arg1_0)) => __self_0 == __arg1_0,
(Suggestions::Sealed(__self_0), Suggestions::Sealed(__arg1_0))
=> __self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Suggestions {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
Suggestions::Enabled(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
Suggestions::Sealed(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for Suggestions {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
Suggestions::Enabled(ref __binding_0) => { 0usize }
Suggestions::Sealed(ref __binding_0) => { 1usize }
Suggestions::Disabled => { 2usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
Suggestions::Enabled(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
Suggestions::Sealed(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
Suggestions::Disabled => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for Suggestions {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
Suggestions::Enabled(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => {
Suggestions::Sealed(::rustc_serialize::Decodable::decode(__decoder))
}
2usize => { Suggestions::Disabled }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Suggestions`, expected 0..3, actual {0}",
n));
}
}
}
}
};Decodable)]
127pub enum Suggestions {
128 Enabled(Vec<CodeSuggestion>),
133 Sealed(Box<[CodeSuggestion]>),
137 Disabled,
141}
142
143impl Suggestions {
144 pub fn unwrap_tag(self) -> Vec<CodeSuggestion> {
146 match self {
147 Suggestions::Enabled(suggestions) => suggestions,
148 Suggestions::Sealed(suggestions) => suggestions.into_vec(),
149 Suggestions::Disabled => Vec::new(),
150 }
151 }
152}
153
154impl Default for Suggestions {
155 fn default() -> Self {
156 Self::Enabled(::alloc::vec::Vec::new()vec![])
157 }
158}
159
160#[derive(#[automatically_derived]
impl ::core::clone::Clone for CodeSuggestion {
#[inline]
fn clone(&self) -> CodeSuggestion {
CodeSuggestion {
substitutions: ::core::clone::Clone::clone(&self.substitutions),
msg: ::core::clone::Clone::clone(&self.msg),
style: ::core::clone::Clone::clone(&self.style),
applicability: ::core::clone::Clone::clone(&self.applicability),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for CodeSuggestion {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f,
"CodeSuggestion", "substitutions", &self.substitutions, "msg",
&self.msg, "style", &self.style, "applicability",
&&self.applicability)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for CodeSuggestion {
#[inline]
fn eq(&self, other: &CodeSuggestion) -> bool {
self.substitutions == other.substitutions && self.msg == other.msg &&
self.style == other.style &&
self.applicability == other.applicability
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for CodeSuggestion {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.substitutions, state);
::core::hash::Hash::hash(&self.msg, state);
::core::hash::Hash::hash(&self.style, state);
::core::hash::Hash::hash(&self.applicability, state)
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for CodeSuggestion {
fn encode(&self, __encoder: &mut __E) {
match *self {
CodeSuggestion {
substitutions: ref __binding_0,
msg: ref __binding_1,
style: ref __binding_2,
applicability: ref __binding_3 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_2,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_3,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for CodeSuggestion {
fn decode(__decoder: &mut __D) -> Self {
CodeSuggestion {
substitutions: ::rustc_serialize::Decodable::decode(__decoder),
msg: ::rustc_serialize::Decodable::decode(__decoder),
style: ::rustc_serialize::Decodable::decode(__decoder),
applicability: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
161pub struct CodeSuggestion {
162 pub substitutions: Vec<Substitution>,
184 pub msg: DiagMessage,
185 pub style: SuggestionStyle,
187 pub applicability: Applicability,
193}
194
195#[derive(#[automatically_derived]
impl ::core::clone::Clone for Substitution {
#[inline]
fn clone(&self) -> Substitution {
Substitution { parts: ::core::clone::Clone::clone(&self.parts) }
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Substitution {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "Substitution",
"parts", &&self.parts)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Substitution {
#[inline]
fn eq(&self, other: &Substitution) -> bool { self.parts == other.parts }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Substitution {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.parts, state)
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for Substitution {
fn encode(&self, __encoder: &mut __E) {
match *self {
Substitution { parts: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for Substitution {
fn decode(__decoder: &mut __D) -> Self {
Substitution {
parts: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
196pub struct Substitution {
198 pub parts: Vec<SubstitutionPart>,
199}
200
201#[derive(#[automatically_derived]
impl ::core::clone::Clone for SubstitutionPart {
#[inline]
fn clone(&self) -> SubstitutionPart {
SubstitutionPart {
span: ::core::clone::Clone::clone(&self.span),
snippet: ::core::clone::Clone::clone(&self.snippet),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for SubstitutionPart {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"SubstitutionPart", "span", &self.span, "snippet", &&self.snippet)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for SubstitutionPart {
#[inline]
fn eq(&self, other: &SubstitutionPart) -> bool {
self.span == other.span && self.snippet == other.snippet
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for SubstitutionPart {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.span, state);
::core::hash::Hash::hash(&self.snippet, state)
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for SubstitutionPart {
fn encode(&self, __encoder: &mut __E) {
match *self {
SubstitutionPart {
span: ref __binding_0, snippet: ref __binding_1 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for SubstitutionPart {
fn decode(__decoder: &mut __D) -> Self {
SubstitutionPart {
span: ::rustc_serialize::Decodable::decode(__decoder),
snippet: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
202pub struct SubstitutionPart {
203 pub span: Span,
204 pub snippet: String,
205}
206
207#[derive(#[automatically_derived]
impl ::core::clone::Clone for TrimmedSubstitutionPart {
#[inline]
fn clone(&self) -> TrimmedSubstitutionPart {
TrimmedSubstitutionPart {
original_span: ::core::clone::Clone::clone(&self.original_span),
span: ::core::clone::Clone::clone(&self.span),
snippet: ::core::clone::Clone::clone(&self.snippet),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for TrimmedSubstitutionPart {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"TrimmedSubstitutionPart", "original_span", &self.original_span,
"span", &self.span, "snippet", &&self.snippet)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for TrimmedSubstitutionPart {
#[inline]
fn eq(&self, other: &TrimmedSubstitutionPart) -> bool {
self.original_span == other.original_span && self.span == other.span
&& self.snippet == other.snippet
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for TrimmedSubstitutionPart {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.original_span, state);
::core::hash::Hash::hash(&self.span, state);
::core::hash::Hash::hash(&self.snippet, state)
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for TrimmedSubstitutionPart {
fn encode(&self, __encoder: &mut __E) {
match *self {
TrimmedSubstitutionPart {
original_span: ref __binding_0,
span: ref __binding_1,
snippet: ref __binding_2 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_2,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for TrimmedSubstitutionPart {
fn decode(__decoder: &mut __D) -> Self {
TrimmedSubstitutionPart {
original_span: ::rustc_serialize::Decodable::decode(__decoder),
span: ::rustc_serialize::Decodable::decode(__decoder),
snippet: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
208pub struct TrimmedSubstitutionPart {
209 pub original_span: Span,
210 pub span: Span,
211 pub snippet: String,
212}
213
214impl TrimmedSubstitutionPart {
215 pub fn is_addition(&self, sm: &SourceMap) -> bool {
216 !self.snippet.is_empty() && !self.replaces_meaningful_content(sm)
217 }
218
219 pub fn is_deletion(&self, sm: &SourceMap) -> bool {
220 self.snippet.trim().is_empty() && self.replaces_meaningful_content(sm)
221 }
222
223 pub fn is_replacement(&self, sm: &SourceMap) -> bool {
224 !self.snippet.is_empty() && self.replaces_meaningful_content(sm)
225 }
226
227 pub fn is_destructive_replacement(&self, sm: &SourceMap) -> bool {
232 self.is_replacement(sm)
233 && !sm
234 .span_to_snippet(self.span)
235 .is_ok_and(|snippet| as_substr(snippet.trim(), self.snippet.trim()).is_some())
236 }
237
238 fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool {
239 sm.span_to_snippet(self.span)
240 .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty())
241 }
242}
243
244fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a str, usize)> {
249 let common_prefix = original
250 .chars()
251 .zip(suggestion.chars())
252 .take_while(|(c1, c2)| c1 == c2)
253 .map(|(c, _)| c.len_utf8())
254 .sum();
255 let original = &original[common_prefix..];
256 let suggestion = &suggestion[common_prefix..];
257 if suggestion.ends_with(original) {
258 let common_suffix = original.len();
259 Some((common_prefix, &suggestion[..suggestion.len() - original.len()], common_suffix))
260 } else {
261 None
262 }
263}
264
265pub struct ExplicitBug;
268
269pub struct DelayedBugPanic;
272
273pub struct DiagCtxt {
277 inner: Lock<DiagCtxtInner>,
278}
279
280#[derive(#[automatically_derived]
impl<'a> ::core::marker::Copy for DiagCtxtHandle<'a> { }Copy, #[automatically_derived]
impl<'a> ::core::clone::Clone for DiagCtxtHandle<'a> {
#[inline]
fn clone(&self) -> DiagCtxtHandle<'a> {
let _: ::core::clone::AssertParamIsClone<&'a DiagCtxt>;
let _:
::core::clone::AssertParamIsClone<Option<&'a Cell<Option<ErrorGuaranteed>>>>;
*self
}
}Clone)]
281pub struct DiagCtxtHandle<'a> {
282 dcx: &'a DiagCtxt,
283 tainted_with_errors: Option<&'a Cell<Option<ErrorGuaranteed>>>,
286}
287
288impl<'a> std::ops::Deref for DiagCtxtHandle<'a> {
289 type Target = &'a DiagCtxt;
290
291 fn deref(&self) -> &Self::Target {
292 &self.dcx
293 }
294}
295
296struct DiagCtxtInner {
300 flags: DiagCtxtFlags,
301
302 registry: Registry,
303
304 err_guars: Vec<ErrorGuaranteed>,
306 lint_err_guars: Vec<ErrorGuaranteed>,
309 delayed_bugs: Vec<(DelayedDiagInner, ErrorGuaranteed)>,
311
312 deduplicated_err_count: usize,
314 deduplicated_warn_count: usize,
316
317 emitter: Box<DynEmitter>,
318
319 must_produce_diag: Option<Backtrace>,
322
323 has_printed: bool,
326
327 suppressed_expected_diag: bool,
330
331 taught_diagnostics: FxHashSet<ErrCode>,
335
336 emitted_diagnostic_codes: FxIndexSet<ErrCode>,
338
339 emitted_diagnostics: FxHashSet<Hash128>,
343
344 stashed_diagnostics:
350 FxIndexMap<StashKey, FxIndexMap<Span, (DiagInner, Option<ErrorGuaranteed>)>>,
351
352 future_breakage_diagnostics: Vec<DiagInner>,
353
354 fulfilled_expectations: FxIndexSet<LintExpectationId>,
366
367 ice_file: Option<PathBuf>,
370}
371
372#[derive(#[automatically_derived]
impl ::core::marker::Copy for StashKey { }Copy, #[automatically_derived]
impl ::core::clone::Clone for StashKey {
#[inline]
fn clone(&self) -> StashKey { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for StashKey {
#[inline]
fn eq(&self, other: &StashKey) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for StashKey {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for StashKey {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for StashKey {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
StashKey::ItemNoType => "ItemNoType",
StashKey::UnderscoreForArrayLengths =>
"UnderscoreForArrayLengths",
StashKey::EarlySyntaxWarning => "EarlySyntaxWarning",
StashKey::CallIntoMethod => "CallIntoMethod",
StashKey::LifetimeIsChar => "LifetimeIsChar",
StashKey::MaybeFruTypo => "MaybeFruTypo",
StashKey::CallAssocMethod => "CallAssocMethod",
StashKey::AssociatedTypeSuggestion =>
"AssociatedTypeSuggestion",
StashKey::Cycle => "Cycle",
StashKey::UndeterminedMacroResolution =>
"UndeterminedMacroResolution",
StashKey::ExprInPat => "ExprInPat",
StashKey::GenericInFieldExpr => "GenericInFieldExpr",
})
}
}Debug)]
374pub enum StashKey {
375 ItemNoType,
376 UnderscoreForArrayLengths,
377 EarlySyntaxWarning,
378 CallIntoMethod,
379 LifetimeIsChar,
382 MaybeFruTypo,
385 CallAssocMethod,
386 AssociatedTypeSuggestion,
387 Cycle,
389 UndeterminedMacroResolution,
390 ExprInPat,
392 GenericInFieldExpr,
396}
397
398fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
399 (*f)(diag)
400}
401
402pub static TRACK_DIAGNOSTIC: AtomicRef<
405 fn(DiagInner, &mut dyn FnMut(DiagInner) -> Option<ErrorGuaranteed>) -> Option<ErrorGuaranteed>,
406> = AtomicRef::new(&(default_track_diagnostic as _));
407
408#[derive(#[automatically_derived]
impl ::core::marker::Copy for DiagCtxtFlags { }Copy, #[automatically_derived]
impl ::core::clone::Clone for DiagCtxtFlags {
#[inline]
fn clone(&self) -> DiagCtxtFlags {
let _: ::core::clone::AssertParamIsClone<bool>;
let _: ::core::clone::AssertParamIsClone<Option<NonZero<usize>>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::default::Default for DiagCtxtFlags {
#[inline]
fn default() -> DiagCtxtFlags {
DiagCtxtFlags {
can_emit_warnings: ::core::default::Default::default(),
treat_err_as_bug: ::core::default::Default::default(),
eagerly_emit_delayed_bugs: ::core::default::Default::default(),
macro_backtrace: ::core::default::Default::default(),
deduplicate_diagnostics: ::core::default::Default::default(),
track_diagnostics: ::core::default::Default::default(),
}
}
}Default)]
409pub struct DiagCtxtFlags {
410 pub can_emit_warnings: bool,
413 pub treat_err_as_bug: Option<NonZero<usize>>,
416 pub eagerly_emit_delayed_bugs: bool,
419 pub macro_backtrace: bool,
422 pub deduplicate_diagnostics: bool,
424 pub track_diagnostics: bool,
426}
427
428impl Drop for DiagCtxtInner {
429 fn drop(&mut self) {
430 self.emit_stashed_diagnostics();
438
439 self.flush_delayed();
443
444 if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() {
448 if let Some(backtrace) = &self.must_produce_diag {
449 let suggestion = match backtrace.status() {
450 BacktraceStatus::Disabled => String::from(
451 "Backtraces are currently disabled: set `RUST_BACKTRACE=1` and re-run \
452 to see where it happened.",
453 ),
454 BacktraceStatus::Captured => ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("This happened in the following `must_produce_diag` call\'s backtrace:\n{0}",
backtrace))
})format!(
455 "This happened in the following `must_produce_diag` call's backtrace:\n\
456 {backtrace}",
457 ),
458 _ => String::from("(impossible to capture backtrace where this happened)"),
459 };
460 {
::core::panicking::panic_fmt(format_args!("`trimmed_def_paths` called, diagnostics were expected but none were emitted. Use `with_no_trimmed_paths` for debugging. {0}",
suggestion));
};panic!(
461 "`trimmed_def_paths` called, diagnostics were expected but none were emitted. \
462 Use `with_no_trimmed_paths` for debugging. {suggestion}"
463 );
464 }
465 }
466 }
467}
468
469impl DiagCtxt {
470 pub fn disable_warnings(mut self) -> Self {
471 self.inner.get_mut().flags.can_emit_warnings = false;
472 self
473 }
474
475 pub fn with_flags(mut self, flags: DiagCtxtFlags) -> Self {
476 self.inner.get_mut().flags = flags;
477 self
478 }
479
480 pub fn with_ice_file(mut self, ice_file: PathBuf) -> Self {
481 self.inner.get_mut().ice_file = Some(ice_file);
482 self
483 }
484
485 pub fn with_registry(mut self, registry: Registry) -> Self {
486 self.inner.get_mut().registry = registry;
487 self
488 }
489
490 pub fn new(emitter: Box<DynEmitter>) -> Self {
491 Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
492 }
493
494 pub fn make_silent(&self) {
495 let mut inner = self.inner.borrow_mut();
496 let translator = inner.emitter.translator().clone();
497 inner.emitter = Box::new(emitter::SilentEmitter { translator });
498 }
499
500 pub fn set_emitter(&self, emitter: Box<dyn Emitter + DynSend>) {
501 self.inner.borrow_mut().emitter = emitter;
502 }
503
504 pub fn eagerly_translate<'a>(
506 &self,
507 message: DiagMessage,
508 args: impl Iterator<Item = DiagArg<'a>>,
509 ) -> SubdiagMessage {
510 let inner = self.inner.borrow();
511 inner.eagerly_translate(message, args)
512 }
513
514 pub fn eagerly_translate_to_string<'a>(
516 &self,
517 message: DiagMessage,
518 args: impl Iterator<Item = DiagArg<'a>>,
519 ) -> String {
520 let inner = self.inner.borrow();
521 inner.eagerly_translate_to_string(message, args)
522 }
523
524 pub fn can_emit_warnings(&self) -> bool {
528 self.inner.borrow_mut().flags.can_emit_warnings
529 }
530
531 pub fn reset_err_count(&self) {
537 let mut inner = self.inner.borrow_mut();
540 let DiagCtxtInner {
541 flags: _,
542 registry: _,
543 err_guars,
544 lint_err_guars,
545 delayed_bugs,
546 deduplicated_err_count,
547 deduplicated_warn_count,
548 emitter: _,
549 must_produce_diag,
550 has_printed,
551 suppressed_expected_diag,
552 taught_diagnostics,
553 emitted_diagnostic_codes,
554 emitted_diagnostics,
555 stashed_diagnostics,
556 future_breakage_diagnostics,
557 fulfilled_expectations,
558 ice_file: _,
559 } = inner.deref_mut();
560
561 *err_guars = Default::default();
564 *lint_err_guars = Default::default();
565 *delayed_bugs = Default::default();
566 *deduplicated_err_count = 0;
567 *deduplicated_warn_count = 0;
568 *must_produce_diag = None;
569 *has_printed = false;
570 *suppressed_expected_diag = false;
571 *taught_diagnostics = Default::default();
572 *emitted_diagnostic_codes = Default::default();
573 *emitted_diagnostics = Default::default();
574 *stashed_diagnostics = Default::default();
575 *future_breakage_diagnostics = Default::default();
576 *fulfilled_expectations = Default::default();
577 }
578
579 pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> {
580 DiagCtxtHandle { dcx: self, tainted_with_errors: None }
581 }
582
583 pub fn taintable_handle<'a>(
587 &'a self,
588 tainted_with_errors: &'a Cell<Option<ErrorGuaranteed>>,
589 ) -> DiagCtxtHandle<'a> {
590 DiagCtxtHandle { dcx: self, tainted_with_errors: Some(tainted_with_errors) }
591 }
592}
593
594impl<'a> DiagCtxtHandle<'a> {
595 pub fn stash_diagnostic(
617 &self,
618 span: Span,
619 key: StashKey,
620 diag: DiagInner,
621 ) -> Option<ErrorGuaranteed> {
622 let guar = match diag.level {
623 Bug | Fatal => {
624 self.span_bug(
625 span,
626 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("invalid level in `stash_diagnostic`: {0:?}",
diag.level))
})format!("invalid level in `stash_diagnostic`: {:?}", diag.level),
627 );
628 }
629 Error => Some(self.span_delayed_bug(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("stashing {0:?}", key))
})format!("stashing {key:?}"))),
633 DelayedBug => {
634 return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors);
635 }
636 ForceWarning | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
637 | Expect => None,
638 };
639
640 self.inner
644 .borrow_mut()
645 .stashed_diagnostics
646 .entry(key)
647 .or_default()
648 .insert(span.with_parent(None), (diag, guar));
649
650 guar
651 }
652
653 pub fn steal_non_err(self, span: Span, key: StashKey) -> Option<Diag<'a, ()>> {
657 let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
659 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
660 )?;
661 if !!diag.is_error() {
::core::panicking::panic("assertion failed: !diag.is_error()")
};assert!(!diag.is_error());
662 if !guar.is_none() {
::core::panicking::panic("assertion failed: guar.is_none()")
};assert!(guar.is_none());
663 Some(Diag::new_diagnostic(self, diag))
664 }
665
666 pub fn try_steal_modify_and_emit_err<F>(
671 self,
672 span: Span,
673 key: StashKey,
674 mut modify_err: F,
675 ) -> Option<ErrorGuaranteed>
676 where
677 F: FnMut(&mut Diag<'_>),
678 {
679 let err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
681 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
682 );
683 err.map(|(err, guar)| {
684 match (&err.level, &Error) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(err.level, Error);
686 if !guar.is_some() {
::core::panicking::panic("assertion failed: guar.is_some()")
};assert!(guar.is_some());
687 let mut err = Diag::<ErrorGuaranteed>::new_diagnostic(self, err);
688 modify_err(&mut err);
689 match (&err.level, &Error) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(err.level, Error);
690 err.emit()
691 })
692 }
693
694 pub fn try_steal_replace_and_emit_err(
698 self,
699 span: Span,
700 key: StashKey,
701 new_err: Diag<'_>,
702 ) -> ErrorGuaranteed {
703 let old_err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
705 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
706 );
707 match old_err {
708 Some((old_err, guar)) => {
709 match (&old_err.level, &Error) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(old_err.level, Error);
710 if !guar.is_some() {
::core::panicking::panic("assertion failed: guar.is_some()")
};assert!(guar.is_some());
711 Diag::<ErrorGuaranteed>::new_diagnostic(self, old_err).cancel();
714 }
715 None => {}
716 };
717 new_err.emit()
718 }
719
720 pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool {
721 let inner = self.inner.borrow();
722 if let Some(stashed_diagnostics) = inner.stashed_diagnostics.get(&key)
723 && !stashed_diagnostics.is_empty()
724 {
725 stashed_diagnostics.contains_key(&span.with_parent(None))
726 } else {
727 false
728 }
729 }
730
731 pub fn emit_stashed_diagnostics(&self) -> Option<ErrorGuaranteed> {
733 self.inner.borrow_mut().emit_stashed_diagnostics()
734 }
735
736 #[inline]
738 pub fn err_count(&self) -> usize {
739 let inner = self.inner.borrow();
740 inner.err_guars.len()
741 + inner.lint_err_guars.len()
742 + inner
743 .stashed_diagnostics
744 .values()
745 .map(|a| a.values().filter(|(_, guar)| guar.is_some()).count())
746 .sum::<usize>()
747 }
748
749 pub fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
752 self.inner.borrow().has_errors_excluding_lint_errors()
753 }
754
755 pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
757 self.inner.borrow().has_errors()
758 }
759
760 pub fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
763 self.inner.borrow().has_errors_or_delayed_bugs()
764 }
765
766 pub fn print_error_count(&self) {
767 let mut inner = self.inner.borrow_mut();
768
769 if !inner.stashed_diagnostics.is_empty() {
::core::panicking::panic("assertion failed: inner.stashed_diagnostics.is_empty()")
};assert!(inner.stashed_diagnostics.is_empty());
772
773 if inner.treat_err_as_bug() {
774 return;
775 }
776
777 let warnings = match inner.deduplicated_warn_count {
778 0 => Cow::from(""),
779 1 => Cow::from("1 warning emitted"),
780 count => Cow::from(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} warnings emitted", count))
})format!("{count} warnings emitted")),
781 };
782 let errors = match inner.deduplicated_err_count {
783 0 => Cow::from(""),
784 1 => Cow::from("aborting due to 1 previous error"),
785 count => Cow::from(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("aborting due to {0} previous errors",
count))
})format!("aborting due to {count} previous errors")),
786 };
787
788 match (errors.len(), warnings.len()) {
789 (0, 0) => return,
790 (0, _) => {
791 inner.emit_diagnostic(
794 DiagInner::new(ForceWarning, DiagMessage::Str(warnings)),
795 None,
796 );
797 }
798 (_, 0) => {
799 inner.emit_diagnostic(DiagInner::new(Error, errors), self.tainted_with_errors);
800 }
801 (_, _) => {
802 inner.emit_diagnostic(
803 DiagInner::new(Error, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}; {1}", errors, warnings))
})format!("{errors}; {warnings}")),
804 self.tainted_with_errors,
805 );
806 }
807 }
808
809 let can_show_explain = inner.emitter.should_show_explain();
810 let are_there_diagnostics = !inner.emitted_diagnostic_codes.is_empty();
811 if can_show_explain && are_there_diagnostics {
812 let mut error_codes = inner
813 .emitted_diagnostic_codes
814 .iter()
815 .filter_map(|&code| {
816 if inner.registry.try_find_description(code).is_ok() {
817 Some(code.to_string())
818 } else {
819 None
820 }
821 })
822 .collect::<Vec<_>>();
823 if !error_codes.is_empty() {
824 error_codes.sort();
825 if error_codes.len() > 1 {
826 let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
827 let msg1 = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Some errors have detailed explanations: {0}{1}",
error_codes[..limit].join(", "),
if error_codes.len() > 9 { "..." } else { "." }))
})format!(
828 "Some errors have detailed explanations: {}{}",
829 error_codes[..limit].join(", "),
830 if error_codes.len() > 9 { "..." } else { "." }
831 );
832 let msg2 = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("For more information about an error, try `rustc --explain {0}`.",
&error_codes[0]))
})format!(
833 "For more information about an error, try `rustc --explain {}`.",
834 &error_codes[0]
835 );
836 inner.emit_diagnostic(DiagInner::new(FailureNote, msg1), None);
837 inner.emit_diagnostic(DiagInner::new(FailureNote, msg2), None);
838 } else {
839 let msg = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("For more information about this error, try `rustc --explain {0}`.",
&error_codes[0]))
})format!(
840 "For more information about this error, try `rustc --explain {}`.",
841 &error_codes[0]
842 );
843 inner.emit_diagnostic(DiagInner::new(FailureNote, msg), None);
844 }
845 }
846 }
847 }
848
849 pub fn abort_if_errors(&self) {
854 if let Some(guar) = self.has_errors() {
855 guar.raise_fatal();
856 }
857 }
858
859 pub fn must_teach(&self, code: ErrCode) -> bool {
865 self.inner.borrow_mut().taught_diagnostics.insert(code)
866 }
867
868 pub fn emit_diagnostic(&self, diagnostic: DiagInner) -> Option<ErrorGuaranteed> {
869 self.inner.borrow_mut().emit_diagnostic(diagnostic, self.tainted_with_errors)
870 }
871
872 pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
873 self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type);
874 }
875
876 pub fn emit_timing_section_start(&self, record: TimingRecord) {
877 self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::Start);
878 }
879
880 pub fn emit_timing_section_end(&self, record: TimingRecord) {
881 self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::End);
882 }
883
884 pub fn emit_future_breakage_report(&self) {
885 let inner = &mut *self.inner.borrow_mut();
886 let diags = std::mem::take(&mut inner.future_breakage_diagnostics);
887 if !diags.is_empty() {
888 inner.emitter.emit_future_breakage_report(diags, &inner.registry);
889 }
890 }
891
892 pub fn emit_unused_externs(
893 &self,
894 lint_level: rustc_lint_defs::Level,
895 loud: bool,
896 unused_externs: &[&str],
897 ) {
898 let mut inner = self.inner.borrow_mut();
899
900 if loud && lint_level.is_error() {
911 #[allow(deprecated)]
914 inner.lint_err_guars.push(ErrorGuaranteed::unchecked_error_guaranteed());
915 inner.panic_if_treat_err_as_bug();
916 }
917
918 inner.emitter.emit_unused_externs(lint_level, unused_externs)
919 }
920
921 #[must_use]
924 pub fn steal_fulfilled_expectation_ids(&self) -> FxIndexSet<LintExpectationId> {
925 std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations)
926 }
927
928 pub fn flush_delayed(&self) {
933 self.inner.borrow_mut().flush_delayed();
934 }
935
936 #[track_caller]
939 pub fn set_must_produce_diag(&self) {
940 if !self.inner.borrow().must_produce_diag.is_none() {
{
::core::panicking::panic_fmt(format_args!("should only need to collect a backtrace once"));
}
};assert!(
941 self.inner.borrow().must_produce_diag.is_none(),
942 "should only need to collect a backtrace once"
943 );
944 self.inner.borrow_mut().must_produce_diag = Some(Backtrace::capture());
945 }
946}
947
948impl<'a> DiagCtxtHandle<'a> {
953 #[track_caller]
954 pub fn struct_bug(self, msg: impl Into<Cow<'static, str>>) -> Diag<'a, BugAbort> {
955 Diag::new(self, Bug, msg.into())
956 }
957
958 #[track_caller]
959 pub fn bug(self, msg: impl Into<Cow<'static, str>>) -> ! {
960 self.struct_bug(msg).emit()
961 }
962
963 #[track_caller]
964 pub fn struct_span_bug(
965 self,
966 span: impl Into<MultiSpan>,
967 msg: impl Into<Cow<'static, str>>,
968 ) -> Diag<'a, BugAbort> {
969 self.struct_bug(msg).with_span(span)
970 }
971
972 #[track_caller]
973 pub fn span_bug(self, span: impl Into<MultiSpan>, msg: impl Into<Cow<'static, str>>) -> ! {
974 self.struct_span_bug(span, msg.into()).emit()
975 }
976
977 #[track_caller]
978 pub fn create_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> Diag<'a, BugAbort> {
979 bug.into_diag(self, Bug)
980 }
981
982 #[track_caller]
983 pub fn emit_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> ! {
984 self.create_bug(bug).emit()
985 }
986
987 #[track_caller]
988 pub fn struct_fatal(self, msg: impl Into<DiagMessage>) -> Diag<'a, FatalAbort> {
989 Diag::new(self, Fatal, msg)
990 }
991
992 #[track_caller]
993 pub fn fatal(self, msg: impl Into<DiagMessage>) -> ! {
994 self.struct_fatal(msg).emit()
995 }
996
997 #[track_caller]
998 pub fn struct_span_fatal(
999 self,
1000 span: impl Into<MultiSpan>,
1001 msg: impl Into<DiagMessage>,
1002 ) -> Diag<'a, FatalAbort> {
1003 self.struct_fatal(msg).with_span(span)
1004 }
1005
1006 #[track_caller]
1007 pub fn span_fatal(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) -> ! {
1008 self.struct_span_fatal(span, msg).emit()
1009 }
1010
1011 #[track_caller]
1012 pub fn create_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> Diag<'a, FatalAbort> {
1013 fatal.into_diag(self, Fatal)
1014 }
1015
1016 #[track_caller]
1017 pub fn emit_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> ! {
1018 self.create_fatal(fatal).emit()
1019 }
1020
1021 #[track_caller]
1022 pub fn create_almost_fatal(
1023 self,
1024 fatal: impl Diagnostic<'a, FatalError>,
1025 ) -> Diag<'a, FatalError> {
1026 fatal.into_diag(self, Fatal)
1027 }
1028
1029 #[track_caller]
1030 pub fn emit_almost_fatal(self, fatal: impl Diagnostic<'a, FatalError>) -> FatalError {
1031 self.create_almost_fatal(fatal).emit()
1032 }
1033
1034 #[track_caller]
1036 pub fn struct_err(self, msg: impl Into<DiagMessage>) -> Diag<'a> {
1037 Diag::new(self, Error, msg)
1038 }
1039
1040 #[track_caller]
1041 pub fn err(self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
1042 self.struct_err(msg).emit()
1043 }
1044
1045 #[track_caller]
1046 pub fn struct_span_err(
1047 self,
1048 span: impl Into<MultiSpan>,
1049 msg: impl Into<DiagMessage>,
1050 ) -> Diag<'a> {
1051 self.struct_err(msg).with_span(span)
1052 }
1053
1054 #[track_caller]
1055 pub fn span_err(
1056 self,
1057 span: impl Into<MultiSpan>,
1058 msg: impl Into<DiagMessage>,
1059 ) -> ErrorGuaranteed {
1060 self.struct_span_err(span, msg).emit()
1061 }
1062
1063 #[track_caller]
1064 pub fn create_err(self, err: impl Diagnostic<'a>) -> Diag<'a> {
1065 err.into_diag(self, Error)
1066 }
1067
1068 #[track_caller]
1069 pub fn emit_err(self, err: impl Diagnostic<'a>) -> ErrorGuaranteed {
1070 self.create_err(err).emit()
1071 }
1072
1073 #[track_caller]
1075 pub fn delayed_bug(self, msg: impl Into<Cow<'static, str>>) -> ErrorGuaranteed {
1076 Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).emit()
1077 }
1078
1079 #[track_caller]
1084 pub fn span_delayed_bug(
1085 self,
1086 sp: impl Into<MultiSpan>,
1087 msg: impl Into<Cow<'static, str>>,
1088 ) -> ErrorGuaranteed {
1089 Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).with_span(sp).emit()
1090 }
1091
1092 #[track_caller]
1093 pub fn struct_warn(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1094 Diag::new(self, Warning, msg)
1095 }
1096
1097 #[track_caller]
1098 pub fn warn(self, msg: impl Into<DiagMessage>) {
1099 self.struct_warn(msg).emit()
1100 }
1101
1102 #[track_caller]
1103 pub fn struct_span_warn(
1104 self,
1105 span: impl Into<MultiSpan>,
1106 msg: impl Into<DiagMessage>,
1107 ) -> Diag<'a, ()> {
1108 self.struct_warn(msg).with_span(span)
1109 }
1110
1111 #[track_caller]
1112 pub fn span_warn(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
1113 self.struct_span_warn(span, msg).emit()
1114 }
1115
1116 #[track_caller]
1117 pub fn create_warn(self, warning: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
1118 warning.into_diag(self, Warning)
1119 }
1120
1121 #[track_caller]
1122 pub fn emit_warn(self, warning: impl Diagnostic<'a, ()>) {
1123 self.create_warn(warning).emit()
1124 }
1125
1126 #[track_caller]
1127 pub fn struct_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1128 Diag::new(self, Note, msg)
1129 }
1130
1131 #[track_caller]
1132 pub fn note(&self, msg: impl Into<DiagMessage>) {
1133 self.struct_note(msg).emit()
1134 }
1135
1136 #[track_caller]
1137 pub fn struct_span_note(
1138 self,
1139 span: impl Into<MultiSpan>,
1140 msg: impl Into<DiagMessage>,
1141 ) -> Diag<'a, ()> {
1142 self.struct_note(msg).with_span(span)
1143 }
1144
1145 #[track_caller]
1146 pub fn span_note(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
1147 self.struct_span_note(span, msg).emit()
1148 }
1149
1150 #[track_caller]
1151 pub fn create_note(self, note: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
1152 note.into_diag(self, Note)
1153 }
1154
1155 #[track_caller]
1156 pub fn emit_note(self, note: impl Diagnostic<'a, ()>) {
1157 self.create_note(note).emit()
1158 }
1159
1160 #[track_caller]
1161 pub fn struct_help(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1162 Diag::new(self, Help, msg)
1163 }
1164
1165 #[track_caller]
1166 pub fn struct_failure_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1167 Diag::new(self, FailureNote, msg)
1168 }
1169
1170 #[track_caller]
1171 pub fn struct_allow(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1172 Diag::new(self, Allow, msg)
1173 }
1174
1175 #[track_caller]
1176 pub fn struct_expect(self, msg: impl Into<DiagMessage>, id: LintExpectationId) -> Diag<'a, ()> {
1177 Diag::new(self, Expect, msg).with_lint_id(id)
1178 }
1179}
1180
1181impl DiagCtxtInner {
1186 fn new(emitter: Box<DynEmitter>) -> Self {
1187 Self {
1188 flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
1189 registry: Registry::new(&[]),
1190 err_guars: Vec::new(),
1191 lint_err_guars: Vec::new(),
1192 delayed_bugs: Vec::new(),
1193 deduplicated_err_count: 0,
1194 deduplicated_warn_count: 0,
1195 emitter,
1196 must_produce_diag: None,
1197 has_printed: false,
1198 suppressed_expected_diag: false,
1199 taught_diagnostics: Default::default(),
1200 emitted_diagnostic_codes: Default::default(),
1201 emitted_diagnostics: Default::default(),
1202 stashed_diagnostics: Default::default(),
1203 future_breakage_diagnostics: Vec::new(),
1204 fulfilled_expectations: Default::default(),
1205 ice_file: None,
1206 }
1207 }
1208
1209 fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
1211 let mut guar = None;
1212 let has_errors = !self.err_guars.is_empty();
1213 for (_, stashed_diagnostics) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
1214 for (_, (diag, _guar)) in stashed_diagnostics {
1215 if !diag.is_error() {
1216 if !diag.is_force_warn() && has_errors {
1220 continue;
1221 }
1222 }
1223 guar = guar.or(self.emit_diagnostic(diag, None));
1224 }
1225 }
1226 guar
1227 }
1228
1229 fn emit_diagnostic(
1231 &mut self,
1232 mut diagnostic: DiagInner,
1233 taint: Option<&Cell<Option<ErrorGuaranteed>>>,
1234 ) -> Option<ErrorGuaranteed> {
1235 if diagnostic.has_future_breakage() {
1236 match diagnostic.level {
Error | ForceWarning | Warning | Allow | Expect => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"Error | ForceWarning | Warning | Allow | Expect",
::core::option::Option::None);
}
};assert_matches!(diagnostic.level, Error | ForceWarning | Warning | Allow | Expect);
1240 self.future_breakage_diagnostics.push(diagnostic.clone());
1241 }
1242
1243 match diagnostic.level {
1247 Bug => {}
1248 Fatal | Error => {
1249 if self.treat_next_err_as_bug() {
1250 diagnostic.level = Bug;
1252 }
1253 }
1254 DelayedBug => {
1255 if self.flags.eagerly_emit_delayed_bugs {
1260 if self.treat_next_err_as_bug() {
1262 diagnostic.level = Bug;
1263 } else {
1264 diagnostic.level = Error;
1265 }
1266 } else {
1267 return if let Some(guar) = self.has_errors() {
1270 Some(guar)
1271 } else {
1272 let backtrace = std::backtrace::Backtrace::capture();
1276 #[allow(deprecated)]
1280 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
1281 self.delayed_bugs
1282 .push((DelayedDiagInner::with_backtrace(diagnostic, backtrace), guar));
1283 Some(guar)
1284 };
1285 }
1286 }
1287 ForceWarning if diagnostic.lint_id.is_none() => {} Warning => {
1289 if !self.flags.can_emit_warnings {
1290 if diagnostic.has_future_breakage() {
1292 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1294 }
1295 return None;
1296 }
1297 }
1298 Note | Help | FailureNote => {}
1299 OnceNote | OnceHelp => {
::core::panicking::panic_fmt(format_args!("bad level: {0:?}",
diagnostic.level));
}panic!("bad level: {:?}", diagnostic.level),
1300 Allow => {
1301 if diagnostic.has_future_breakage() {
1303 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1305 self.suppressed_expected_diag = true;
1306 }
1307 return None;
1308 }
1309 Expect | ForceWarning => {
1310 self.fulfilled_expectations.insert(diagnostic.lint_id.unwrap());
1311 if let Expect = diagnostic.level {
1312 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1314 self.suppressed_expected_diag = true;
1315 return None;
1316 }
1317 }
1318 }
1319
1320 TRACK_DIAGNOSTIC(diagnostic, &mut |mut diagnostic| {
1321 if let Some(code) = diagnostic.code {
1322 self.emitted_diagnostic_codes.insert(code);
1323 }
1324
1325 let already_emitted = {
1326 let mut hasher = StableHasher::new();
1327 diagnostic.hash(&mut hasher);
1328 let diagnostic_hash = hasher.finish();
1329 !self.emitted_diagnostics.insert(diagnostic_hash)
1330 };
1331
1332 let is_error = diagnostic.is_error();
1333 let is_lint = diagnostic.is_lint.is_some();
1334
1335 if !(self.flags.deduplicate_diagnostics && already_emitted) {
1338 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_errors/src/lib.rs:1338",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1338u32),
::tracing_core::__macro_support::Option::Some("rustc_errors"),
::tracing_core::field::FieldSet::new(&["diagnostic"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&diagnostic)
as &dyn Value))])
});
} else { ; }
};debug!(?diagnostic);
1339 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_errors/src/lib.rs:1339",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1339u32),
::tracing_core::__macro_support::Option::Some("rustc_errors"),
::tracing_core::field::FieldSet::new(&["self.emitted_diagnostics"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&self.emitted_diagnostics)
as &dyn Value))])
});
} else { ; }
};debug!(?self.emitted_diagnostics);
1340
1341 let not_yet_emitted = |sub: &mut Subdiag| {
1342 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_errors/src/lib.rs:1342",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1342u32),
::tracing_core::__macro_support::Option::Some("rustc_errors"),
::tracing_core::field::FieldSet::new(&["sub"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&sub) as
&dyn Value))])
});
} else { ; }
};debug!(?sub);
1343 if sub.level != OnceNote && sub.level != OnceHelp {
1344 return true;
1345 }
1346 let mut hasher = StableHasher::new();
1347 sub.hash(&mut hasher);
1348 let diagnostic_hash = hasher.finish();
1349 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_errors/src/lib.rs:1349",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1349u32),
::tracing_core::__macro_support::Option::Some("rustc_errors"),
::tracing_core::field::FieldSet::new(&["diagnostic_hash"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&diagnostic_hash)
as &dyn Value))])
});
} else { ; }
};debug!(?diagnostic_hash);
1350 self.emitted_diagnostics.insert(diagnostic_hash)
1351 };
1352 diagnostic.children.retain_mut(not_yet_emitted);
1353 if already_emitted {
1354 let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`";
1355 diagnostic.sub(Note, msg, MultiSpan::new());
1356 }
1357
1358 if is_error {
1359 self.deduplicated_err_count += 1;
1360 } else if #[allow(non_exhaustive_omitted_patterns)] match diagnostic.level {
ForceWarning | Warning => true,
_ => false,
}matches!(diagnostic.level, ForceWarning | Warning) {
1361 self.deduplicated_warn_count += 1;
1362 }
1363 self.has_printed = true;
1364
1365 self.emitter.emit_diagnostic(diagnostic, &self.registry);
1366 }
1367
1368 if is_error {
1369 if !self.delayed_bugs.is_empty() {
1374 match (&(self.lint_err_guars.len() + self.err_guars.len()), &0) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(self.lint_err_guars.len() + self.err_guars.len(), 0);
1375 self.delayed_bugs.clear();
1376 self.delayed_bugs.shrink_to_fit();
1377 }
1378
1379 #[allow(deprecated)]
1382 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
1383 if is_lint {
1384 self.lint_err_guars.push(guar);
1385 } else {
1386 if let Some(taint) = taint {
1387 taint.set(Some(guar));
1388 }
1389 self.err_guars.push(guar);
1390 }
1391 self.panic_if_treat_err_as_bug();
1392 Some(guar)
1393 } else {
1394 None
1395 }
1396 })
1397 }
1398
1399 fn treat_err_as_bug(&self) -> bool {
1400 self.flags
1401 .treat_err_as_bug
1402 .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() >= c.get())
1403 }
1404
1405 fn treat_next_err_as_bug(&self) -> bool {
1407 self.flags
1408 .treat_err_as_bug
1409 .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() + 1 >= c.get())
1410 }
1411
1412 fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
1413 self.err_guars.get(0).copied().or_else(|| {
1414 if let Some((_diag, guar)) = self
1415 .stashed_diagnostics
1416 .values()
1417 .flat_map(|stashed_diagnostics| stashed_diagnostics.values())
1418 .find(|(diag, guar)| guar.is_some() && diag.is_lint.is_none())
1419 {
1420 *guar
1421 } else {
1422 None
1423 }
1424 })
1425 }
1426
1427 fn has_errors(&self) -> Option<ErrorGuaranteed> {
1428 self.err_guars.get(0).copied().or_else(|| self.lint_err_guars.get(0).copied()).or_else(
1429 || {
1430 self.stashed_diagnostics.values().find_map(|stashed_diagnostics| {
1431 stashed_diagnostics.values().find_map(|(_, guar)| *guar)
1432 })
1433 },
1434 )
1435 }
1436
1437 fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
1438 self.has_errors().or_else(|| self.delayed_bugs.get(0).map(|(_, guar)| guar).copied())
1439 }
1440
1441 fn eagerly_translate<'a>(
1443 &self,
1444 message: DiagMessage,
1445 args: impl Iterator<Item = DiagArg<'a>>,
1446 ) -> SubdiagMessage {
1447 SubdiagMessage::Str(Cow::from(self.eagerly_translate_to_string(message, args)))
1448 }
1449
1450 fn eagerly_translate_to_string<'a>(
1452 &self,
1453 message: DiagMessage,
1454 args: impl Iterator<Item = DiagArg<'a>>,
1455 ) -> String {
1456 let args = crate::translation::to_fluent_args(args);
1457 self.emitter
1458 .translator()
1459 .translate_message(&message, &args)
1460 .map_err(Report::new)
1461 .unwrap()
1462 .to_string()
1463 }
1464
1465 fn eagerly_translate_for_subdiag(
1466 &self,
1467 diag: &DiagInner,
1468 msg: impl Into<SubdiagMessage>,
1469 ) -> SubdiagMessage {
1470 let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
1471 self.eagerly_translate(msg, diag.args.iter())
1472 }
1473
1474 fn flush_delayed(&mut self) {
1475 if !self.stashed_diagnostics.is_empty() {
::core::panicking::panic("assertion failed: self.stashed_diagnostics.is_empty()")
};assert!(self.stashed_diagnostics.is_empty());
1479
1480 if !self.err_guars.is_empty() {
1481 return;
1483 }
1484
1485 if self.delayed_bugs.is_empty() {
1486 return;
1488 }
1489
1490 let bugs: Vec<_> =
1491 std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect();
1492
1493 let backtrace = std::env::var_os("RUST_BACKTRACE").as_deref() != Some(OsStr::new("0"));
1494 let decorate = backtrace || self.ice_file.is_none();
1495 let mut out = self
1496 .ice_file
1497 .as_ref()
1498 .and_then(|file| std::fs::File::options().create(true).append(true).open(file).ok());
1499
1500 let note1 = "no errors encountered even though delayed bugs were created";
1505 let note2 = "those delayed bugs will now be shown as internal compiler errors";
1506 self.emit_diagnostic(DiagInner::new(Note, note1), None);
1507 self.emit_diagnostic(DiagInner::new(Note, note2), None);
1508
1509 for bug in bugs {
1510 if let Some(out) = &mut out {
1511 _ = out.write_fmt(format_args!("delayed bug: {0}\n{1}\n",
bug.inner.messages.iter().filter_map(|(msg, _)|
msg.as_str()).collect::<String>(), &bug.note))write!(
1512 out,
1513 "delayed bug: {}\n{}\n",
1514 bug.inner
1515 .messages
1516 .iter()
1517 .filter_map(|(msg, _)| msg.as_str())
1518 .collect::<String>(),
1519 &bug.note
1520 );
1521 }
1522
1523 let mut bug = if decorate { bug.decorate(self) } else { bug.inner };
1524
1525 if bug.level != DelayedBug {
1527 bug.arg("level", bug.level);
1534 let msg = crate::fluent_generated::errors_invalid_flushed_delayed_diagnostic_level;
1535 let msg = self.eagerly_translate_for_subdiag(&bug, msg); bug.sub(Note, msg, bug.span.primary_span().unwrap().into());
1537 }
1538 bug.level = Bug;
1539
1540 self.emit_diagnostic(bug, None);
1541 }
1542
1543 panic::panic_any(DelayedBugPanic);
1545 }
1546
1547 fn panic_if_treat_err_as_bug(&self) {
1548 if self.treat_err_as_bug() {
1549 let n = self.flags.treat_err_as_bug.map(|c| c.get()).unwrap();
1550 match (&n, &(self.err_guars.len() + self.lint_err_guars.len())) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(n, self.err_guars.len() + self.lint_err_guars.len());
1551 if n == 1 {
1552 {
::core::panicking::panic_fmt(format_args!("aborting due to `-Z treat-err-as-bug=1`"));
};panic!("aborting due to `-Z treat-err-as-bug=1`");
1553 } else {
1554 {
::core::panicking::panic_fmt(format_args!("aborting after {0} errors due to `-Z treat-err-as-bug={0}`",
n));
};panic!("aborting after {n} errors due to `-Z treat-err-as-bug={n}`");
1555 }
1556 }
1557 }
1558}
1559
1560struct DelayedDiagInner {
1561 inner: DiagInner,
1562 note: Backtrace,
1563}
1564
1565impl DelayedDiagInner {
1566 fn with_backtrace(diagnostic: DiagInner, backtrace: Backtrace) -> Self {
1567 DelayedDiagInner { inner: diagnostic, note: backtrace }
1568 }
1569
1570 fn decorate(self, dcx: &DiagCtxtInner) -> DiagInner {
1571 let mut diag = self.inner;
1575 let msg = match self.note.status() {
1576 BacktraceStatus::Captured => crate::fluent_generated::errors_delayed_at_with_newline,
1577 _ => crate::fluent_generated::errors_delayed_at_without_newline,
1580 };
1581 diag.arg("emitted_at", diag.emitted_at.clone());
1582 diag.arg("note", self.note);
1583 let msg = dcx.eagerly_translate_for_subdiag(&diag, msg); diag.sub(Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into());
1585 diag
1586 }
1587}
1588
1589#[derive(#[automatically_derived]
impl ::core::marker::Copy for Level { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Level {
#[inline]
fn eq(&self, other: &Level) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Level {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::clone::Clone for Level {
#[inline]
fn clone(&self) -> Level { *self }
}Clone, #[automatically_derived]
impl ::core::hash::Hash for Level {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Level {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Level::Bug => "Bug",
Level::Fatal => "Fatal",
Level::Error => "Error",
Level::DelayedBug => "DelayedBug",
Level::ForceWarning => "ForceWarning",
Level::Warning => "Warning",
Level::Note => "Note",
Level::OnceNote => "OnceNote",
Level::Help => "Help",
Level::OnceHelp => "OnceHelp",
Level::FailureNote => "FailureNote",
Level::Allow => "Allow",
Level::Expect => "Expect",
})
}
}Debug, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for Level {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
Level::Bug => { 0usize }
Level::Fatal => { 1usize }
Level::Error => { 2usize }
Level::DelayedBug => { 3usize }
Level::ForceWarning => { 4usize }
Level::Warning => { 5usize }
Level::Note => { 6usize }
Level::OnceNote => { 7usize }
Level::Help => { 8usize }
Level::OnceHelp => { 9usize }
Level::FailureNote => { 10usize }
Level::Allow => { 11usize }
Level::Expect => { 12usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
Level::Bug => {}
Level::Fatal => {}
Level::Error => {}
Level::DelayedBug => {}
Level::ForceWarning => {}
Level::Warning => {}
Level::Note => {}
Level::OnceNote => {}
Level::Help => {}
Level::OnceHelp => {}
Level::FailureNote => {}
Level::Allow => {}
Level::Expect => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for Level {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { Level::Bug }
1usize => { Level::Fatal }
2usize => { Level::Error }
3usize => { Level::DelayedBug }
4usize => { Level::ForceWarning }
5usize => { Level::Warning }
6usize => { Level::Note }
7usize => { Level::OnceNote }
8usize => { Level::Help }
9usize => { Level::OnceHelp }
10usize => { Level::FailureNote }
11usize => { Level::Allow }
12usize => { Level::Expect }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Level`, expected 0..13, actual {0}",
n));
}
}
}
}
};Decodable)]
1609pub enum Level {
1610 Bug,
1612
1613 Fatal,
1616
1617 Error,
1620
1621 DelayedBug,
1626
1627 ForceWarning,
1633
1634 Warning,
1637
1638 Note,
1640
1641 OnceNote,
1643
1644 Help,
1646
1647 OnceHelp,
1649
1650 FailureNote,
1653
1654 Allow,
1656
1657 Expect,
1659}
1660
1661impl fmt::Display for Level {
1662 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1663 self.to_str().fmt(f)
1664 }
1665}
1666
1667impl Level {
1668 fn color(self) -> anstyle::Style {
1669 match self {
1670 Bug | Fatal | Error | DelayedBug => AnsiColor::BrightRed.on_default(),
1671 ForceWarning | Warning => {
1672 if falsecfg!(windows) {
1673 AnsiColor::BrightYellow.on_default()
1674 } else {
1675 AnsiColor::Yellow.on_default()
1676 }
1677 }
1678 Note | OnceNote => AnsiColor::BrightGreen.on_default(),
1679 Help | OnceHelp => AnsiColor::BrightCyan.on_default(),
1680 FailureNote => anstyle::Style::new(),
1681 Allow | Expect => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1682 }
1683 }
1684
1685 pub fn to_str(self) -> &'static str {
1686 match self {
1687 Bug | DelayedBug => "error: internal compiler error",
1688 Fatal | Error => "error",
1689 ForceWarning | Warning => "warning",
1690 Note | OnceNote => "note",
1691 Help | OnceHelp => "help",
1692 FailureNote => "failure-note",
1693 Allow | Expect => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1694 }
1695 }
1696
1697 pub fn is_failure_note(&self) -> bool {
1698 #[allow(non_exhaustive_omitted_patterns)] match *self {
FailureNote => true,
_ => false,
}matches!(*self, FailureNote)
1699 }
1700}
1701
1702impl IntoDiagArg for Level {
1703 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
1704 DiagArgValue::Str(Cow::from(self.to_string()))
1705 }
1706}
1707
1708#[derive(#[automatically_derived]
impl ::core::marker::Copy for Style { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Style {
#[inline]
fn clone(&self) -> Style {
let _: ::core::clone::AssertParamIsClone<Level>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Style {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Style::MainHeaderMsg =>
::core::fmt::Formatter::write_str(f, "MainHeaderMsg"),
Style::HeaderMsg =>
::core::fmt::Formatter::write_str(f, "HeaderMsg"),
Style::LineAndColumn =>
::core::fmt::Formatter::write_str(f, "LineAndColumn"),
Style::LineNumber =>
::core::fmt::Formatter::write_str(f, "LineNumber"),
Style::Quotation =>
::core::fmt::Formatter::write_str(f, "Quotation"),
Style::UnderlinePrimary =>
::core::fmt::Formatter::write_str(f, "UnderlinePrimary"),
Style::UnderlineSecondary =>
::core::fmt::Formatter::write_str(f, "UnderlineSecondary"),
Style::LabelPrimary =>
::core::fmt::Formatter::write_str(f, "LabelPrimary"),
Style::LabelSecondary =>
::core::fmt::Formatter::write_str(f, "LabelSecondary"),
Style::NoStyle => ::core::fmt::Formatter::write_str(f, "NoStyle"),
Style::Level(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Level",
&__self_0),
Style::Highlight =>
::core::fmt::Formatter::write_str(f, "Highlight"),
Style::Addition =>
::core::fmt::Formatter::write_str(f, "Addition"),
Style::Removal => ::core::fmt::Formatter::write_str(f, "Removal"),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Style {
#[inline]
fn eq(&self, other: &Style) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(Style::Level(__self_0), Style::Level(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Style {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Level>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Style {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
Style::Level(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for Style {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
Style::MainHeaderMsg => { 0usize }
Style::HeaderMsg => { 1usize }
Style::LineAndColumn => { 2usize }
Style::LineNumber => { 3usize }
Style::Quotation => { 4usize }
Style::UnderlinePrimary => { 5usize }
Style::UnderlineSecondary => { 6usize }
Style::LabelPrimary => { 7usize }
Style::LabelSecondary => { 8usize }
Style::NoStyle => { 9usize }
Style::Level(ref __binding_0) => { 10usize }
Style::Highlight => { 11usize }
Style::Addition => { 12usize }
Style::Removal => { 13usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
Style::MainHeaderMsg => {}
Style::HeaderMsg => {}
Style::LineAndColumn => {}
Style::LineNumber => {}
Style::Quotation => {}
Style::UnderlinePrimary => {}
Style::UnderlineSecondary => {}
Style::LabelPrimary => {}
Style::LabelSecondary => {}
Style::NoStyle => {}
Style::Level(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
Style::Highlight => {}
Style::Addition => {}
Style::Removal => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for Style {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { Style::MainHeaderMsg }
1usize => { Style::HeaderMsg }
2usize => { Style::LineAndColumn }
3usize => { Style::LineNumber }
4usize => { Style::Quotation }
5usize => { Style::UnderlinePrimary }
6usize => { Style::UnderlineSecondary }
7usize => { Style::LabelPrimary }
8usize => { Style::LabelSecondary }
9usize => { Style::NoStyle }
10usize => {
Style::Level(::rustc_serialize::Decodable::decode(__decoder))
}
11usize => { Style::Highlight }
12usize => { Style::Addition }
13usize => { Style::Removal }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Style`, expected 0..14, actual {0}",
n));
}
}
}
}
};Decodable)]
1709pub enum Style {
1710 MainHeaderMsg,
1711 HeaderMsg,
1712 LineAndColumn,
1713 LineNumber,
1714 Quotation,
1715 UnderlinePrimary,
1716 UnderlineSecondary,
1717 LabelPrimary,
1718 LabelSecondary,
1719 NoStyle,
1720 Level(Level),
1721 Highlight,
1722 Addition,
1723 Removal,
1724}
1725
1726pub fn elided_lifetime_in_path_suggestion(
1728 source_map: &SourceMap,
1729 n: usize,
1730 path_span: Span,
1731 incl_angl_brckt: bool,
1732 insertion_span: Span,
1733) -> ElidedLifetimeInPathSubdiag {
1734 let expected = ExpectedLifetimeParameter { span: path_span, count: n };
1735 let indicate = source_map.is_span_accessible(insertion_span).then(|| {
1737 let anon_lts = ::alloc::vec::from_elem("'_", n)vec!["'_"; n].join(", ");
1738 let suggestion =
1739 if incl_angl_brckt { ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("<{0}>", anon_lts))
})format!("<{anon_lts}>") } else { ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}, ", anon_lts))
})format!("{anon_lts}, ") };
1740
1741 IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion }
1742 });
1743
1744 ElidedLifetimeInPathSubdiag { expected, indicate }
1745}
1746
1747pub fn a_or_an(s: &str) -> &'static str {
1751 let mut chars = s.chars();
1752 let Some(mut first_alpha_char) = chars.next() else {
1753 return "a";
1754 };
1755 if first_alpha_char == '`' {
1756 let Some(next) = chars.next() else {
1757 return "a";
1758 };
1759 first_alpha_char = next;
1760 }
1761 if ["a", "e", "i", "o", "u", "&"].contains(&&first_alpha_char.to_lowercase().to_string()[..]) {
1762 "an"
1763 } else {
1764 "a"
1765 }
1766}
1767
1768#[derive(#[automatically_derived]
impl ::core::clone::Clone for TerminalUrl {
#[inline]
fn clone(&self) -> TerminalUrl { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for TerminalUrl { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for TerminalUrl {
#[inline]
fn eq(&self, other: &TerminalUrl) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for TerminalUrl {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for TerminalUrl {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
TerminalUrl::No => "No",
TerminalUrl::Yes => "Yes",
TerminalUrl::Auto => "Auto",
})
}
}Debug)]
1769pub enum TerminalUrl {
1770 No,
1771 Yes,
1772 Auto,
1773}