1#![allow(internal_features)]
7#![allow(rustc::direct_use_of_rustc_type_ir)]
8#![feature(associated_type_defaults)]
9#![feature(default_field_values)]
10#![feature(macro_metavar_expr_concat)]
11#![feature(negative_impls)]
12#![feature(never_type)]
13#![feature(rustc_attrs)]
14extern crate self as rustc_errors;
17
18use std::backtrace::{Backtrace, BacktraceStatus};
19use std::borrow::Cow;
20use std::cell::Cell;
21use std::ffi::OsStr;
22use std::hash::Hash;
23use std::io::Write;
24use std::num::NonZero;
25use std::ops::DerefMut;
26use std::path::{Path, PathBuf};
27use std::{assert_matches, fmt, panic};
28
29use Level::*;
30pub use anstream::{AutoStream, ColorChoice};
33pub use anstyle::{
34 Ansi256Color, AnsiColor, Color, EffectIter, Effects, Reset, RgbColor, Style as Anstyle,
35};
36pub use codes::*;
37pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer};
38pub use diagnostic::{
39 BugAbort, Diag, DiagDecorator, DiagInner, DiagLocation, DiagStyledString, Diagnostic,
40 EmissionGuarantee, FatalAbort, StringPart, Subdiag, Subdiagnostic,
41};
42pub use diagnostic_impls::{
43 DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
44 IndicateAnonymousLifetime, SingleLabelManySpans,
45};
46pub use emitter::ColorConfig;
47use emitter::{DynEmitter, Emitter};
48use rustc_data_structures::AtomicRef;
49use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
50use rustc_data_structures::stable_hasher::StableHasher;
51use rustc_data_structures::sync::{DynSend, Lock};
52pub use rustc_error_messages::{
53 DiagArg, DiagArgFromDisplay, DiagArgMap, DiagArgName, DiagArgValue, DiagMessage, IntoDiagArg,
54 LanguageIdentifier, MultiSpan, SpanLabel, fluent_bundle, into_diag_arg_using_display,
55};
56use rustc_hashes::Hash128;
57use rustc_lint_defs::LintExpectationId;
58pub use rustc_lint_defs::{Applicability, listify, pluralize};
59pub use rustc_macros::msg;
60use rustc_macros::{Decodable, Encodable};
61pub use rustc_span::ErrorGuaranteed;
62pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker, catch_fatal_errors};
63use rustc_span::source_map::SourceMap;
64use rustc_span::{DUMMY_SP, Span};
65use tracing::debug;
66
67use crate::emitter::TimingEvent;
68use crate::formatting::DiagMessageAddArg;
69pub use crate::formatting::format_diag_message;
70use crate::timings::TimingRecord;
71
72pub mod annotate_snippet_emitter_writer;
73pub mod codes;
74mod decorate_diag;
75mod diagnostic;
76mod diagnostic_impls;
77pub mod emitter;
78pub mod formatting;
79pub mod json;
80mod lock;
81pub mod markdown;
82pub mod timings;
83
84pub type PResult<'a, T> = Result<T, Diag<'a>>;
85
86#[cfg(target_pointer_width = "64")]
88const _: [(); 24] = [(); ::std::mem::size_of::<PResult<'_, ()>>()];rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24);
89#[cfg(target_pointer_width = "64")]
90const _: [(); 24] = [(); ::std::mem::size_of::<PResult<'_, bool>>()];rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
91
92#[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_fields_are_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)]
93pub enum SuggestionStyle {
94 HideCodeInline,
96 HideCodeAlways,
98 CompletelyHidden,
100 ShowCode,
104 ShowAlways,
106}
107
108impl SuggestionStyle {
109 fn hide_inline(&self) -> bool {
110 !#[allow(non_exhaustive_omitted_patterns)] match *self {
SuggestionStyle::ShowCode => true,
_ => false,
}matches!(*self, SuggestionStyle::ShowCode)
111 }
112}
113
114#[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)]
116pub enum Suggestions {
117 Enabled(Vec<CodeSuggestion>),
122 Sealed(Box<[CodeSuggestion]>),
126 Disabled,
130}
131
132impl Suggestions {
133 pub fn unwrap_tag(self) -> Vec<CodeSuggestion> {
135 match self {
136 Suggestions::Enabled(suggestions) => suggestions,
137 Suggestions::Sealed(suggestions) => suggestions.into_vec(),
138 Suggestions::Disabled => Vec::new(),
139 }
140 }
141
142 pub fn len(&self) -> usize {
143 match self {
144 Suggestions::Enabled(suggestions) => suggestions.len(),
145 Suggestions::Sealed(suggestions) => suggestions.len(),
146 Suggestions::Disabled => 0,
147 }
148 }
149}
150
151impl Default for Suggestions {
152 fn default() -> Self {
153 Self::Enabled(::alloc::vec::Vec::new()vec![])
154 }
155}
156
157#[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)]
158pub struct CodeSuggestion {
159 pub substitutions: Vec<Substitution>,
181 pub msg: DiagMessage,
182 pub style: SuggestionStyle,
184 pub applicability: Applicability,
190}
191
192#[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)]
193pub struct Substitution {
195 pub parts: Vec<SubstitutionPart>,
196}
197
198#[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)]
199pub struct SubstitutionPart {
200 pub span: Span,
201 pub snippet: String,
202}
203
204#[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)]
205pub struct TrimmedSubstitutionPart {
206 pub original_span: Span,
207 pub span: Span,
208 pub snippet: String,
209}
210
211impl TrimmedSubstitutionPart {
212 pub fn is_addition(&self, sm: &SourceMap) -> bool {
213 !self.snippet.is_empty() && !self.replaces_meaningful_content(sm)
214 }
215
216 pub fn is_deletion(&self, sm: &SourceMap) -> bool {
217 self.snippet.trim().is_empty() && self.replaces_meaningful_content(sm)
218 }
219
220 pub fn is_replacement(&self, sm: &SourceMap) -> bool {
221 !self.snippet.is_empty() && self.replaces_meaningful_content(sm)
222 }
223
224 pub fn is_destructive_replacement(&self, sm: &SourceMap) -> bool {
229 self.is_replacement(sm)
230 && !sm
231 .span_to_snippet(self.span)
232 .is_ok_and(|snippet| as_substr(snippet.trim(), self.snippet.trim()).is_some())
233 }
234
235 fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool {
236 sm.span_to_snippet(self.span)
237 .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty())
238 }
239}
240
241fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a str, usize)> {
246 let common_prefix = original
247 .chars()
248 .zip(suggestion.chars())
249 .take_while(|(c1, c2)| c1 == c2)
250 .map(|(c, _)| c.len_utf8())
251 .sum();
252 let original = &original[common_prefix..];
253 let suggestion = &suggestion[common_prefix..];
254 if suggestion.ends_with(original) {
255 let common_suffix = original.len();
256 Some((common_prefix, &suggestion[..suggestion.len() - original.len()], common_suffix))
257 } else {
258 None
259 }
260}
261
262pub struct ExplicitBug;
265
266pub struct DelayedBugPanic;
269
270pub struct DiagCtxt {
274 inner: Lock<DiagCtxtInner>,
275}
276
277#[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)]
278pub struct DiagCtxtHandle<'a> {
279 dcx: &'a DiagCtxt,
280 tainted_with_errors: Option<&'a Cell<Option<ErrorGuaranteed>>>,
283}
284
285impl<'a> std::ops::Deref for DiagCtxtHandle<'a> {
286 type Target = &'a DiagCtxt;
287
288 fn deref(&self) -> &Self::Target {
289 &self.dcx
290 }
291}
292
293struct DiagCtxtInner {
297 flags: DiagCtxtFlags,
298
299 err_guars: Vec<ErrorGuaranteed>,
301 lint_err_guars: Vec<ErrorGuaranteed>,
304 delayed_bugs: Vec<(DelayedDiagInner, ErrorGuaranteed)>,
306
307 deduplicated_err_count: usize,
309 deduplicated_warn_count: usize,
311
312 emitter: Box<DynEmitter>,
313
314 must_produce_diag: Option<Backtrace>,
317
318 has_printed: bool,
321
322 suppressed_expected_diag: bool,
325
326 taught_diagnostics: FxHashSet<ErrCode>,
330
331 emitted_diagnostic_codes: FxIndexSet<ErrCode>,
333
334 emitted_diagnostics: FxHashSet<Hash128>,
338
339 stashed_diagnostics:
345 FxIndexMap<StashKey, FxIndexMap<Span, (DiagInner, Option<ErrorGuaranteed>)>>,
346
347 future_breakage_diagnostics: Vec<DiagInner>,
348
349 fulfilled_expectations: FxIndexSet<LintExpectationId>,
361
362 ice_file: Option<PathBuf>,
365}
366
367#[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_fields_are_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::UndeterminedMacroResolution =>
"UndeterminedMacroResolution",
StashKey::ExprInPat => "ExprInPat",
StashKey::GenericInFieldExpr => "GenericInFieldExpr",
StashKey::ReturnTypeNotation => "ReturnTypeNotation",
})
}
}Debug)]
369pub enum StashKey {
370 ItemNoType,
371 UnderscoreForArrayLengths,
372 EarlySyntaxWarning,
373 CallIntoMethod,
374 LifetimeIsChar,
377 MaybeFruTypo,
380 CallAssocMethod,
381 AssociatedTypeSuggestion,
382 UndeterminedMacroResolution,
383 ExprInPat,
385 GenericInFieldExpr,
389 ReturnTypeNotation,
390}
391
392fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
393 (*f)(diag)
394}
395
396pub static TRACK_DIAGNOSTIC: AtomicRef<
399 fn(DiagInner, &mut dyn FnMut(DiagInner) -> Option<ErrorGuaranteed>) -> Option<ErrorGuaranteed>,
400> = AtomicRef::new(&(default_track_diagnostic as _));
401
402#[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)]
403pub struct DiagCtxtFlags {
404 pub can_emit_warnings: bool,
407 pub treat_err_as_bug: Option<NonZero<usize>>,
410 pub eagerly_emit_delayed_bugs: bool,
413 pub macro_backtrace: bool,
416 pub deduplicate_diagnostics: bool,
418 pub track_diagnostics: bool,
420}
421
422impl Drop for DiagCtxtInner {
423 fn drop(&mut self) {
424 self.emit_stashed_diagnostics();
432
433 self.flush_delayed();
437
438 if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() {
442 if let Some(backtrace) = &self.must_produce_diag {
443 let suggestion = match backtrace.status() {
444 BacktraceStatus::Disabled => String::from(
445 "Backtraces are currently disabled: set `RUST_BACKTRACE=1` and re-run \
446 to see where it happened.",
447 ),
448 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!(
449 "This happened in the following `must_produce_diag` call's backtrace:\n\
450 {backtrace}",
451 ),
452 _ => String::from("(impossible to capture backtrace where this happened)"),
453 };
454 {
::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!(
455 "`trimmed_def_paths` called, diagnostics were expected but none were emitted. \
456 Use `with_no_trimmed_paths` for debugging. {suggestion}"
457 );
458 }
459 }
460 }
461}
462
463impl DiagCtxt {
464 pub fn disable_warnings(mut self) -> Self {
465 self.inner.get_mut().flags.can_emit_warnings = false;
466 self
467 }
468
469 pub fn with_flags(mut self, flags: DiagCtxtFlags) -> Self {
470 self.inner.get_mut().flags = flags;
471 self
472 }
473
474 pub fn with_ice_file(mut self, ice_file: PathBuf) -> Self {
475 self.inner.get_mut().ice_file = Some(ice_file);
476 self
477 }
478
479 pub fn new(emitter: Box<DynEmitter>) -> Self {
480 Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
481 }
482
483 pub fn make_silent(&self) {
484 let mut inner = self.inner.borrow_mut();
485 inner.emitter = Box::new(emitter::SilentEmitter {});
486 }
487
488 pub fn set_emitter(&self, emitter: Box<dyn Emitter + DynSend>) {
489 self.inner.borrow_mut().emitter = emitter;
490 }
491
492 pub fn can_emit_warnings(&self) -> bool {
496 self.inner.borrow_mut().flags.can_emit_warnings
497 }
498
499 pub fn reset_err_count(&self) {
505 let mut inner = self.inner.borrow_mut();
508 let DiagCtxtInner {
509 flags: _,
510 err_guars,
511 lint_err_guars,
512 delayed_bugs,
513 deduplicated_err_count,
514 deduplicated_warn_count,
515 emitter: _,
516 must_produce_diag,
517 has_printed,
518 suppressed_expected_diag,
519 taught_diagnostics,
520 emitted_diagnostic_codes,
521 emitted_diagnostics,
522 stashed_diagnostics,
523 future_breakage_diagnostics,
524 fulfilled_expectations,
525 ice_file: _,
526 } = inner.deref_mut();
527
528 *err_guars = Default::default();
531 *lint_err_guars = Default::default();
532 *delayed_bugs = Default::default();
533 *deduplicated_err_count = 0;
534 *deduplicated_warn_count = 0;
535 *must_produce_diag = None;
536 *has_printed = false;
537 *suppressed_expected_diag = false;
538 *taught_diagnostics = Default::default();
539 *emitted_diagnostic_codes = Default::default();
540 *emitted_diagnostics = Default::default();
541 *stashed_diagnostics = Default::default();
542 *future_breakage_diagnostics = Default::default();
543 *fulfilled_expectations = Default::default();
544 }
545
546 pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> {
547 DiagCtxtHandle { dcx: self, tainted_with_errors: None }
548 }
549
550 pub fn taintable_handle<'a>(
554 &'a self,
555 tainted_with_errors: &'a Cell<Option<ErrorGuaranteed>>,
556 ) -> DiagCtxtHandle<'a> {
557 DiagCtxtHandle { dcx: self, tainted_with_errors: Some(tainted_with_errors) }
558 }
559}
560
561impl<'a> DiagCtxtHandle<'a> {
562 pub fn stash_diagnostic(
584 &self,
585 span: Span,
586 key: StashKey,
587 diag: DiagInner,
588 ) -> Option<ErrorGuaranteed> {
589 let guar = match diag.level {
590 Bug | Fatal => {
591 self.span_bug(
592 span,
593 ::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),
594 );
595 }
596 Error => Some(self.span_delayed_bug(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("stashing {0:?}", key))
})format!("stashing {key:?}"))),
600 DelayedBug => {
601 return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors);
602 }
603 ForceWarning | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
604 | Expect => None,
605 };
606
607 self.inner
611 .borrow_mut()
612 .stashed_diagnostics
613 .entry(key)
614 .or_default()
615 .insert(span.with_parent(None), (diag, guar));
616
617 guar
618 }
619
620 pub fn steal_non_err(self, span: Span, key: StashKey) -> Option<Diag<'a, ()>> {
624 let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
626 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
627 )?;
628 if !!diag.is_error() {
::core::panicking::panic("assertion failed: !diag.is_error()")
};assert!(!diag.is_error());
629 if !guar.is_none() {
::core::panicking::panic("assertion failed: guar.is_none()")
};assert!(guar.is_none());
630 Some(Diag::new_diagnostic(self, diag))
631 }
632
633 pub fn try_steal_modify_and_emit_err<F>(
638 self,
639 span: Span,
640 key: StashKey,
641 mut modify_err: F,
642 ) -> Option<ErrorGuaranteed>
643 where
644 F: FnMut(&mut Diag<'_>),
645 {
646 let err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
648 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
649 );
650 err.map(|(err, guar)| {
651 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);
653 if !guar.is_some() {
::core::panicking::panic("assertion failed: guar.is_some()")
};assert!(guar.is_some());
654 let mut err = Diag::<ErrorGuaranteed>::new_diagnostic(self, err);
655 modify_err(&mut err);
656 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);
657 err.emit()
658 })
659 }
660
661 pub fn try_steal_replace_and_emit_err(
665 self,
666 span: Span,
667 key: StashKey,
668 new_err: Diag<'_>,
669 ) -> ErrorGuaranteed {
670 let old_err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
672 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
673 );
674 match old_err {
675 Some((old_err, guar)) => {
676 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);
677 if !guar.is_some() {
::core::panicking::panic("assertion failed: guar.is_some()")
};assert!(guar.is_some());
678 Diag::<ErrorGuaranteed>::new_diagnostic(self, old_err).cancel();
681 }
682 None => {}
683 };
684 new_err.emit()
685 }
686
687 pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool {
688 let inner = self.inner.borrow();
689 if let Some(stashed_diagnostics) = inner.stashed_diagnostics.get(&key)
690 && !stashed_diagnostics.is_empty()
691 {
692 stashed_diagnostics.contains_key(&span.with_parent(None))
693 } else {
694 false
695 }
696 }
697
698 pub fn emit_stashed_diagnostics(&self) -> Option<ErrorGuaranteed> {
700 self.inner.borrow_mut().emit_stashed_diagnostics()
701 }
702
703 #[inline]
705 pub fn err_count(&self) -> usize {
706 let inner = self.inner.borrow();
707 inner.err_guars.len()
708 + inner.lint_err_guars.len()
709 + inner
710 .stashed_diagnostics
711 .values()
712 .map(|a| a.values().filter(|(_, guar)| guar.is_some()).count())
713 .sum::<usize>()
714 }
715
716 pub fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
719 self.inner.borrow().has_errors_excluding_lint_errors()
720 }
721
722 pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
724 self.inner.borrow().has_errors()
725 }
726
727 pub fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
730 self.inner.borrow().has_errors_or_delayed_bugs()
731 }
732
733 pub fn print_error_count(&self) {
734 let mut inner = self.inner.borrow_mut();
735
736 if !inner.stashed_diagnostics.is_empty() {
::core::panicking::panic("assertion failed: inner.stashed_diagnostics.is_empty()")
};assert!(inner.stashed_diagnostics.is_empty());
739
740 if inner.treat_err_as_bug() {
741 return;
742 }
743
744 let warnings = match inner.deduplicated_warn_count {
745 0 => Cow::from(""),
746 1 => Cow::from("1 warning emitted"),
747 count => Cow::from(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} warnings emitted", count))
})format!("{count} warnings emitted")),
748 };
749 let errors = match inner.deduplicated_err_count {
750 0 => Cow::from(""),
751 1 => Cow::from("aborting due to 1 previous error"),
752 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")),
753 };
754
755 match (errors.len(), warnings.len()) {
756 (0, 0) => return,
757 (0, _) => {
758 inner.emit_diagnostic(
761 DiagInner::new(ForceWarning, DiagMessage::Str(warnings)),
762 None,
763 );
764 }
765 (_, 0) => {
766 inner.emit_diagnostic(DiagInner::new(Error, errors), self.tainted_with_errors);
767 }
768 (_, _) => {
769 inner.emit_diagnostic(
770 DiagInner::new(Error, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}; {1}", errors, warnings))
})format!("{errors}; {warnings}")),
771 self.tainted_with_errors,
772 );
773 }
774 }
775
776 let can_show_explain = inner.emitter.should_show_explain();
777 let are_there_diagnostics = !inner.emitted_diagnostic_codes.is_empty();
778 if can_show_explain && are_there_diagnostics {
779 let mut error_codes = inner
780 .emitted_diagnostic_codes
781 .iter()
782 .filter_map(|&code| {
783 if crate::codes::try_find_description(code).is_ok() {
784 Some(code.to_string())
785 } else {
786 None
787 }
788 })
789 .collect::<Vec<_>>();
790 if !error_codes.is_empty() {
791 error_codes.sort();
792 if error_codes.len() > 1 {
793 let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
794 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!(
795 "Some errors have detailed explanations: {}{}",
796 error_codes[..limit].join(", "),
797 if error_codes.len() > 9 { "..." } else { "." }
798 );
799 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!(
800 "For more information about an error, try `rustc --explain {}`.",
801 &error_codes[0]
802 );
803 inner.emit_diagnostic(DiagInner::new(FailureNote, msg1), None);
804 inner.emit_diagnostic(DiagInner::new(FailureNote, msg2), None);
805 } else {
806 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!(
807 "For more information about this error, try `rustc --explain {}`.",
808 &error_codes[0]
809 );
810 inner.emit_diagnostic(DiagInner::new(FailureNote, msg), None);
811 }
812 }
813 }
814 }
815
816 pub fn abort_if_errors(&self) {
821 if let Some(guar) = self.has_errors() {
822 guar.raise_fatal();
823 }
824 }
825
826 pub fn must_teach(&self, code: ErrCode) -> bool {
832 self.inner.borrow_mut().taught_diagnostics.insert(code)
833 }
834
835 pub fn emit_diagnostic(&self, diagnostic: DiagInner) -> Option<ErrorGuaranteed> {
836 self.inner.borrow_mut().emit_diagnostic(diagnostic, self.tainted_with_errors)
837 }
838
839 pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
840 self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type);
841 }
842
843 pub fn emit_timing_section_start(&self, record: TimingRecord) {
844 self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::Start);
845 }
846
847 pub fn emit_timing_section_end(&self, record: TimingRecord) {
848 self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::End);
849 }
850
851 pub fn emit_future_breakage_report(&self) {
852 let inner = &mut *self.inner.borrow_mut();
853 let diags = std::mem::take(&mut inner.future_breakage_diagnostics);
854 if !diags.is_empty() {
855 inner.emitter.emit_future_breakage_report(diags);
856 }
857 }
858
859 pub fn emit_unused_externs(
860 &self,
861 lint_level: rustc_lint_defs::Level,
862 loud: bool,
863 unused_externs: &[&str],
864 ) {
865 let mut inner = self.inner.borrow_mut();
866
867 if loud && lint_level.is_error() {
878 #[allow(deprecated)]
881 inner.lint_err_guars.push(ErrorGuaranteed::unchecked_error_guaranteed());
882 inner.panic_if_treat_err_as_bug();
883 }
884
885 inner.emitter.emit_unused_externs(lint_level, unused_externs)
886 }
887
888 #[must_use]
891 pub fn steal_fulfilled_expectation_ids(&self) -> FxIndexSet<LintExpectationId> {
892 std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations)
893 }
894
895 pub fn flush_delayed(&self) {
900 self.inner.borrow_mut().flush_delayed();
901 }
902
903 #[track_caller]
906 pub fn set_must_produce_diag(&self) {
907 if !self.inner.borrow().must_produce_diag.is_none() {
{
::core::panicking::panic_fmt(format_args!("should only need to collect a backtrace once"));
}
};assert!(
908 self.inner.borrow().must_produce_diag.is_none(),
909 "should only need to collect a backtrace once"
910 );
911 self.inner.borrow_mut().must_produce_diag = Some(Backtrace::capture());
912 }
913}
914
915impl<'a> DiagCtxtHandle<'a> {
920 #[track_caller]
921 pub fn struct_bug(self, msg: impl Into<Cow<'static, str>>) -> Diag<'a, BugAbort> {
922 Diag::new(self, Bug, msg.into())
923 }
924
925 #[track_caller]
926 pub fn bug(self, msg: impl Into<Cow<'static, str>>) -> ! {
927 self.struct_bug(msg).emit()
928 }
929
930 #[track_caller]
931 pub fn struct_span_bug(
932 self,
933 span: impl Into<MultiSpan>,
934 msg: impl Into<Cow<'static, str>>,
935 ) -> Diag<'a, BugAbort> {
936 self.struct_bug(msg).with_span(span)
937 }
938
939 #[track_caller]
940 pub fn span_bug(self, span: impl Into<MultiSpan>, msg: impl Into<Cow<'static, str>>) -> ! {
941 self.struct_span_bug(span, msg.into()).emit()
942 }
943
944 #[track_caller]
945 pub fn create_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> Diag<'a, BugAbort> {
946 bug.into_diag(self, Bug)
947 }
948
949 #[track_caller]
950 pub fn emit_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> ! {
951 self.create_bug(bug).emit()
952 }
953
954 #[track_caller]
955 pub fn struct_fatal(self, msg: impl Into<DiagMessage>) -> Diag<'a, FatalAbort> {
956 Diag::new(self, Fatal, msg)
957 }
958
959 #[track_caller]
960 pub fn fatal(self, msg: impl Into<DiagMessage>) -> ! {
961 self.struct_fatal(msg).emit()
962 }
963
964 #[track_caller]
965 pub fn struct_span_fatal(
966 self,
967 span: impl Into<MultiSpan>,
968 msg: impl Into<DiagMessage>,
969 ) -> Diag<'a, FatalAbort> {
970 self.struct_fatal(msg).with_span(span)
971 }
972
973 #[track_caller]
974 pub fn span_fatal(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) -> ! {
975 self.struct_span_fatal(span, msg).emit()
976 }
977
978 #[track_caller]
979 pub fn create_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> Diag<'a, FatalAbort> {
980 fatal.into_diag(self, Fatal)
981 }
982
983 #[track_caller]
984 pub fn emit_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> ! {
985 self.create_fatal(fatal).emit()
986 }
987
988 #[track_caller]
989 pub fn create_almost_fatal(
990 self,
991 fatal: impl Diagnostic<'a, FatalError>,
992 ) -> Diag<'a, FatalError> {
993 fatal.into_diag(self, Fatal)
994 }
995
996 #[track_caller]
997 pub fn emit_almost_fatal(self, fatal: impl Diagnostic<'a, FatalError>) -> FatalError {
998 self.create_almost_fatal(fatal).emit()
999 }
1000
1001 #[track_caller]
1003 pub fn struct_err(self, msg: impl Into<DiagMessage>) -> Diag<'a> {
1004 Diag::new(self, Error, msg)
1005 }
1006
1007 #[track_caller]
1008 pub fn err(self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
1009 self.struct_err(msg).emit()
1010 }
1011
1012 #[track_caller]
1013 pub fn struct_span_err(
1014 self,
1015 span: impl Into<MultiSpan>,
1016 msg: impl Into<DiagMessage>,
1017 ) -> Diag<'a> {
1018 self.struct_err(msg).with_span(span)
1019 }
1020
1021 #[track_caller]
1022 pub fn span_err(
1023 self,
1024 span: impl Into<MultiSpan>,
1025 msg: impl Into<DiagMessage>,
1026 ) -> ErrorGuaranteed {
1027 self.struct_span_err(span, msg).emit()
1028 }
1029
1030 #[track_caller]
1031 pub fn create_err(self, err: impl Diagnostic<'a>) -> Diag<'a> {
1032 err.into_diag(self, Error)
1033 }
1034
1035 #[track_caller]
1036 pub fn emit_err(self, err: impl Diagnostic<'a>) -> ErrorGuaranteed {
1037 self.create_err(err).emit()
1038 }
1039
1040 #[track_caller]
1042 pub fn delayed_bug(self, msg: impl Into<Cow<'static, str>>) -> ErrorGuaranteed {
1043 Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).emit()
1044 }
1045
1046 #[track_caller]
1051 pub fn span_delayed_bug(
1052 self,
1053 sp: impl Into<MultiSpan>,
1054 msg: impl Into<Cow<'static, str>>,
1055 ) -> ErrorGuaranteed {
1056 Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).with_span(sp).emit()
1057 }
1058
1059 #[track_caller]
1060 pub fn struct_warn(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1061 Diag::new(self, Warning, msg)
1062 }
1063
1064 #[track_caller]
1065 pub fn warn(self, msg: impl Into<DiagMessage>) {
1066 self.struct_warn(msg).emit()
1067 }
1068
1069 #[track_caller]
1070 pub fn struct_span_warn(
1071 self,
1072 span: impl Into<MultiSpan>,
1073 msg: impl Into<DiagMessage>,
1074 ) -> Diag<'a, ()> {
1075 self.struct_warn(msg).with_span(span)
1076 }
1077
1078 #[track_caller]
1079 pub fn span_warn(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
1080 self.struct_span_warn(span, msg).emit()
1081 }
1082
1083 #[track_caller]
1084 pub fn create_warn(self, warning: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
1085 warning.into_diag(self, Warning)
1086 }
1087
1088 #[track_caller]
1089 pub fn emit_warn(self, warning: impl Diagnostic<'a, ()>) {
1090 self.create_warn(warning).emit()
1091 }
1092
1093 #[track_caller]
1094 pub fn struct_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1095 Diag::new(self, Note, msg)
1096 }
1097
1098 #[track_caller]
1099 pub fn note(&self, msg: impl Into<DiagMessage>) {
1100 self.struct_note(msg).emit()
1101 }
1102
1103 #[track_caller]
1104 pub fn struct_span_note(
1105 self,
1106 span: impl Into<MultiSpan>,
1107 msg: impl Into<DiagMessage>,
1108 ) -> Diag<'a, ()> {
1109 self.struct_note(msg).with_span(span)
1110 }
1111
1112 #[track_caller]
1113 pub fn span_note(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
1114 self.struct_span_note(span, msg).emit()
1115 }
1116
1117 #[track_caller]
1118 pub fn create_note(self, note: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
1119 note.into_diag(self, Note)
1120 }
1121
1122 #[track_caller]
1123 pub fn emit_note(self, note: impl Diagnostic<'a, ()>) {
1124 self.create_note(note).emit()
1125 }
1126
1127 #[track_caller]
1128 pub fn struct_help(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1129 Diag::new(self, Help, msg)
1130 }
1131
1132 #[track_caller]
1133 pub fn struct_failure_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1134 Diag::new(self, FailureNote, msg)
1135 }
1136
1137 #[track_caller]
1138 pub fn struct_allow(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1139 Diag::new(self, Allow, msg)
1140 }
1141
1142 #[track_caller]
1143 pub fn struct_expect(self, msg: impl Into<DiagMessage>, id: LintExpectationId) -> Diag<'a, ()> {
1144 Diag::new(self, Expect, msg).with_lint_id(id)
1145 }
1146}
1147
1148impl DiagCtxtInner {
1153 fn new(emitter: Box<DynEmitter>) -> Self {
1154 Self {
1155 flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
1156 err_guars: Vec::new(),
1157 lint_err_guars: Vec::new(),
1158 delayed_bugs: Vec::new(),
1159 deduplicated_err_count: 0,
1160 deduplicated_warn_count: 0,
1161 emitter,
1162 must_produce_diag: None,
1163 has_printed: false,
1164 suppressed_expected_diag: false,
1165 taught_diagnostics: Default::default(),
1166 emitted_diagnostic_codes: Default::default(),
1167 emitted_diagnostics: Default::default(),
1168 stashed_diagnostics: Default::default(),
1169 future_breakage_diagnostics: Vec::new(),
1170 fulfilled_expectations: Default::default(),
1171 ice_file: None,
1172 }
1173 }
1174
1175 fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
1177 let mut guar = None;
1178 let has_errors = !self.err_guars.is_empty();
1179 for (_, stashed_diagnostics) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
1180 for (_, (diag, _guar)) in stashed_diagnostics {
1181 if !diag.is_error() {
1182 if !diag.is_force_warn() && has_errors {
1186 continue;
1187 }
1188 }
1189 guar = guar.or(self.emit_diagnostic(diag, None));
1190 }
1191 }
1192 guar
1193 }
1194
1195 fn emit_diagnostic(
1197 &mut self,
1198 mut diagnostic: DiagInner,
1199 taint: Option<&Cell<Option<ErrorGuaranteed>>>,
1200 ) -> Option<ErrorGuaranteed> {
1201 if diagnostic.has_future_breakage() {
1202 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);
1206 self.future_breakage_diagnostics.push(diagnostic.clone());
1207 }
1208
1209 match diagnostic.level {
1213 Bug => {}
1214 Fatal | Error => {
1215 if self.treat_next_err_as_bug() {
1216 diagnostic.level = Bug;
1218 }
1219 }
1220 DelayedBug => {
1221 if self.flags.eagerly_emit_delayed_bugs {
1226 if self.treat_next_err_as_bug() {
1228 diagnostic.level = Bug;
1229 } else {
1230 diagnostic.level = Error;
1231 }
1232 } else {
1233 return if let Some(guar) = self.has_errors() {
1236 Some(guar)
1237 } else {
1238 let backtrace = std::backtrace::Backtrace::capture();
1242 #[allow(deprecated)]
1246 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
1247 self.delayed_bugs
1248 .push((DelayedDiagInner::with_backtrace(diagnostic, backtrace), guar));
1249 Some(guar)
1250 };
1251 }
1252 }
1253 ForceWarning if diagnostic.lint_id.is_none() => {} Warning => {
1255 if !self.flags.can_emit_warnings {
1256 if diagnostic.has_future_breakage() {
1258 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1260 }
1261 return None;
1262 }
1263 }
1264 Note | Help | FailureNote => {}
1265 OnceNote | OnceHelp => {
::core::panicking::panic_fmt(format_args!("bad level: {0:?}",
diagnostic.level));
}panic!("bad level: {:?}", diagnostic.level),
1266 Allow => {
1267 if diagnostic.has_future_breakage() {
1269 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1271 self.suppressed_expected_diag = true;
1272 }
1273 return None;
1274 }
1275 Expect | ForceWarning => {
1276 self.fulfilled_expectations.insert(diagnostic.lint_id.unwrap());
1277 if let Expect = diagnostic.level {
1278 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1280 self.suppressed_expected_diag = true;
1281 return None;
1282 }
1283 }
1284 }
1285
1286 TRACK_DIAGNOSTIC(diagnostic, &mut |mut diagnostic| {
1287 if let Some(code) = diagnostic.code {
1288 self.emitted_diagnostic_codes.insert(code);
1289 }
1290
1291 let already_emitted = {
1292 let mut hasher = StableHasher::new();
1293 diagnostic.hash(&mut hasher);
1294 let diagnostic_hash = hasher.finish();
1295 !self.emitted_diagnostics.insert(diagnostic_hash)
1296 };
1297
1298 let is_error = diagnostic.is_error();
1299 let is_lint = diagnostic.is_lint.is_some();
1300
1301 if !(self.flags.deduplicate_diagnostics && already_emitted) {
1304 {
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:1304",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1304u32),
::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);
1305 {
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:1305",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1305u32),
::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);
1306
1307 let not_yet_emitted = |sub: &mut Subdiag| {
1308 {
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:1308",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1308u32),
::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);
1309 if sub.level != OnceNote && sub.level != OnceHelp {
1310 return true;
1311 }
1312 let mut hasher = StableHasher::new();
1313 sub.hash(&mut hasher);
1314 let diagnostic_hash = hasher.finish();
1315 {
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:1315",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1315u32),
::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);
1316 self.emitted_diagnostics.insert(diagnostic_hash)
1317 };
1318 diagnostic.children.retain_mut(not_yet_emitted);
1319 if already_emitted {
1320 let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`";
1321 diagnostic.sub(Note, msg, MultiSpan::new());
1322 }
1323
1324 if is_error {
1325 self.deduplicated_err_count += 1;
1326 } else if #[allow(non_exhaustive_omitted_patterns)] match diagnostic.level {
ForceWarning | Warning => true,
_ => false,
}matches!(diagnostic.level, ForceWarning | Warning) {
1327 self.deduplicated_warn_count += 1;
1328 }
1329 self.has_printed = true;
1330
1331 self.emitter.emit_diagnostic(diagnostic);
1332 }
1333
1334 if is_error {
1335 if !self.delayed_bugs.is_empty() {
1340 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);
1341 self.delayed_bugs.clear();
1342 self.delayed_bugs.shrink_to_fit();
1343 }
1344
1345 #[allow(deprecated)]
1348 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
1349 if is_lint {
1350 self.lint_err_guars.push(guar);
1351 } else {
1352 if let Some(taint) = taint {
1353 taint.set(Some(guar));
1354 }
1355 self.err_guars.push(guar);
1356 }
1357 self.panic_if_treat_err_as_bug();
1358 Some(guar)
1359 } else {
1360 None
1361 }
1362 })
1363 }
1364
1365 fn treat_err_as_bug(&self) -> bool {
1366 self.flags
1367 .treat_err_as_bug
1368 .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() >= c.get())
1369 }
1370
1371 fn treat_next_err_as_bug(&self) -> bool {
1373 self.flags
1374 .treat_err_as_bug
1375 .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() + 1 >= c.get())
1376 }
1377
1378 fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
1379 self.err_guars.get(0).copied().or_else(|| {
1380 if let Some((_diag, guar)) = self
1381 .stashed_diagnostics
1382 .values()
1383 .flat_map(|stashed_diagnostics| stashed_diagnostics.values())
1384 .find(|(diag, guar)| guar.is_some() && diag.is_lint.is_none())
1385 {
1386 *guar
1387 } else {
1388 None
1389 }
1390 })
1391 }
1392
1393 fn has_errors(&self) -> Option<ErrorGuaranteed> {
1394 self.err_guars.get(0).copied().or_else(|| self.lint_err_guars.get(0).copied()).or_else(
1395 || {
1396 self.stashed_diagnostics.values().find_map(|stashed_diagnostics| {
1397 stashed_diagnostics.values().find_map(|(_, guar)| *guar)
1398 })
1399 },
1400 )
1401 }
1402
1403 fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
1404 self.has_errors().or_else(|| self.delayed_bugs.get(0).map(|(_, guar)| guar).copied())
1405 }
1406
1407 fn flush_delayed(&mut self) {
1408 if !self.stashed_diagnostics.is_empty() {
::core::panicking::panic("assertion failed: self.stashed_diagnostics.is_empty()")
};assert!(self.stashed_diagnostics.is_empty());
1412
1413 if !self.err_guars.is_empty() {
1414 return;
1416 }
1417
1418 if self.delayed_bugs.is_empty() {
1419 return;
1421 }
1422
1423 let bugs: Vec<_> =
1424 std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect();
1425
1426 let backtrace = std::env::var_os("RUST_BACKTRACE").as_deref() != Some(OsStr::new("0"));
1427 let decorate = backtrace || self.ice_file.is_none();
1428 let mut out = self
1429 .ice_file
1430 .as_ref()
1431 .and_then(|file| std::fs::File::options().create(true).append(true).open(file).ok());
1432
1433 let note1 = "no errors encountered even though delayed bugs were created";
1438 let note2 = "those delayed bugs will now be shown as internal compiler errors";
1439 self.emit_diagnostic(DiagInner::new(Note, note1), None);
1440 self.emit_diagnostic(DiagInner::new(Note, note2), None);
1441
1442 for bug in bugs {
1443 if let Some(out) = &mut out {
1444 _ = 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!(
1445 out,
1446 "delayed bug: {}\n{}\n",
1447 bug.inner
1448 .messages
1449 .iter()
1450 .filter_map(|(msg, _)| msg.as_str())
1451 .collect::<String>(),
1452 &bug.note
1453 );
1454 }
1455
1456 let mut bug = if decorate { bug.decorate() } else { bug.inner };
1457
1458 if bug.level != DelayedBug {
1460 let msg = rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"))msg!(
1467 "`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"
1468 ).arg("level", bug.level).format();
1469 bug.sub(Note, msg, bug.span.primary_span().unwrap().into());
1470 }
1471 bug.level = Bug;
1472
1473 self.emit_diagnostic(bug, None);
1474 }
1475
1476 panic::panic_any(DelayedBugPanic);
1478 }
1479
1480 fn panic_if_treat_err_as_bug(&self) {
1481 if self.treat_err_as_bug() {
1482 let n = self.flags.treat_err_as_bug.map(|c| c.get()).unwrap();
1483 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());
1484 if n == 1 {
1485 {
::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`");
1486 } else {
1487 {
::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}`");
1488 }
1489 }
1490 }
1491}
1492
1493struct DelayedDiagInner {
1494 inner: DiagInner,
1495 note: Backtrace,
1496}
1497
1498impl DelayedDiagInner {
1499 fn with_backtrace(diagnostic: DiagInner, backtrace: Backtrace) -> Self {
1500 DelayedDiagInner { inner: diagnostic, note: backtrace }
1501 }
1502
1503 fn decorate(self) -> DiagInner {
1504 let mut diag = self.inner;
1508 let msg = match self.note.status() {
1509 BacktraceStatus::Captured => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("delayed at {$emitted_at}\n {$note}"))msg!(
1510 "delayed at {$emitted_at}
1511 {$note}"
1512 ),
1513 _ => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("delayed at {$emitted_at} - {$note}"))msg!("delayed at {$emitted_at} - {$note}"),
1516 }
1517 .arg("emitted_at", diag.emitted_at.clone())
1518 .arg("note", self.note)
1519 .format();
1520 diag.sub(Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into());
1521 diag
1522 }
1523}
1524
1525#[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_fields_are_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)]
1545pub enum Level {
1546 Bug,
1548
1549 Fatal,
1552
1553 Error,
1556
1557 DelayedBug,
1562
1563 ForceWarning,
1569
1570 Warning,
1573
1574 Note,
1576
1577 OnceNote,
1579
1580 Help,
1582
1583 OnceHelp,
1585
1586 FailureNote,
1589
1590 Allow,
1592
1593 Expect,
1595}
1596
1597impl fmt::Display for Level {
1598 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1599 self.to_str().fmt(f)
1600 }
1601}
1602
1603impl Level {
1604 fn color(self) -> anstyle::Style {
1605 match self {
1606 Bug | Fatal | Error | DelayedBug => AnsiColor::BrightRed.on_default(),
1607 ForceWarning | Warning => {
1608 if falsecfg!(windows) {
1609 AnsiColor::BrightYellow.on_default()
1610 } else {
1611 AnsiColor::Yellow.on_default()
1612 }
1613 }
1614 Note | OnceNote => AnsiColor::BrightGreen.on_default(),
1615 Help | OnceHelp => AnsiColor::BrightCyan.on_default(),
1616 FailureNote => anstyle::Style::new(),
1617 Allow | Expect => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1618 }
1619 }
1620
1621 pub fn to_str(self) -> &'static str {
1622 match self {
1623 Bug | DelayedBug => "error: internal compiler error",
1624 Fatal | Error => "error",
1625 ForceWarning | Warning => "warning",
1626 Note | OnceNote => "note",
1627 Help | OnceHelp => "help",
1628 FailureNote => "failure-note",
1629 Allow | Expect => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1630 }
1631 }
1632
1633 pub fn is_failure_note(&self) -> bool {
1634 #[allow(non_exhaustive_omitted_patterns)] match *self {
FailureNote => true,
_ => false,
}matches!(*self, FailureNote)
1635 }
1636}
1637
1638impl IntoDiagArg for Level {
1639 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
1640 DiagArgValue::Str(Cow::from(self.to_string()))
1641 }
1642}
1643
1644#[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_fields_are_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)]
1645pub enum Style {
1646 MainHeaderMsg,
1647 HeaderMsg,
1648 LineAndColumn,
1649 LineNumber,
1650 Quotation,
1651 UnderlinePrimary,
1652 UnderlineSecondary,
1653 LabelPrimary,
1654 LabelSecondary,
1655 NoStyle,
1656 Level(Level),
1657 Highlight,
1658 Addition,
1659 Removal,
1660}
1661
1662pub fn elided_lifetime_in_path_suggestion(
1664 source_map: &SourceMap,
1665 n: usize,
1666 path_span: Span,
1667 incl_angl_brckt: bool,
1668 insertion_span: Span,
1669) -> ElidedLifetimeInPathSubdiag {
1670 let expected = ExpectedLifetimeParameter { span: path_span, count: n };
1671 let indicate = source_map.is_span_accessible(insertion_span).then(|| {
1673 let anon_lts = ::alloc::vec::from_elem("'_", n)vec!["'_"; n].join(", ");
1674 let suggestion =
1675 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}, ") };
1676
1677 IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion }
1678 });
1679
1680 ElidedLifetimeInPathSubdiag { expected, indicate }
1681}
1682
1683pub fn a_or_an(s: &str) -> &'static str {
1687 let mut chars = s.chars();
1688 let Some(mut first_alpha_char) = chars.next() else {
1689 return "a";
1690 };
1691 if first_alpha_char == '`' {
1692 let Some(next) = chars.next() else {
1693 return "a";
1694 };
1695 first_alpha_char = next;
1696 }
1697 if ["a", "e", "i", "o", "u", "&"].contains(&&first_alpha_char.to_lowercase().to_string()[..]) {
1698 "an"
1699 } else {
1700 "a"
1701 }
1702}
1703
1704#[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)]
1705pub enum TerminalUrl {
1706 No,
1707 Yes,
1708 Auto,
1709}