1#![feature(associated_type_defaults)]
7#![feature(default_field_values)]
8#![feature(macro_metavar_expr_concat)]
9#![feature(negative_impls)]
10#![feature(never_type)]
11extern crate self as rustc_errors;
14
15use std::backtrace::{Backtrace, BacktraceStatus};
16use std::borrow::Cow;
17use std::cell::Cell;
18use std::ffi::OsStr;
19use std::hash::Hash;
20use std::io::Write;
21use std::num::NonZero;
22use std::ops::DerefMut;
23use std::path::{Path, PathBuf};
24use std::thread::ThreadId;
25use std::{assert_matches, fmt, panic};
26
27use Level::*;
28pub use anstream::{AutoStream, ColorChoice};
31pub use anstyle::{
32 Ansi256Color, AnsiColor, Color, EffectIter, Effects, Reset, RgbColor, Style as Anstyle,
33};
34pub use codes::*;
35pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer};
36pub use diagnostic::{
37 BugAbort, Diag, DiagDecorator, DiagInner, DiagLocation, DiagStyledString, Diagnostic,
38 EmissionGuarantee, FatalAbort, StringPart, Subdiag, Subdiagnostic,
39};
40pub use diagnostic_impls::{
41 DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
42 IndicateAnonymousLifetime, SingleLabelManySpans,
43};
44pub use emitter::ColorConfig;
45use emitter::{DynEmitter, Emitter};
46use rustc_ast::attr::version::RustcVersion;
47use rustc_data_structures::AtomicRef;
48use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
49use rustc_data_structures::stable_hash::StableHasher;
50use rustc_data_structures::sync::{DynSend, Lock};
51pub use rustc_error_messages::{
52 DiagArg, DiagArgFromDisplay, DiagArgMap, DiagArgName, DiagArgValue, DiagMessage, IntoDiagArg,
53 LanguageIdentifier, MultiSpan, SpanLabel, fluent_bundle, into_diag_arg_using_display,
54};
55use rustc_hashes::Hash128;
56use rustc_lint_defs::LintExpectationId;
57pub use rustc_lint_defs::{Applicability, listify, pluralize};
58pub use rustc_macros::msg;
59use rustc_macros::{Decodable, Encodable};
60pub use rustc_span::ErrorGuaranteed;
61pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker, catch_fatal_errors};
62use rustc_span::source_map::SourceMap;
63use rustc_span::{DUMMY_SP, Span};
64use tracing::debug;
65
66use crate::emitter::TimingEvent;
67use crate::formatting::DiagMessageAddArg;
68pub use crate::formatting::format_diag_message;
69use crate::timings::TimingRecord;
70
71pub mod annotate_snippet_emitter_writer;
72pub mod codes;
73mod decorate_diag;
74mod diagnostic;
75mod diagnostic_impls;
76pub mod emitter;
77pub mod formatting;
78pub mod json;
79mod lock;
80pub mod markdown;
81pub mod timings;
82
83pub type PResult<'a, T> = Result<T, Diag<'a>>;
84
85#[cfg(target_pointer_width = "64")]
87const _: [(); 24] = [(); ::std::mem::size_of::<PResult<'_, ()>>()];rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24);
88#[cfg(target_pointer_width = "64")]
89const _: [(); 24] = [(); ::std::mem::size_of::<PResult<'_, bool>>()];rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
90
91#[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)]
92pub enum SuggestionStyle {
93 HideCodeInline,
95 HideCodeAlways,
97 CompletelyHidden,
99 ShowCode,
103 ShowAlways,
105}
106
107impl SuggestionStyle {
108 fn hide_inline(&self) -> bool {
109 !#[allow(non_exhaustive_omitted_patterns)] match *self {
SuggestionStyle::ShowCode => true,
_ => false,
}matches!(*self, SuggestionStyle::ShowCode)
110 }
111}
112
113#[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)]
115pub enum Suggestions {
116 Enabled(Vec<CodeSuggestion>),
121 Sealed(Box<[CodeSuggestion]>),
125 Disabled,
129}
130
131impl Suggestions {
132 pub fn unwrap_tag(self) -> Vec<CodeSuggestion> {
134 match self {
135 Suggestions::Enabled(suggestions) => suggestions,
136 Suggestions::Sealed(suggestions) => suggestions.into_vec(),
137 Suggestions::Disabled => Vec::new(),
138 }
139 }
140
141 pub fn len(&self) -> usize {
142 match self {
143 Suggestions::Enabled(suggestions) => suggestions.len(),
144 Suggestions::Sealed(suggestions) => suggestions.len(),
145 Suggestions::Disabled => 0,
146 }
147 }
148}
149
150impl Default for Suggestions {
151 fn default() -> Self {
152 Self::Enabled(::alloc::vec::Vec::new()vec![])
153 }
154}
155
156#[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)]
157pub struct CodeSuggestion {
158 pub substitutions: Vec<Substitution>,
180 pub msg: DiagMessage,
181 pub style: SuggestionStyle,
183 pub applicability: Applicability,
189}
190
191#[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)]
192pub struct Substitution {
194 pub parts: Vec<SubstitutionPart>,
195}
196
197#[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)]
198pub struct SubstitutionPart {
199 pub span: Span,
200 pub snippet: String,
201}
202
203#[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)]
204pub struct TrimmedSubstitutionPart {
205 pub original_span: Span,
206 pub span: Span,
207 pub snippet: String,
208}
209
210impl TrimmedSubstitutionPart {
211 pub fn is_addition(&self, sm: &SourceMap) -> bool {
212 !self.snippet.is_empty() && !self.replaces_meaningful_content(sm)
213 }
214
215 pub fn is_deletion(&self, sm: &SourceMap) -> bool {
216 self.snippet.trim().is_empty() && self.replaces_meaningful_content(sm)
217 }
218
219 pub fn is_replacement(&self, sm: &SourceMap) -> bool {
220 !self.snippet.is_empty() && self.replaces_meaningful_content(sm)
221 }
222
223 pub fn is_destructive_replacement(&self, sm: &SourceMap) -> bool {
228 self.is_replacement(sm)
229 && !sm
230 .span_to_snippet(self.span)
231 .is_ok_and(|snippet| as_substr(snippet.trim(), self.snippet.trim()).is_some())
232 }
233
234 fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool {
235 sm.span_to_snippet(self.span)
236 .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty())
237 }
238}
239
240fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a str, usize)> {
245 let common_prefix = original
246 .chars()
247 .zip(suggestion.chars())
248 .take_while(|(c1, c2)| c1 == c2)
249 .map(|(c, _)| c.len_utf8())
250 .sum();
251 let original = &original[common_prefix..];
252 let suggestion = &suggestion[common_prefix..];
253 if suggestion.ends_with(original) {
254 let common_suffix = original.len();
255 Some((common_prefix, &suggestion[..suggestion.len() - original.len()], common_suffix))
256 } else {
257 None
258 }
259}
260
261pub struct ExplicitBug;
264
265pub struct DelayedBugPanic;
268
269pub struct DiagCtxt {
273 inner: Lock<DiagCtxtInner>,
274}
275
276#[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)]
277pub struct DiagCtxtHandle<'a> {
278 dcx: &'a DiagCtxt,
279 tainted_with_errors: Option<&'a Cell<Option<ErrorGuaranteed>>>,
282}
283
284impl<'a> std::ops::Deref for DiagCtxtHandle<'a> {
285 type Target = &'a DiagCtxt;
286
287 fn deref(&self) -> &Self::Target {
288 &self.dcx
289 }
290}
291
292struct DiagCtxtInner {
296 flags: DiagCtxtFlags,
297
298 err_guars: Vec<(ErrorGuaranteed, ThreadId)>,
301 lint_err_guars: Vec<(ErrorGuaranteed, ThreadId)>,
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>, ThreadId)>>,
346
347 future_breakage_diagnostics: Vec<DiagInner>,
348
349 fulfilled_expectations: FxIndexSet<LintExpectationId>,
361
362 ice_file: Option<PathBuf>,
365
366 msrv: Option<RustcVersion>,
368}
369
370#[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 {
static __NAMES: &str =
"ItemNoTypeUnderscoreForArrayLengthsEarlySyntaxWarningCallIntoMethodLifetimeIsCharMaybeFruTypoCallAssocMethodAssociatedTypeSuggestionUndeterminedMacroResolutionExprInPatGenericInFieldExprReturnTypeNotation";
static __OFFSET: [usize; 13] =
[0usize, 10usize, 35usize, 53usize, 67usize, 81usize, 93usize,
108usize, 132usize, 159usize, 168usize, 186usize, 204usize];
let __d = ::core::intrinsics::discriminant_value(self) as usize;
::core::fmt::Formatter::debug_c_like_enum_write_str(f, __NAMES,
&__OFFSET, __d)
}
}Debug)]
372pub enum StashKey {
373 ItemNoType,
374 UnderscoreForArrayLengths,
375 EarlySyntaxWarning,
376 CallIntoMethod,
377 LifetimeIsChar,
380 MaybeFruTypo,
383 CallAssocMethod,
384 AssociatedTypeSuggestion,
385 UndeterminedMacroResolution,
386 ExprInPat,
388 GenericInFieldExpr,
392 ReturnTypeNotation,
393}
394
395fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
396 (*f)(diag)
397}
398
399pub static TRACK_DIAGNOSTIC: AtomicRef<
402 fn(DiagInner, &mut dyn FnMut(DiagInner) -> Option<ErrorGuaranteed>) -> Option<ErrorGuaranteed>,
403> = AtomicRef::new(&(default_track_diagnostic as _));
404
405#[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)]
406pub struct DiagCtxtFlags {
407 pub can_emit_warnings: bool,
410 pub treat_err_as_bug: Option<NonZero<usize>>,
413 pub eagerly_emit_delayed_bugs: bool,
416 pub macro_backtrace: bool,
419 pub deduplicate_diagnostics: bool,
421 pub track_diagnostics: bool,
423}
424
425impl Drop for DiagCtxtInner {
426 fn drop(&mut self) {
427 self.emit_stashed_diagnostics();
435
436 self.flush_delayed();
440
441 if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() {
445 if let Some(backtrace) = &self.must_produce_diag {
446 let suggestion = match backtrace.status() {
447 BacktraceStatus::Disabled => String::from(
448 "Backtraces are currently disabled: set `RUST_BACKTRACE=1` and re-run \
449 to see where it happened.",
450 ),
451 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!(
452 "This happened in the following `must_produce_diag` call's backtrace:\n\
453 {backtrace}",
454 ),
455 _ => String::from("(impossible to capture backtrace where this happened)"),
456 };
457 {
::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!(
458 "`trimmed_def_paths` called, diagnostics were expected but none were emitted. \
459 Use `with_no_trimmed_paths` for debugging. {suggestion}"
460 );
461 }
462 }
463 }
464}
465
466impl DiagCtxt {
467 pub fn disable_warnings(mut self) -> Self {
468 self.inner.get_mut().flags.can_emit_warnings = false;
469 self
470 }
471
472 pub fn with_flags(mut self, flags: DiagCtxtFlags) -> Self {
473 self.inner.get_mut().flags = flags;
474 self
475 }
476
477 pub fn with_ice_file(mut self, ice_file: PathBuf) -> Self {
478 self.inner.get_mut().ice_file = Some(ice_file);
479 self
480 }
481
482 pub fn with_msrv(mut self, msrv: RustcVersion) -> Self {
483 self.inner.get_mut().msrv = Some(msrv);
484 self
485 }
486
487 pub fn new(emitter: Box<DynEmitter>) -> Self {
488 Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
489 }
490
491 pub fn make_silent(&self) {
492 let mut inner = self.inner.borrow_mut();
493 inner.emitter = Box::new(emitter::SilentEmitter {});
494 }
495
496 pub fn set_emitter(&self, emitter: Box<dyn Emitter + DynSend>) {
497 self.inner.borrow_mut().emitter = emitter;
498 }
499
500 pub fn can_emit_warnings(&self) -> bool {
504 self.inner.borrow_mut().flags.can_emit_warnings
505 }
506
507 pub fn reset_err_count(&self) {
513 let mut inner = self.inner.borrow_mut();
516 let DiagCtxtInner {
517 flags: _,
518 err_guars,
519 lint_err_guars,
520 delayed_bugs,
521 deduplicated_err_count,
522 deduplicated_warn_count,
523 emitter: _,
524 must_produce_diag,
525 has_printed,
526 suppressed_expected_diag,
527 taught_diagnostics,
528 emitted_diagnostic_codes,
529 emitted_diagnostics,
530 stashed_diagnostics,
531 future_breakage_diagnostics,
532 fulfilled_expectations,
533 ice_file: _,
534 msrv: _,
535 } = inner.deref_mut();
536
537 *err_guars = Default::default();
540 *lint_err_guars = Default::default();
541 *delayed_bugs = Default::default();
542 *deduplicated_err_count = 0;
543 *deduplicated_warn_count = 0;
544 *must_produce_diag = None;
545 *has_printed = false;
546 *suppressed_expected_diag = false;
547 *taught_diagnostics = Default::default();
548 *emitted_diagnostic_codes = Default::default();
549 *emitted_diagnostics = Default::default();
550 *stashed_diagnostics = Default::default();
551 *future_breakage_diagnostics = Default::default();
552 *fulfilled_expectations = Default::default();
553 }
554
555 pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> {
556 DiagCtxtHandle { dcx: self, tainted_with_errors: None }
557 }
558
559 pub fn taintable_handle<'a>(
563 &'a self,
564 tainted_with_errors: &'a Cell<Option<ErrorGuaranteed>>,
565 ) -> DiagCtxtHandle<'a> {
566 DiagCtxtHandle { dcx: self, tainted_with_errors: Some(tainted_with_errors) }
567 }
568}
569
570impl<'a> DiagCtxtHandle<'a> {
571 pub fn stash_diagnostic(
593 &self,
594 span: Span,
595 key: StashKey,
596 diag: DiagInner,
597 ) -> Option<ErrorGuaranteed> {
598 let guar = match diag.level {
599 Bug | Fatal => {
600 self.span_bug(
601 span,
602 ::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),
603 );
604 }
605 Error => Some(self.span_delayed_bug(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("stashing {0:?}", key))
})format!("stashing {key:?}"))),
609 DelayedBug => {
610 return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors);
611 }
612 ForceWarning | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
613 | Expect => None,
614 };
615
616 self.inner
620 .borrow_mut()
621 .stashed_diagnostics
622 .entry(key)
623 .or_default()
624 .insert(span.with_parent(None), (diag, guar, std::thread::current().id()));
625
626 guar
627 }
628
629 pub fn steal_non_err(self, span: Span, key: StashKey) -> Option<Diag<'a, ()>> {
633 let (diag, guar, _) = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
635 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
636 )?;
637 if !!diag.is_error() {
::core::panicking::panic("assertion failed: !diag.is_error()")
};assert!(!diag.is_error());
638 if !guar.is_none() {
::core::panicking::panic("assertion failed: guar.is_none()")
};assert!(guar.is_none());
639 Some(Diag::new_diagnostic(self, diag))
640 }
641
642 pub fn try_steal_modify_and_emit_err<F>(
647 self,
648 span: Span,
649 key: StashKey,
650 mut modify_err: F,
651 ) -> Option<ErrorGuaranteed>
652 where
653 F: FnMut(&mut Diag<'_>),
654 {
655 let err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
657 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
658 );
659 err.map(|(err, guar, _)| {
660 {
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);
662 if !guar.is_some() {
::core::panicking::panic("assertion failed: guar.is_some()")
};assert!(guar.is_some());
663 let mut err = Diag::<ErrorGuaranteed>::new_diagnostic(self, err);
664 modify_err(&mut err);
665 {
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);
666 err.emit()
667 })
668 }
669
670 pub fn try_steal_replace_and_emit_err(
674 self,
675 span: Span,
676 key: StashKey,
677 new_err: Diag<'_>,
678 ) -> ErrorGuaranteed {
679 let old_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 match old_err {
684 Some((old_err, guar, _)) => {
685 {
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);
686 if !guar.is_some() {
::core::panicking::panic("assertion failed: guar.is_some()")
};assert!(guar.is_some());
687 Diag::<ErrorGuaranteed>::new_diagnostic(self, old_err).cancel();
690 }
691 None => {}
692 };
693 new_err.emit()
694 }
695
696 pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool {
697 let inner = self.inner.borrow();
698 if let Some(stashed_diagnostics) = inner.stashed_diagnostics.get(&key)
699 && !stashed_diagnostics.is_empty()
700 {
701 stashed_diagnostics.contains_key(&span.with_parent(None))
702 } else {
703 false
704 }
705 }
706
707 pub fn emit_stashed_diagnostics(&self) -> Option<ErrorGuaranteed> {
709 self.inner.borrow_mut().emit_stashed_diagnostics()
710 }
711
712 #[inline]
714 pub fn err_count(&self) -> usize {
715 let inner = self.inner.borrow();
716 inner.err_guars.len()
717 + inner.lint_err_guars.len()
718 + inner
719 .stashed_diagnostics
720 .values()
721 .map(|a| a.values().filter(|(_, guar, _)| guar.is_some()).count())
722 .sum::<usize>()
723 }
724
725 pub fn err_count_on_current_thread(&self) -> usize {
730 let inner = self.inner.borrow();
731 let current = std::thread::current().id();
732 inner.err_guars.iter().filter(|(_, thread)| *thread == current).count()
733 + inner.lint_err_guars.iter().filter(|(_, thread)| *thread == current).count()
734 + inner
735 .stashed_diagnostics
736 .values()
737 .map(|a| {
738 a.values()
739 .filter(|(_, guar, thread)| guar.is_some() && *thread == current)
740 .count()
741 })
742 .sum::<usize>()
743 }
744
745 pub fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
748 self.inner.borrow().has_errors_excluding_lint_errors()
749 }
750
751 pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
753 self.inner.borrow().has_errors()
754 }
755
756 pub fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
759 self.inner.borrow().has_errors_or_delayed_bugs()
760 }
761
762 pub fn print_error_count(&self) {
763 let mut inner = self.inner.borrow_mut();
764
765 if !inner.stashed_diagnostics.is_empty() {
::core::panicking::panic("assertion failed: inner.stashed_diagnostics.is_empty()")
};assert!(inner.stashed_diagnostics.is_empty());
768
769 if inner.treat_err_as_bug() {
770 return;
771 }
772
773 let warnings = match inner.deduplicated_warn_count {
774 0 => Cow::from(""),
775 1 => Cow::from("1 warning emitted"),
776 count => Cow::from(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} warnings emitted", count))
})format!("{count} warnings emitted")),
777 };
778 let errors = match inner.deduplicated_err_count {
779 0 => Cow::from(""),
780 1 => Cow::from("aborting due to 1 previous error"),
781 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")),
782 };
783
784 match (errors.len(), warnings.len()) {
785 (0, 0) => return,
786 (0, _) => {
787 inner.emit_diagnostic(
790 DiagInner::new(ForceWarning, DiagMessage::Str(warnings)),
791 None,
792 );
793 }
794 (_, 0) => {
795 inner.emit_diagnostic(DiagInner::new(Error, errors), self.tainted_with_errors);
796 }
797 (_, _) => {
798 inner.emit_diagnostic(
799 DiagInner::new(Error, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}; {1}", errors, warnings))
})format!("{errors}; {warnings}")),
800 self.tainted_with_errors,
801 );
802 }
803 }
804
805 let can_show_explain = inner.emitter.should_show_explain();
806 let are_there_diagnostics = !inner.emitted_diagnostic_codes.is_empty();
807 if can_show_explain && are_there_diagnostics {
808 let mut error_codes = inner
809 .emitted_diagnostic_codes
810 .iter()
811 .filter_map(|&code| {
812 if crate::codes::try_find_description(code).is_ok() {
813 Some(code.to_string())
814 } else {
815 None
816 }
817 })
818 .collect::<Vec<_>>();
819 if !error_codes.is_empty() {
820 error_codes.sort();
821 if error_codes.len() > 1 {
822 let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
823 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!(
824 "Some errors have detailed explanations: {}{}",
825 error_codes[..limit].join(", "),
826 if error_codes.len() > 9 { "..." } else { "." }
827 );
828 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!(
829 "For more information about an error, try `rustc --explain {}`.",
830 &error_codes[0]
831 );
832 inner.emit_diagnostic(DiagInner::new(FailureNote, msg1), None);
833 inner.emit_diagnostic(DiagInner::new(FailureNote, msg2), None);
834 } else {
835 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!(
836 "For more information about this error, try `rustc --explain {}`.",
837 &error_codes[0]
838 );
839 inner.emit_diagnostic(DiagInner::new(FailureNote, msg), None);
840 }
841 }
842 }
843 }
844
845 pub fn abort_if_errors(&self) {
850 if let Some(guar) = self.has_errors() {
851 guar.raise_fatal();
852 }
853 }
854
855 pub fn must_teach(&self, code: ErrCode) -> bool {
861 self.inner.borrow_mut().taught_diagnostics.insert(code)
862 }
863
864 pub fn emit_diagnostic(&self, diagnostic: DiagInner) -> Option<ErrorGuaranteed> {
865 self.inner.borrow_mut().emit_diagnostic(diagnostic, self.tainted_with_errors)
866 }
867
868 pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
869 self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type);
870 }
871
872 pub fn emit_timing_section_start(&self, record: TimingRecord) {
873 self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::Start);
874 }
875
876 pub fn emit_timing_section_end(&self, record: TimingRecord) {
877 self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::End);
878 }
879
880 pub fn emit_future_breakage_report(&self) {
881 let inner = &mut *self.inner.borrow_mut();
882 let diags = std::mem::take(&mut inner.future_breakage_diagnostics);
883 if !diags.is_empty() {
884 inner.emitter.emit_future_breakage_report(diags);
885 }
886 }
887
888 pub fn emit_unused_externs(
889 &self,
890 lint_level: rustc_lint_defs::Level,
891 loud: bool,
892 unused_externs: &[&str],
893 ) {
894 let mut inner = self.inner.borrow_mut();
895
896 if loud && lint_level.is_error() {
907 #[allow(deprecated)]
910 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
911 inner.lint_err_guars.push((guar, std::thread::current().id()));
912 inner.panic_if_treat_err_as_bug();
913 }
914
915 inner.emitter.emit_unused_externs(lint_level, unused_externs)
916 }
917
918 #[must_use]
921 pub fn steal_fulfilled_expectation_ids(&self) -> FxIndexSet<LintExpectationId> {
922 std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations)
923 }
924
925 pub fn flush_delayed(&self) {
930 self.inner.borrow_mut().flush_delayed();
931 }
932
933 #[track_caller]
936 pub fn set_must_produce_diag(&self) {
937 if !self.inner.borrow().must_produce_diag.is_none() {
{
::core::panicking::panic_fmt(format_args!("should only need to collect a backtrace once"));
}
};assert!(
938 self.inner.borrow().must_produce_diag.is_none(),
939 "should only need to collect a backtrace once"
940 );
941 self.inner.borrow_mut().must_produce_diag = Some(Backtrace::capture());
942 }
943}
944
945impl<'a> DiagCtxtHandle<'a> {
950 #[track_caller]
951 pub fn struct_bug(self, msg: impl Into<Cow<'static, str>>) -> Diag<'a, BugAbort> {
952 Diag::new(self, Bug, msg.into())
953 }
954
955 #[track_caller]
956 pub fn bug(self, msg: impl Into<Cow<'static, str>>) -> ! {
957 self.struct_bug(msg).emit()
958 }
959
960 #[track_caller]
961 pub fn struct_span_bug(
962 self,
963 span: impl Into<MultiSpan>,
964 msg: impl Into<Cow<'static, str>>,
965 ) -> Diag<'a, BugAbort> {
966 self.struct_bug(msg).with_span(span)
967 }
968
969 #[track_caller]
970 pub fn span_bug(self, span: impl Into<MultiSpan>, msg: impl Into<Cow<'static, str>>) -> ! {
971 self.struct_span_bug(span, msg.into()).emit()
972 }
973
974 #[track_caller]
975 pub fn create_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> Diag<'a, BugAbort> {
976 bug.into_diag(self, Bug)
977 }
978
979 #[track_caller]
980 pub fn emit_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> ! {
981 self.create_bug(bug).emit()
982 }
983
984 #[track_caller]
985 pub fn struct_fatal(self, msg: impl Into<DiagMessage>) -> Diag<'a, FatalAbort> {
986 Diag::new(self, Fatal, msg)
987 }
988
989 #[track_caller]
990 pub fn fatal(self, msg: impl Into<DiagMessage>) -> ! {
991 self.struct_fatal(msg).emit()
992 }
993
994 #[track_caller]
995 pub fn struct_span_fatal(
996 self,
997 span: impl Into<MultiSpan>,
998 msg: impl Into<DiagMessage>,
999 ) -> Diag<'a, FatalAbort> {
1000 self.struct_fatal(msg).with_span(span)
1001 }
1002
1003 #[track_caller]
1004 pub fn span_fatal(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) -> ! {
1005 self.struct_span_fatal(span, msg).emit()
1006 }
1007
1008 #[track_caller]
1009 pub fn create_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> Diag<'a, FatalAbort> {
1010 fatal.into_diag(self, Fatal)
1011 }
1012
1013 #[track_caller]
1014 pub fn emit_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> ! {
1015 self.create_fatal(fatal).emit()
1016 }
1017
1018 #[track_caller]
1019 pub fn create_almost_fatal(
1020 self,
1021 fatal: impl Diagnostic<'a, FatalError>,
1022 ) -> Diag<'a, FatalError> {
1023 fatal.into_diag(self, Fatal)
1024 }
1025
1026 #[track_caller]
1027 pub fn emit_almost_fatal(self, fatal: impl Diagnostic<'a, FatalError>) -> FatalError {
1028 self.create_almost_fatal(fatal).emit()
1029 }
1030
1031 #[track_caller]
1033 pub fn struct_err(self, msg: impl Into<DiagMessage>) -> Diag<'a> {
1034 Diag::new(self, Error, msg)
1035 }
1036
1037 #[track_caller]
1038 pub fn err(self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
1039 self.struct_err(msg).emit()
1040 }
1041
1042 #[track_caller]
1043 pub fn struct_span_err(
1044 self,
1045 span: impl Into<MultiSpan>,
1046 msg: impl Into<DiagMessage>,
1047 ) -> Diag<'a> {
1048 self.struct_err(msg).with_span(span)
1049 }
1050
1051 #[track_caller]
1052 pub fn span_err(
1053 self,
1054 span: impl Into<MultiSpan>,
1055 msg: impl Into<DiagMessage>,
1056 ) -> ErrorGuaranteed {
1057 self.struct_span_err(span, msg).emit()
1058 }
1059
1060 #[track_caller]
1061 pub fn create_err(self, err: impl Diagnostic<'a>) -> Diag<'a> {
1062 err.into_diag(self, Error)
1063 }
1064
1065 #[track_caller]
1066 pub fn emit_err(self, err: impl Diagnostic<'a>) -> ErrorGuaranteed {
1067 self.create_err(err).emit()
1068 }
1069
1070 #[track_caller]
1072 pub fn delayed_bug(self, msg: impl Into<Cow<'static, str>>) -> ErrorGuaranteed {
1073 Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).emit()
1074 }
1075
1076 #[track_caller]
1081 pub fn span_delayed_bug(
1082 self,
1083 sp: impl Into<MultiSpan>,
1084 msg: impl Into<Cow<'static, str>>,
1085 ) -> ErrorGuaranteed {
1086 Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).with_span(sp).emit()
1087 }
1088
1089 #[track_caller]
1090 pub fn struct_warn(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1091 Diag::new(self, Warning, msg)
1092 }
1093
1094 #[track_caller]
1095 pub fn warn(self, msg: impl Into<DiagMessage>) {
1096 self.struct_warn(msg).emit()
1097 }
1098
1099 #[track_caller]
1100 pub fn struct_span_warn(
1101 self,
1102 span: impl Into<MultiSpan>,
1103 msg: impl Into<DiagMessage>,
1104 ) -> Diag<'a, ()> {
1105 self.struct_warn(msg).with_span(span)
1106 }
1107
1108 #[track_caller]
1109 pub fn span_warn(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
1110 self.struct_span_warn(span, msg).emit()
1111 }
1112
1113 #[track_caller]
1114 pub fn create_warn(self, warning: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
1115 warning.into_diag(self, Warning)
1116 }
1117
1118 #[track_caller]
1119 pub fn emit_warn(self, warning: impl Diagnostic<'a, ()>) {
1120 self.create_warn(warning).emit()
1121 }
1122
1123 #[track_caller]
1124 pub fn struct_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1125 Diag::new(self, Note, msg)
1126 }
1127
1128 #[track_caller]
1129 pub fn note(&self, msg: impl Into<DiagMessage>) {
1130 self.struct_note(msg).emit()
1131 }
1132
1133 #[track_caller]
1134 pub fn struct_span_note(
1135 self,
1136 span: impl Into<MultiSpan>,
1137 msg: impl Into<DiagMessage>,
1138 ) -> Diag<'a, ()> {
1139 self.struct_note(msg).with_span(span)
1140 }
1141
1142 #[track_caller]
1143 pub fn span_note(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
1144 self.struct_span_note(span, msg).emit()
1145 }
1146
1147 #[track_caller]
1148 pub fn create_note(self, note: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
1149 note.into_diag(self, Note)
1150 }
1151
1152 #[track_caller]
1153 pub fn emit_note(self, note: impl Diagnostic<'a, ()>) {
1154 self.create_note(note).emit()
1155 }
1156
1157 #[track_caller]
1158 pub fn struct_help(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1159 Diag::new(self, Help, msg)
1160 }
1161
1162 #[track_caller]
1163 pub fn struct_failure_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1164 Diag::new(self, FailureNote, msg)
1165 }
1166
1167 #[track_caller]
1168 pub fn struct_allow(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1169 Diag::new(self, Allow, msg)
1170 }
1171
1172 #[track_caller]
1173 pub fn struct_expect(self, msg: impl Into<DiagMessage>, id: LintExpectationId) -> Diag<'a, ()> {
1174 Diag::new(self, Expect, msg).with_lint_id(id)
1175 }
1176}
1177
1178impl DiagCtxtInner {
1183 fn new(emitter: Box<DynEmitter>) -> Self {
1184 Self {
1185 flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
1186 err_guars: Vec::new(),
1187 lint_err_guars: Vec::new(),
1188 delayed_bugs: Vec::new(),
1189 deduplicated_err_count: 0,
1190 deduplicated_warn_count: 0,
1191 emitter,
1192 must_produce_diag: None,
1193 has_printed: false,
1194 suppressed_expected_diag: false,
1195 taught_diagnostics: Default::default(),
1196 emitted_diagnostic_codes: Default::default(),
1197 emitted_diagnostics: Default::default(),
1198 stashed_diagnostics: Default::default(),
1199 future_breakage_diagnostics: Vec::new(),
1200 fulfilled_expectations: Default::default(),
1201 ice_file: None,
1202 msrv: None,
1203 }
1204 }
1205
1206 fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
1208 let mut guar = None;
1209 let has_errors = !self.err_guars.is_empty();
1210 for (_, stashed_diagnostics) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
1211 for (_, (diag, _guar, _thread)) in stashed_diagnostics {
1212 if !diag.is_error() {
1213 if !diag.is_force_warn() && has_errors {
1217 continue;
1218 }
1219 }
1220 guar = guar.or(self.emit_diagnostic(diag, None));
1221 }
1222 }
1223 guar
1224 }
1225
1226 fn emit_diagnostic(
1228 &mut self,
1229 mut diagnostic: DiagInner,
1230 taint: Option<&Cell<Option<ErrorGuaranteed>>>,
1231 ) -> Option<ErrorGuaranteed> {
1232 if diagnostic.has_future_breakage() {
1233 {
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);
1237 self.future_breakage_diagnostics.push(diagnostic.clone());
1238 }
1239
1240 match diagnostic.level {
1244 Bug => {}
1245 Fatal | Error => {
1246 if self.treat_next_err_as_bug() {
1247 diagnostic.level = Bug;
1249 }
1250 }
1251 DelayedBug => {
1252 if self.flags.eagerly_emit_delayed_bugs {
1257 if self.treat_next_err_as_bug() {
1259 diagnostic.level = Bug;
1260 } else {
1261 diagnostic.level = Error;
1262 }
1263 } else {
1264 return if let Some(guar) = self.has_errors() {
1267 Some(guar)
1268 } else {
1269 let backtrace = std::backtrace::Backtrace::capture();
1273 #[allow(deprecated)]
1277 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
1278 self.delayed_bugs
1279 .push((DelayedDiagInner::with_backtrace(diagnostic, backtrace), guar));
1280 Some(guar)
1281 };
1282 }
1283 }
1284 ForceWarning if diagnostic.lint_id.is_none() => {} Warning => {
1286 if !self.flags.can_emit_warnings {
1287 if diagnostic.has_future_breakage() {
1289 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1291 }
1292 return None;
1293 }
1294 }
1295 Note | Help | FailureNote => {}
1296 OnceNote | OnceHelp => {
::core::panicking::panic_fmt(format_args!("bad level: {0:?}",
diagnostic.level));
}panic!("bad level: {:?}", diagnostic.level),
1297 Allow => {
1298 if diagnostic.has_future_breakage() {
1300 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1302 self.suppressed_expected_diag = true;
1303 }
1304 return None;
1305 }
1306 Expect | ForceWarning => {
1307 self.fulfilled_expectations.insert(diagnostic.lint_id.unwrap());
1308 if let Expect = diagnostic.level {
1309 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1311 self.suppressed_expected_diag = true;
1312 return None;
1313 }
1314 }
1315 }
1316
1317 if let (Some(msrv), Some(diag_msrv)) = (self.msrv, diagnostic.rust_version())
1318 && diag_msrv > msrv
1319 {
1320 return None;
1321 }
1322
1323 TRACK_DIAGNOSTIC(diagnostic, &mut |mut diagnostic| {
1324 if let Some(code) = diagnostic.code {
1325 self.emitted_diagnostic_codes.insert(code);
1326 }
1327
1328 let already_emitted = {
1329 let mut hasher = StableHasher::new();
1330 diagnostic.hash(&mut hasher);
1331 let diagnostic_hash = hasher.finish();
1332 !self.emitted_diagnostics.insert(diagnostic_hash)
1333 };
1334
1335 let is_error = diagnostic.is_error();
1336 let is_lint = diagnostic.is_lint.is_some();
1337
1338 if !(self.flags.deduplicate_diagnostics && already_emitted) {
1341 {
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:1341",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1341u32),
::tracing_core::__macro_support::Option::Some("rustc_errors"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("diagnostic")
}> =
::tracing::__macro_support::FieldName::new("diagnostic");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&diagnostic)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?diagnostic);
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(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("self.emitted_diagnostics")
}> =
::tracing::__macro_support::FieldName::new("self.emitted_diagnostics");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&self.emitted_diagnostics)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?self.emitted_diagnostics);
1343
1344 let not_yet_emitted = |sub: &mut Subdiag| {
1345 {
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:1345",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1345u32),
::tracing_core::__macro_support::Option::Some("rustc_errors"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("sub")
}> =
::tracing::__macro_support::FieldName::new("sub");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sub)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?sub);
1346 if sub.level != OnceNote && sub.level != OnceHelp {
1347 return true;
1348 }
1349 let mut hasher = StableHasher::new();
1350 sub.hash(&mut hasher);
1351 let diagnostic_hash = hasher.finish();
1352 {
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:1352",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1352u32),
::tracing_core::__macro_support::Option::Some("rustc_errors"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("diagnostic_hash")
}> =
::tracing::__macro_support::FieldName::new("diagnostic_hash");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&diagnostic_hash)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?diagnostic_hash);
1353 self.emitted_diagnostics.insert(diagnostic_hash)
1354 };
1355 diagnostic.children.retain_mut(not_yet_emitted);
1356 if already_emitted {
1357 let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`";
1358 diagnostic.sub(Note, msg, MultiSpan::new());
1359 }
1360
1361 if is_error {
1362 self.deduplicated_err_count += 1;
1363 } else if #[allow(non_exhaustive_omitted_patterns)] match diagnostic.level {
ForceWarning | Warning => true,
_ => false,
}matches!(diagnostic.level, ForceWarning | Warning) {
1364 self.deduplicated_warn_count += 1;
1365 }
1366 self.has_printed = true;
1367
1368 self.emitter.emit_diagnostic(diagnostic);
1369 }
1370
1371 if is_error {
1372 if !self.delayed_bugs.is_empty() {
1377 {
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);
1378 self.delayed_bugs.clear();
1379 self.delayed_bugs.shrink_to_fit();
1380 }
1381
1382 #[allow(deprecated)]
1385 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
1386 let thread = std::thread::current().id();
1387 if is_lint {
1388 self.lint_err_guars.push((guar, thread));
1389 } else {
1390 if let Some(taint) = taint {
1391 taint.set(Some(guar));
1392 }
1393 self.err_guars.push((guar, thread));
1394 }
1395 self.panic_if_treat_err_as_bug();
1396 Some(guar)
1397 } else {
1398 None
1399 }
1400 })
1401 }
1402
1403 fn treat_err_as_bug(&self) -> bool {
1404 self.flags
1405 .treat_err_as_bug
1406 .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() >= c.get())
1407 }
1408
1409 fn treat_next_err_as_bug(&self) -> bool {
1411 self.flags
1412 .treat_err_as_bug
1413 .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() + 1 >= c.get())
1414 }
1415
1416 fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
1417 self.err_guars.get(0).map(|(guar, _)| *guar).or_else(|| {
1418 if let Some((_diag, guar, _)) = self
1419 .stashed_diagnostics
1420 .values()
1421 .flat_map(|stashed_diagnostics| stashed_diagnostics.values())
1422 .find(|(diag, guar, _)| guar.is_some() && diag.is_lint.is_none())
1423 {
1424 *guar
1425 } else {
1426 None
1427 }
1428 })
1429 }
1430
1431 fn has_errors(&self) -> Option<ErrorGuaranteed> {
1432 self.err_guars
1433 .get(0)
1434 .map(|(guar, _)| *guar)
1435 .or_else(|| self.lint_err_guars.get(0).map(|(guar, _)| *guar))
1436 .or_else(|| {
1437 self.stashed_diagnostics.values().find_map(|stashed_diagnostics| {
1438 stashed_diagnostics.values().find_map(|(_, guar, _)| *guar)
1439 })
1440 })
1441 }
1442
1443 fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
1444 self.has_errors().or_else(|| self.delayed_bugs.get(0).map(|(_, guar)| guar).copied())
1445 }
1446
1447 fn flush_delayed(&mut self) {
1448 if !self.stashed_diagnostics.is_empty() {
::core::panicking::panic("assertion failed: self.stashed_diagnostics.is_empty()")
};assert!(self.stashed_diagnostics.is_empty());
1452
1453 if !self.err_guars.is_empty() {
1454 return;
1456 }
1457
1458 if self.delayed_bugs.is_empty() {
1459 return;
1461 }
1462
1463 let bugs: Vec<_> =
1464 std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect();
1465
1466 let backtrace = std::env::var_os("RUST_BACKTRACE").as_deref() != Some(OsStr::new("0"));
1467 let decorate = backtrace || self.ice_file.is_none();
1468 let mut out = self
1469 .ice_file
1470 .as_ref()
1471 .and_then(|file| std::fs::File::options().create(true).append(true).open(file).ok());
1472
1473 let note1 = "no errors encountered even though delayed bugs were created";
1478 let note2 = "those delayed bugs will now be shown as internal compiler errors";
1479 self.emit_diagnostic(DiagInner::new(Note, note1), None);
1480 self.emit_diagnostic(DiagInner::new(Note, note2), None);
1481
1482 for bug in bugs {
1483 if let Some(out) = &mut out {
1484 _ = 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!(
1485 out,
1486 "delayed bug: {}\n{}\n",
1487 bug.inner
1488 .messages
1489 .iter()
1490 .filter_map(|(msg, _)| msg.as_str())
1491 .collect::<String>(),
1492 &bug.note
1493 );
1494 }
1495
1496 let mut bug = if decorate { bug.decorate() } else { bug.inner };
1497
1498 if bug.level != DelayedBug {
1500 let msg = rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"))msg!(
1507 "`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"
1508 ).arg("level", bug.level).format();
1509 bug.sub(Note, msg, bug.span.primary_span().unwrap().into());
1510 }
1511 bug.level = Bug;
1512
1513 self.emit_diagnostic(bug, None);
1514 }
1515
1516 panic::panic_any(DelayedBugPanic);
1518 }
1519
1520 fn panic_if_treat_err_as_bug(&self) {
1521 if self.treat_err_as_bug() {
1522 let n = self.flags.treat_err_as_bug.map(|c| c.get()).unwrap();
1523 {
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());
1524 if n == 1 {
1525 {
::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`");
1526 } else {
1527 {
::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}`");
1528 }
1529 }
1530 }
1531}
1532
1533struct DelayedDiagInner {
1534 inner: DiagInner,
1535 note: Backtrace,
1536}
1537
1538impl DelayedDiagInner {
1539 fn with_backtrace(diagnostic: DiagInner, backtrace: Backtrace) -> Self {
1540 DelayedDiagInner { inner: diagnostic, note: backtrace }
1541 }
1542
1543 fn decorate(self) -> DiagInner {
1544 let mut diag = self.inner;
1548 let msg = match self.note.status() {
1549 BacktraceStatus::Captured => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("delayed at {$emitted_at}\n {$note}"))msg!(
1550 "delayed at {$emitted_at}
1551 {$note}"
1552 ),
1553 _ => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("delayed at {$emitted_at} - {$note}"))msg!("delayed at {$emitted_at} - {$note}"),
1556 }
1557 .arg("emitted_at", diag.emitted_at.clone())
1558 .arg("note", self.note)
1559 .format();
1560 diag.sub(Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into());
1561 diag
1562 }
1563}
1564
1565#[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 {
static __NAMES: &str =
"BugFatalErrorDelayedBugForceWarningWarningNoteOnceNoteHelpOnceHelpFailureNoteAllowExpect";
static __OFFSET: [usize; 14] =
[0usize, 3usize, 8usize, 13usize, 23usize, 35usize, 42usize,
46usize, 54usize, 58usize, 66usize, 77usize, 82usize,
88usize];
let __d = ::core::intrinsics::discriminant_value(self) as usize;
::core::fmt::Formatter::debug_c_like_enum_write_str(f, __NAMES,
&__OFFSET, __d)
}
}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)]
1585pub enum Level {
1586 Bug,
1588
1589 Fatal,
1592
1593 Error,
1596
1597 DelayedBug,
1602
1603 ForceWarning,
1609
1610 Warning,
1613
1614 Note,
1616
1617 OnceNote,
1619
1620 Help,
1622
1623 OnceHelp,
1625
1626 FailureNote,
1629
1630 Allow,
1632
1633 Expect,
1635}
1636
1637impl fmt::Display for Level {
1638 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1639 self.to_str().fmt(f)
1640 }
1641}
1642
1643impl Level {
1644 fn color(self) -> anstyle::Style {
1645 match self {
1646 Bug | Fatal | Error | DelayedBug => AnsiColor::BrightRed.on_default(),
1647 ForceWarning | Warning => {
1648 if falsecfg!(windows) {
1649 AnsiColor::BrightYellow.on_default()
1650 } else {
1651 AnsiColor::Yellow.on_default()
1652 }
1653 }
1654 Note | OnceNote => AnsiColor::BrightGreen.on_default(),
1655 Help | OnceHelp => AnsiColor::BrightCyan.on_default(),
1656 FailureNote => anstyle::Style::new(),
1657 Allow | Expect => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1658 }
1659 }
1660
1661 pub fn to_str(self) -> &'static str {
1662 match self {
1663 Bug | DelayedBug => "error: internal compiler error",
1664 Fatal | Error => "error",
1665 ForceWarning | Warning => "warning",
1666 Note | OnceNote => "note",
1667 Help | OnceHelp => "help",
1668 FailureNote => "failure-note",
1669 Allow | Expect => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1670 }
1671 }
1672
1673 pub fn is_failure_note(&self) -> bool {
1674 #[allow(non_exhaustive_omitted_patterns)] match *self {
FailureNote => true,
_ => false,
}matches!(*self, FailureNote)
1675 }
1676}
1677
1678impl IntoDiagArg for Level {
1679 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
1680 DiagArgValue::Str(Cow::from(self.to_string()))
1681 }
1682}
1683
1684#[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)]
1685pub enum Style {
1686 MainHeaderMsg,
1687 HeaderMsg,
1688 LineAndColumn,
1689 LineNumber,
1690 Quotation,
1691 UnderlinePrimary,
1692 UnderlineSecondary,
1693 LabelPrimary,
1694 LabelSecondary,
1695 NoStyle,
1696 Level(Level),
1697 Highlight,
1698 Addition,
1699 Removal,
1700}
1701
1702pub fn elided_lifetime_in_path_suggestion(
1704 source_map: &SourceMap,
1705 n: usize,
1706 path_span: Span,
1707 incl_angl_brckt: bool,
1708 insertion_span: Span,
1709) -> ElidedLifetimeInPathSubdiag {
1710 let expected = ExpectedLifetimeParameter { span: path_span, count: n };
1711 let indicate = source_map.is_span_accessible(insertion_span).then(|| {
1713 let anon_lts = ::alloc::vec::from_elem("'_", n)vec!["'_"; n].join(", ");
1714 let suggestion =
1715 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}, ") };
1716
1717 IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion }
1718 });
1719
1720 ElidedLifetimeInPathSubdiag { expected, indicate }
1721}
1722
1723pub fn a_or_an(s: &str) -> &'static str {
1727 let mut chars = s.chars();
1728 let Some(mut first_alpha_char) = chars.next() else {
1729 return "a";
1730 };
1731 if first_alpha_char == '`' {
1732 let Some(next) = chars.next() else {
1733 return "a";
1734 };
1735 first_alpha_char = next;
1736 }
1737 if ["a", "e", "i", "o", "u", "&"].contains(&&first_alpha_char.to_lowercase().to_string()[..]) {
1738 "an"
1739 } else {
1740 "a"
1741 }
1742}
1743
1744#[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)]
1745pub enum TerminalUrl {
1746 No,
1747 Yes,
1748 Auto,
1749}