1#![allow(internal_features)]
7#![allow(rustc::direct_use_of_rustc_type_ir)]
8#![cfg_attr(bootstrap, feature(assert_matches))]
9#![feature(associated_type_defaults)]
10#![feature(box_patterns)]
11#![feature(default_field_values)]
12#![feature(error_reporter)]
13#![feature(macro_metavar_expr_concat)]
14#![feature(negative_impls)]
15#![feature(never_type)]
16#![feature(rustc_attrs)]
17extern crate self as rustc_errors;
20
21use std::backtrace::{Backtrace, BacktraceStatus};
22use std::borrow::Cow;
23use std::cell::Cell;
24use std::ffi::OsStr;
25use std::hash::Hash;
26use std::io::Write;
27use std::num::NonZero;
28use std::ops::DerefMut;
29use std::path::{Path, PathBuf};
30use std::{fmt, panic};
31
32use Level::*;
33pub use anstream::{AutoStream, ColorChoice};
36pub use anstyle::{
37 Ansi256Color, AnsiColor, Color, EffectIter, Effects, Reset, RgbColor, Style as Anstyle,
38};
39pub use codes::*;
40pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer};
41pub use diagnostic::{
42 BugAbort, Diag, DiagInner, DiagStyledString, Diagnostic, EmissionGuarantee, FatalAbort,
43 LintDiagnostic, LintDiagnosticBox, StringPart, Subdiag, Subdiagnostic,
44};
45pub use diagnostic_impls::{
46 DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
47 IndicateAnonymousLifetime, SingleLabelManySpans,
48};
49pub use emitter::ColorConfig;
50use emitter::{DynEmitter, Emitter};
51use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
52use rustc_data_structures::stable_hasher::StableHasher;
53use rustc_data_structures::sync::{DynSend, Lock};
54use rustc_data_structures::{AtomicRef, assert_matches};
55pub use rustc_error_messages::{
56 DiagArg, DiagArgFromDisplay, DiagArgMap, DiagArgName, DiagArgValue, DiagMessage, IntoDiagArg,
57 LanguageIdentifier, MultiSpan, SpanLabel, fluent_bundle, into_diag_arg_using_display,
58};
59use rustc_hashes::Hash128;
60use rustc_lint_defs::LintExpectationId;
61pub use rustc_lint_defs::{Applicability, listify, pluralize};
62pub use rustc_macros::msg;
63use rustc_macros::{Decodable, Encodable};
64pub use rustc_span::ErrorGuaranteed;
65pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker, catch_fatal_errors};
66use rustc_span::source_map::SourceMap;
67use rustc_span::{DUMMY_SP, Span};
68use tracing::debug;
69
70use crate::emitter::TimingEvent;
71use crate::timings::TimingRecord;
72use crate::translation::format_diag_message;
73
74pub mod annotate_snippet_emitter_writer;
75pub mod codes;
76mod decorate_diag;
77mod diagnostic;
78mod diagnostic_impls;
79pub mod emitter;
80pub mod json;
81mod lock;
82pub mod markdown;
83pub mod timings;
84pub mod translation;
85
86pub type PResult<'a, T> = Result<T, Diag<'a>>;
87
88#[cfg(target_pointer_width = "64")]
90const _: [(); 24] = [(); ::std::mem::size_of::<PResult<'_, ()>>()];rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24);
91#[cfg(target_pointer_width = "64")]
92const _: [(); 24] = [(); ::std::mem::size_of::<PResult<'_, bool>>()];rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
93
94#[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)]
95pub enum SuggestionStyle {
96 HideCodeInline,
98 HideCodeAlways,
100 CompletelyHidden,
102 ShowCode,
106 ShowAlways,
108}
109
110impl SuggestionStyle {
111 fn hide_inline(&self) -> bool {
112 !#[allow(non_exhaustive_omitted_patterns)] match *self {
SuggestionStyle::ShowCode => true,
_ => false,
}matches!(*self, SuggestionStyle::ShowCode)
113 }
114}
115
116#[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)]
118pub enum Suggestions {
119 Enabled(Vec<CodeSuggestion>),
124 Sealed(Box<[CodeSuggestion]>),
128 Disabled,
132}
133
134impl Suggestions {
135 pub fn unwrap_tag(self) -> Vec<CodeSuggestion> {
137 match self {
138 Suggestions::Enabled(suggestions) => suggestions,
139 Suggestions::Sealed(suggestions) => suggestions.into_vec(),
140 Suggestions::Disabled => Vec::new(),
141 }
142 }
143}
144
145impl Default for Suggestions {
146 fn default() -> Self {
147 Self::Enabled(::alloc::vec::Vec::new()vec![])
148 }
149}
150
151#[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)]
152pub struct CodeSuggestion {
153 pub substitutions: Vec<Substitution>,
175 pub msg: DiagMessage,
176 pub style: SuggestionStyle,
178 pub applicability: Applicability,
184}
185
186#[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)]
187pub struct Substitution {
189 pub parts: Vec<SubstitutionPart>,
190}
191
192#[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)]
193pub struct SubstitutionPart {
194 pub span: Span,
195 pub snippet: String,
196}
197
198#[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)]
199pub struct TrimmedSubstitutionPart {
200 pub original_span: Span,
201 pub span: Span,
202 pub snippet: String,
203}
204
205impl TrimmedSubstitutionPart {
206 pub fn is_addition(&self, sm: &SourceMap) -> bool {
207 !self.snippet.is_empty() && !self.replaces_meaningful_content(sm)
208 }
209
210 pub fn is_deletion(&self, sm: &SourceMap) -> bool {
211 self.snippet.trim().is_empty() && self.replaces_meaningful_content(sm)
212 }
213
214 pub fn is_replacement(&self, sm: &SourceMap) -> bool {
215 !self.snippet.is_empty() && self.replaces_meaningful_content(sm)
216 }
217
218 pub fn is_destructive_replacement(&self, sm: &SourceMap) -> bool {
223 self.is_replacement(sm)
224 && !sm
225 .span_to_snippet(self.span)
226 .is_ok_and(|snippet| as_substr(snippet.trim(), self.snippet.trim()).is_some())
227 }
228
229 fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool {
230 sm.span_to_snippet(self.span)
231 .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty())
232 }
233}
234
235fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a str, usize)> {
240 let common_prefix = original
241 .chars()
242 .zip(suggestion.chars())
243 .take_while(|(c1, c2)| c1 == c2)
244 .map(|(c, _)| c.len_utf8())
245 .sum();
246 let original = &original[common_prefix..];
247 let suggestion = &suggestion[common_prefix..];
248 if suggestion.ends_with(original) {
249 let common_suffix = original.len();
250 Some((common_prefix, &suggestion[..suggestion.len() - original.len()], common_suffix))
251 } else {
252 None
253 }
254}
255
256pub struct ExplicitBug;
259
260pub struct DelayedBugPanic;
263
264pub struct DiagCtxt {
268 inner: Lock<DiagCtxtInner>,
269}
270
271#[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)]
272pub struct DiagCtxtHandle<'a> {
273 dcx: &'a DiagCtxt,
274 tainted_with_errors: Option<&'a Cell<Option<ErrorGuaranteed>>>,
277}
278
279impl<'a> std::ops::Deref for DiagCtxtHandle<'a> {
280 type Target = &'a DiagCtxt;
281
282 fn deref(&self) -> &Self::Target {
283 &self.dcx
284 }
285}
286
287struct DiagCtxtInner {
291 flags: DiagCtxtFlags,
292
293 err_guars: Vec<ErrorGuaranteed>,
295 lint_err_guars: Vec<ErrorGuaranteed>,
298 delayed_bugs: Vec<(DelayedDiagInner, ErrorGuaranteed)>,
300
301 deduplicated_err_count: usize,
303 deduplicated_warn_count: usize,
305
306 emitter: Box<DynEmitter>,
307
308 must_produce_diag: Option<Backtrace>,
311
312 has_printed: bool,
315
316 suppressed_expected_diag: bool,
319
320 taught_diagnostics: FxHashSet<ErrCode>,
324
325 emitted_diagnostic_codes: FxIndexSet<ErrCode>,
327
328 emitted_diagnostics: FxHashSet<Hash128>,
332
333 stashed_diagnostics:
339 FxIndexMap<StashKey, FxIndexMap<Span, (DiagInner, Option<ErrorGuaranteed>)>>,
340
341 future_breakage_diagnostics: Vec<DiagInner>,
342
343 fulfilled_expectations: FxIndexSet<LintExpectationId>,
355
356 ice_file: Option<PathBuf>,
359}
360
361#[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::Cycle => "Cycle",
StashKey::UndeterminedMacroResolution =>
"UndeterminedMacroResolution",
StashKey::ExprInPat => "ExprInPat",
StashKey::GenericInFieldExpr => "GenericInFieldExpr",
})
}
}Debug)]
363pub enum StashKey {
364 ItemNoType,
365 UnderscoreForArrayLengths,
366 EarlySyntaxWarning,
367 CallIntoMethod,
368 LifetimeIsChar,
371 MaybeFruTypo,
374 CallAssocMethod,
375 AssociatedTypeSuggestion,
376 Cycle,
378 UndeterminedMacroResolution,
379 ExprInPat,
381 GenericInFieldExpr,
385}
386
387fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
388 (*f)(diag)
389}
390
391pub static TRACK_DIAGNOSTIC: AtomicRef<
394 fn(DiagInner, &mut dyn FnMut(DiagInner) -> Option<ErrorGuaranteed>) -> Option<ErrorGuaranteed>,
395> = AtomicRef::new(&(default_track_diagnostic as _));
396
397#[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)]
398pub struct DiagCtxtFlags {
399 pub can_emit_warnings: bool,
402 pub treat_err_as_bug: Option<NonZero<usize>>,
405 pub eagerly_emit_delayed_bugs: bool,
408 pub macro_backtrace: bool,
411 pub deduplicate_diagnostics: bool,
413 pub track_diagnostics: bool,
415}
416
417impl Drop for DiagCtxtInner {
418 fn drop(&mut self) {
419 self.emit_stashed_diagnostics();
427
428 self.flush_delayed();
432
433 if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() {
437 if let Some(backtrace) = &self.must_produce_diag {
438 let suggestion = match backtrace.status() {
439 BacktraceStatus::Disabled => String::from(
440 "Backtraces are currently disabled: set `RUST_BACKTRACE=1` and re-run \
441 to see where it happened.",
442 ),
443 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!(
444 "This happened in the following `must_produce_diag` call's backtrace:\n\
445 {backtrace}",
446 ),
447 _ => String::from("(impossible to capture backtrace where this happened)"),
448 };
449 {
::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!(
450 "`trimmed_def_paths` called, diagnostics were expected but none were emitted. \
451 Use `with_no_trimmed_paths` for debugging. {suggestion}"
452 );
453 }
454 }
455 }
456}
457
458impl DiagCtxt {
459 pub fn disable_warnings(mut self) -> Self {
460 self.inner.get_mut().flags.can_emit_warnings = false;
461 self
462 }
463
464 pub fn with_flags(mut self, flags: DiagCtxtFlags) -> Self {
465 self.inner.get_mut().flags = flags;
466 self
467 }
468
469 pub fn with_ice_file(mut self, ice_file: PathBuf) -> Self {
470 self.inner.get_mut().ice_file = Some(ice_file);
471 self
472 }
473
474 pub fn new(emitter: Box<DynEmitter>) -> Self {
475 Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
476 }
477
478 pub fn make_silent(&self) {
479 let mut inner = self.inner.borrow_mut();
480 inner.emitter = Box::new(emitter::SilentEmitter {});
481 }
482
483 pub fn set_emitter(&self, emitter: Box<dyn Emitter + DynSend>) {
484 self.inner.borrow_mut().emitter = emitter;
485 }
486
487 pub fn eagerly_translate<'a>(
489 &self,
490 message: DiagMessage,
491 args: impl Iterator<Item = DiagArg<'a>>,
492 ) -> DiagMessage {
493 let inner = self.inner.borrow();
494 inner.eagerly_translate(message, args)
495 }
496
497 pub fn eagerly_translate_to_string<'a>(
499 &self,
500 message: DiagMessage,
501 args: impl Iterator<Item = DiagArg<'a>>,
502 ) -> String {
503 let inner = self.inner.borrow();
504 inner.eagerly_translate_to_string(message, args)
505 }
506
507 pub fn can_emit_warnings(&self) -> bool {
511 self.inner.borrow_mut().flags.can_emit_warnings
512 }
513
514 pub fn reset_err_count(&self) {
520 let mut inner = self.inner.borrow_mut();
523 let DiagCtxtInner {
524 flags: _,
525 err_guars,
526 lint_err_guars,
527 delayed_bugs,
528 deduplicated_err_count,
529 deduplicated_warn_count,
530 emitter: _,
531 must_produce_diag,
532 has_printed,
533 suppressed_expected_diag,
534 taught_diagnostics,
535 emitted_diagnostic_codes,
536 emitted_diagnostics,
537 stashed_diagnostics,
538 future_breakage_diagnostics,
539 fulfilled_expectations,
540 ice_file: _,
541 } = inner.deref_mut();
542
543 *err_guars = Default::default();
546 *lint_err_guars = Default::default();
547 *delayed_bugs = Default::default();
548 *deduplicated_err_count = 0;
549 *deduplicated_warn_count = 0;
550 *must_produce_diag = None;
551 *has_printed = false;
552 *suppressed_expected_diag = false;
553 *taught_diagnostics = Default::default();
554 *emitted_diagnostic_codes = Default::default();
555 *emitted_diagnostics = Default::default();
556 *stashed_diagnostics = Default::default();
557 *future_breakage_diagnostics = Default::default();
558 *fulfilled_expectations = Default::default();
559 }
560
561 pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> {
562 DiagCtxtHandle { dcx: self, tainted_with_errors: None }
563 }
564
565 pub fn taintable_handle<'a>(
569 &'a self,
570 tainted_with_errors: &'a Cell<Option<ErrorGuaranteed>>,
571 ) -> DiagCtxtHandle<'a> {
572 DiagCtxtHandle { dcx: self, tainted_with_errors: Some(tainted_with_errors) }
573 }
574}
575
576impl<'a> DiagCtxtHandle<'a> {
577 pub fn stash_diagnostic(
599 &self,
600 span: Span,
601 key: StashKey,
602 diag: DiagInner,
603 ) -> Option<ErrorGuaranteed> {
604 let guar = match diag.level {
605 Bug | Fatal => {
606 self.span_bug(
607 span,
608 ::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),
609 );
610 }
611 Error => Some(self.span_delayed_bug(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("stashing {0:?}", key))
})format!("stashing {key:?}"))),
615 DelayedBug => {
616 return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors);
617 }
618 ForceWarning | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
619 | Expect => None,
620 };
621
622 self.inner
626 .borrow_mut()
627 .stashed_diagnostics
628 .entry(key)
629 .or_default()
630 .insert(span.with_parent(None), (diag, guar));
631
632 guar
633 }
634
635 pub fn steal_non_err(self, span: Span, key: StashKey) -> Option<Diag<'a, ()>> {
639 let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
641 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
642 )?;
643 if !!diag.is_error() {
::core::panicking::panic("assertion failed: !diag.is_error()")
};assert!(!diag.is_error());
644 if !guar.is_none() {
::core::panicking::panic("assertion failed: guar.is_none()")
};assert!(guar.is_none());
645 Some(Diag::new_diagnostic(self, diag))
646 }
647
648 pub fn try_steal_modify_and_emit_err<F>(
653 self,
654 span: Span,
655 key: StashKey,
656 mut modify_err: F,
657 ) -> Option<ErrorGuaranteed>
658 where
659 F: FnMut(&mut Diag<'_>),
660 {
661 let err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
663 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
664 );
665 err.map(|(err, guar)| {
666 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);
668 if !guar.is_some() {
::core::panicking::panic("assertion failed: guar.is_some()")
};assert!(guar.is_some());
669 let mut err = Diag::<ErrorGuaranteed>::new_diagnostic(self, err);
670 modify_err(&mut err);
671 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);
672 err.emit()
673 })
674 }
675
676 pub fn try_steal_replace_and_emit_err(
680 self,
681 span: Span,
682 key: StashKey,
683 new_err: Diag<'_>,
684 ) -> ErrorGuaranteed {
685 let old_err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
687 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
688 );
689 match old_err {
690 Some((old_err, guar)) => {
691 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);
692 if !guar.is_some() {
::core::panicking::panic("assertion failed: guar.is_some()")
};assert!(guar.is_some());
693 Diag::<ErrorGuaranteed>::new_diagnostic(self, old_err).cancel();
696 }
697 None => {}
698 };
699 new_err.emit()
700 }
701
702 pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool {
703 let inner = self.inner.borrow();
704 if let Some(stashed_diagnostics) = inner.stashed_diagnostics.get(&key)
705 && !stashed_diagnostics.is_empty()
706 {
707 stashed_diagnostics.contains_key(&span.with_parent(None))
708 } else {
709 false
710 }
711 }
712
713 pub fn emit_stashed_diagnostics(&self) -> Option<ErrorGuaranteed> {
715 self.inner.borrow_mut().emit_stashed_diagnostics()
716 }
717
718 #[inline]
720 pub fn err_count(&self) -> usize {
721 let inner = self.inner.borrow();
722 inner.err_guars.len()
723 + inner.lint_err_guars.len()
724 + inner
725 .stashed_diagnostics
726 .values()
727 .map(|a| a.values().filter(|(_, guar)| guar.is_some()).count())
728 .sum::<usize>()
729 }
730
731 pub fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
734 self.inner.borrow().has_errors_excluding_lint_errors()
735 }
736
737 pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
739 self.inner.borrow().has_errors()
740 }
741
742 pub fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
745 self.inner.borrow().has_errors_or_delayed_bugs()
746 }
747
748 pub fn print_error_count(&self) {
749 let mut inner = self.inner.borrow_mut();
750
751 if !inner.stashed_diagnostics.is_empty() {
::core::panicking::panic("assertion failed: inner.stashed_diagnostics.is_empty()")
};assert!(inner.stashed_diagnostics.is_empty());
754
755 if inner.treat_err_as_bug() {
756 return;
757 }
758
759 let warnings = match inner.deduplicated_warn_count {
760 0 => Cow::from(""),
761 1 => Cow::from("1 warning emitted"),
762 count => Cow::from(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} warnings emitted", count))
})format!("{count} warnings emitted")),
763 };
764 let errors = match inner.deduplicated_err_count {
765 0 => Cow::from(""),
766 1 => Cow::from("aborting due to 1 previous error"),
767 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")),
768 };
769
770 match (errors.len(), warnings.len()) {
771 (0, 0) => return,
772 (0, _) => {
773 inner.emit_diagnostic(
776 DiagInner::new(ForceWarning, DiagMessage::Str(warnings)),
777 None,
778 );
779 }
780 (_, 0) => {
781 inner.emit_diagnostic(DiagInner::new(Error, errors), self.tainted_with_errors);
782 }
783 (_, _) => {
784 inner.emit_diagnostic(
785 DiagInner::new(Error, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}; {1}", errors, warnings))
})format!("{errors}; {warnings}")),
786 self.tainted_with_errors,
787 );
788 }
789 }
790
791 let can_show_explain = inner.emitter.should_show_explain();
792 let are_there_diagnostics = !inner.emitted_diagnostic_codes.is_empty();
793 if can_show_explain && are_there_diagnostics {
794 let mut error_codes = inner
795 .emitted_diagnostic_codes
796 .iter()
797 .filter_map(|&code| {
798 if crate::codes::try_find_description(code).is_ok() {
799 Some(code.to_string())
800 } else {
801 None
802 }
803 })
804 .collect::<Vec<_>>();
805 if !error_codes.is_empty() {
806 error_codes.sort();
807 if error_codes.len() > 1 {
808 let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
809 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!(
810 "Some errors have detailed explanations: {}{}",
811 error_codes[..limit].join(", "),
812 if error_codes.len() > 9 { "..." } else { "." }
813 );
814 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!(
815 "For more information about an error, try `rustc --explain {}`.",
816 &error_codes[0]
817 );
818 inner.emit_diagnostic(DiagInner::new(FailureNote, msg1), None);
819 inner.emit_diagnostic(DiagInner::new(FailureNote, msg2), None);
820 } else {
821 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!(
822 "For more information about this error, try `rustc --explain {}`.",
823 &error_codes[0]
824 );
825 inner.emit_diagnostic(DiagInner::new(FailureNote, msg), None);
826 }
827 }
828 }
829 }
830
831 pub fn abort_if_errors(&self) {
836 if let Some(guar) = self.has_errors() {
837 guar.raise_fatal();
838 }
839 }
840
841 pub fn must_teach(&self, code: ErrCode) -> bool {
847 self.inner.borrow_mut().taught_diagnostics.insert(code)
848 }
849
850 pub fn emit_diagnostic(&self, diagnostic: DiagInner) -> Option<ErrorGuaranteed> {
851 self.inner.borrow_mut().emit_diagnostic(diagnostic, self.tainted_with_errors)
852 }
853
854 pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
855 self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type);
856 }
857
858 pub fn emit_timing_section_start(&self, record: TimingRecord) {
859 self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::Start);
860 }
861
862 pub fn emit_timing_section_end(&self, record: TimingRecord) {
863 self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::End);
864 }
865
866 pub fn emit_future_breakage_report(&self) {
867 let inner = &mut *self.inner.borrow_mut();
868 let diags = std::mem::take(&mut inner.future_breakage_diagnostics);
869 if !diags.is_empty() {
870 inner.emitter.emit_future_breakage_report(diags);
871 }
872 }
873
874 pub fn emit_unused_externs(
875 &self,
876 lint_level: rustc_lint_defs::Level,
877 loud: bool,
878 unused_externs: &[&str],
879 ) {
880 let mut inner = self.inner.borrow_mut();
881
882 if loud && lint_level.is_error() {
893 #[allow(deprecated)]
896 inner.lint_err_guars.push(ErrorGuaranteed::unchecked_error_guaranteed());
897 inner.panic_if_treat_err_as_bug();
898 }
899
900 inner.emitter.emit_unused_externs(lint_level, unused_externs)
901 }
902
903 #[must_use]
906 pub fn steal_fulfilled_expectation_ids(&self) -> FxIndexSet<LintExpectationId> {
907 std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations)
908 }
909
910 pub fn flush_delayed(&self) {
915 self.inner.borrow_mut().flush_delayed();
916 }
917
918 #[track_caller]
921 pub fn set_must_produce_diag(&self) {
922 if !self.inner.borrow().must_produce_diag.is_none() {
{
::core::panicking::panic_fmt(format_args!("should only need to collect a backtrace once"));
}
};assert!(
923 self.inner.borrow().must_produce_diag.is_none(),
924 "should only need to collect a backtrace once"
925 );
926 self.inner.borrow_mut().must_produce_diag = Some(Backtrace::capture());
927 }
928}
929
930impl<'a> DiagCtxtHandle<'a> {
935 #[track_caller]
936 pub fn struct_bug(self, msg: impl Into<Cow<'static, str>>) -> Diag<'a, BugAbort> {
937 Diag::new(self, Bug, msg.into())
938 }
939
940 #[track_caller]
941 pub fn bug(self, msg: impl Into<Cow<'static, str>>) -> ! {
942 self.struct_bug(msg).emit()
943 }
944
945 #[track_caller]
946 pub fn struct_span_bug(
947 self,
948 span: impl Into<MultiSpan>,
949 msg: impl Into<Cow<'static, str>>,
950 ) -> Diag<'a, BugAbort> {
951 self.struct_bug(msg).with_span(span)
952 }
953
954 #[track_caller]
955 pub fn span_bug(self, span: impl Into<MultiSpan>, msg: impl Into<Cow<'static, str>>) -> ! {
956 self.struct_span_bug(span, msg.into()).emit()
957 }
958
959 #[track_caller]
960 pub fn create_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> Diag<'a, BugAbort> {
961 bug.into_diag(self, Bug)
962 }
963
964 #[track_caller]
965 pub fn emit_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> ! {
966 self.create_bug(bug).emit()
967 }
968
969 #[track_caller]
970 pub fn struct_fatal(self, msg: impl Into<DiagMessage>) -> Diag<'a, FatalAbort> {
971 Diag::new(self, Fatal, msg)
972 }
973
974 #[track_caller]
975 pub fn fatal(self, msg: impl Into<DiagMessage>) -> ! {
976 self.struct_fatal(msg).emit()
977 }
978
979 #[track_caller]
980 pub fn struct_span_fatal(
981 self,
982 span: impl Into<MultiSpan>,
983 msg: impl Into<DiagMessage>,
984 ) -> Diag<'a, FatalAbort> {
985 self.struct_fatal(msg).with_span(span)
986 }
987
988 #[track_caller]
989 pub fn span_fatal(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) -> ! {
990 self.struct_span_fatal(span, msg).emit()
991 }
992
993 #[track_caller]
994 pub fn create_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> Diag<'a, FatalAbort> {
995 fatal.into_diag(self, Fatal)
996 }
997
998 #[track_caller]
999 pub fn emit_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> ! {
1000 self.create_fatal(fatal).emit()
1001 }
1002
1003 #[track_caller]
1004 pub fn create_almost_fatal(
1005 self,
1006 fatal: impl Diagnostic<'a, FatalError>,
1007 ) -> Diag<'a, FatalError> {
1008 fatal.into_diag(self, Fatal)
1009 }
1010
1011 #[track_caller]
1012 pub fn emit_almost_fatal(self, fatal: impl Diagnostic<'a, FatalError>) -> FatalError {
1013 self.create_almost_fatal(fatal).emit()
1014 }
1015
1016 #[track_caller]
1018 pub fn struct_err(self, msg: impl Into<DiagMessage>) -> Diag<'a> {
1019 Diag::new(self, Error, msg)
1020 }
1021
1022 #[track_caller]
1023 pub fn err(self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
1024 self.struct_err(msg).emit()
1025 }
1026
1027 #[track_caller]
1028 pub fn struct_span_err(
1029 self,
1030 span: impl Into<MultiSpan>,
1031 msg: impl Into<DiagMessage>,
1032 ) -> Diag<'a> {
1033 self.struct_err(msg).with_span(span)
1034 }
1035
1036 #[track_caller]
1037 pub fn span_err(
1038 self,
1039 span: impl Into<MultiSpan>,
1040 msg: impl Into<DiagMessage>,
1041 ) -> ErrorGuaranteed {
1042 self.struct_span_err(span, msg).emit()
1043 }
1044
1045 #[track_caller]
1046 pub fn create_err(self, err: impl Diagnostic<'a>) -> Diag<'a> {
1047 err.into_diag(self, Error)
1048 }
1049
1050 #[track_caller]
1051 pub fn emit_err(self, err: impl Diagnostic<'a>) -> ErrorGuaranteed {
1052 self.create_err(err).emit()
1053 }
1054
1055 #[track_caller]
1057 pub fn delayed_bug(self, msg: impl Into<Cow<'static, str>>) -> ErrorGuaranteed {
1058 Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).emit()
1059 }
1060
1061 #[track_caller]
1066 pub fn span_delayed_bug(
1067 self,
1068 sp: impl Into<MultiSpan>,
1069 msg: impl Into<Cow<'static, str>>,
1070 ) -> ErrorGuaranteed {
1071 Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).with_span(sp).emit()
1072 }
1073
1074 #[track_caller]
1075 pub fn struct_warn(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1076 Diag::new(self, Warning, msg)
1077 }
1078
1079 #[track_caller]
1080 pub fn warn(self, msg: impl Into<DiagMessage>) {
1081 self.struct_warn(msg).emit()
1082 }
1083
1084 #[track_caller]
1085 pub fn struct_span_warn(
1086 self,
1087 span: impl Into<MultiSpan>,
1088 msg: impl Into<DiagMessage>,
1089 ) -> Diag<'a, ()> {
1090 self.struct_warn(msg).with_span(span)
1091 }
1092
1093 #[track_caller]
1094 pub fn span_warn(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
1095 self.struct_span_warn(span, msg).emit()
1096 }
1097
1098 #[track_caller]
1099 pub fn create_warn(self, warning: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
1100 warning.into_diag(self, Warning)
1101 }
1102
1103 #[track_caller]
1104 pub fn emit_warn(self, warning: impl Diagnostic<'a, ()>) {
1105 self.create_warn(warning).emit()
1106 }
1107
1108 #[track_caller]
1109 pub fn struct_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1110 Diag::new(self, Note, msg)
1111 }
1112
1113 #[track_caller]
1114 pub fn note(&self, msg: impl Into<DiagMessage>) {
1115 self.struct_note(msg).emit()
1116 }
1117
1118 #[track_caller]
1119 pub fn struct_span_note(
1120 self,
1121 span: impl Into<MultiSpan>,
1122 msg: impl Into<DiagMessage>,
1123 ) -> Diag<'a, ()> {
1124 self.struct_note(msg).with_span(span)
1125 }
1126
1127 #[track_caller]
1128 pub fn span_note(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
1129 self.struct_span_note(span, msg).emit()
1130 }
1131
1132 #[track_caller]
1133 pub fn create_note(self, note: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
1134 note.into_diag(self, Note)
1135 }
1136
1137 #[track_caller]
1138 pub fn emit_note(self, note: impl Diagnostic<'a, ()>) {
1139 self.create_note(note).emit()
1140 }
1141
1142 #[track_caller]
1143 pub fn struct_help(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1144 Diag::new(self, Help, msg)
1145 }
1146
1147 #[track_caller]
1148 pub fn struct_failure_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1149 Diag::new(self, FailureNote, msg)
1150 }
1151
1152 #[track_caller]
1153 pub fn struct_allow(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1154 Diag::new(self, Allow, msg)
1155 }
1156
1157 #[track_caller]
1158 pub fn struct_expect(self, msg: impl Into<DiagMessage>, id: LintExpectationId) -> Diag<'a, ()> {
1159 Diag::new(self, Expect, msg).with_lint_id(id)
1160 }
1161}
1162
1163impl DiagCtxtInner {
1168 fn new(emitter: Box<DynEmitter>) -> Self {
1169 Self {
1170 flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
1171 err_guars: Vec::new(),
1172 lint_err_guars: Vec::new(),
1173 delayed_bugs: Vec::new(),
1174 deduplicated_err_count: 0,
1175 deduplicated_warn_count: 0,
1176 emitter,
1177 must_produce_diag: None,
1178 has_printed: false,
1179 suppressed_expected_diag: false,
1180 taught_diagnostics: Default::default(),
1181 emitted_diagnostic_codes: Default::default(),
1182 emitted_diagnostics: Default::default(),
1183 stashed_diagnostics: Default::default(),
1184 future_breakage_diagnostics: Vec::new(),
1185 fulfilled_expectations: Default::default(),
1186 ice_file: None,
1187 }
1188 }
1189
1190 fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
1192 let mut guar = None;
1193 let has_errors = !self.err_guars.is_empty();
1194 for (_, stashed_diagnostics) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
1195 for (_, (diag, _guar)) in stashed_diagnostics {
1196 if !diag.is_error() {
1197 if !diag.is_force_warn() && has_errors {
1201 continue;
1202 }
1203 }
1204 guar = guar.or(self.emit_diagnostic(diag, None));
1205 }
1206 }
1207 guar
1208 }
1209
1210 fn emit_diagnostic(
1212 &mut self,
1213 mut diagnostic: DiagInner,
1214 taint: Option<&Cell<Option<ErrorGuaranteed>>>,
1215 ) -> Option<ErrorGuaranteed> {
1216 if diagnostic.has_future_breakage() {
1217 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);
1221 self.future_breakage_diagnostics.push(diagnostic.clone());
1222 }
1223
1224 match diagnostic.level {
1228 Bug => {}
1229 Fatal | Error => {
1230 if self.treat_next_err_as_bug() {
1231 diagnostic.level = Bug;
1233 }
1234 }
1235 DelayedBug => {
1236 if self.flags.eagerly_emit_delayed_bugs {
1241 if self.treat_next_err_as_bug() {
1243 diagnostic.level = Bug;
1244 } else {
1245 diagnostic.level = Error;
1246 }
1247 } else {
1248 return if let Some(guar) = self.has_errors() {
1251 Some(guar)
1252 } else {
1253 let backtrace = std::backtrace::Backtrace::capture();
1257 #[allow(deprecated)]
1261 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
1262 self.delayed_bugs
1263 .push((DelayedDiagInner::with_backtrace(diagnostic, backtrace), guar));
1264 Some(guar)
1265 };
1266 }
1267 }
1268 ForceWarning if diagnostic.lint_id.is_none() => {} Warning => {
1270 if !self.flags.can_emit_warnings {
1271 if diagnostic.has_future_breakage() {
1273 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1275 }
1276 return None;
1277 }
1278 }
1279 Note | Help | FailureNote => {}
1280 OnceNote | OnceHelp => {
::core::panicking::panic_fmt(format_args!("bad level: {0:?}",
diagnostic.level));
}panic!("bad level: {:?}", diagnostic.level),
1281 Allow => {
1282 if diagnostic.has_future_breakage() {
1284 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1286 self.suppressed_expected_diag = true;
1287 }
1288 return None;
1289 }
1290 Expect | ForceWarning => {
1291 self.fulfilled_expectations.insert(diagnostic.lint_id.unwrap());
1292 if let Expect = diagnostic.level {
1293 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1295 self.suppressed_expected_diag = true;
1296 return None;
1297 }
1298 }
1299 }
1300
1301 TRACK_DIAGNOSTIC(diagnostic, &mut |mut diagnostic| {
1302 if let Some(code) = diagnostic.code {
1303 self.emitted_diagnostic_codes.insert(code);
1304 }
1305
1306 let already_emitted = {
1307 let mut hasher = StableHasher::new();
1308 diagnostic.hash(&mut hasher);
1309 let diagnostic_hash = hasher.finish();
1310 !self.emitted_diagnostics.insert(diagnostic_hash)
1311 };
1312
1313 let is_error = diagnostic.is_error();
1314 let is_lint = diagnostic.is_lint.is_some();
1315
1316 if !(self.flags.deduplicate_diagnostics && already_emitted) {
1319 {
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:1319",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1319u32),
::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);
1320 {
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:1320",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1320u32),
::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);
1321
1322 let not_yet_emitted = |sub: &mut Subdiag| {
1323 {
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:1323",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1323u32),
::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);
1324 if sub.level != OnceNote && sub.level != OnceHelp {
1325 return true;
1326 }
1327 let mut hasher = StableHasher::new();
1328 sub.hash(&mut hasher);
1329 let diagnostic_hash = hasher.finish();
1330 {
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:1330",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1330u32),
::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);
1331 self.emitted_diagnostics.insert(diagnostic_hash)
1332 };
1333 diagnostic.children.retain_mut(not_yet_emitted);
1334 if already_emitted {
1335 let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`";
1336 diagnostic.sub(Note, msg, MultiSpan::new());
1337 }
1338
1339 if is_error {
1340 self.deduplicated_err_count += 1;
1341 } else if #[allow(non_exhaustive_omitted_patterns)] match diagnostic.level {
ForceWarning | Warning => true,
_ => false,
}matches!(diagnostic.level, ForceWarning | Warning) {
1342 self.deduplicated_warn_count += 1;
1343 }
1344 self.has_printed = true;
1345
1346 self.emitter.emit_diagnostic(diagnostic);
1347 }
1348
1349 if is_error {
1350 if !self.delayed_bugs.is_empty() {
1355 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);
1356 self.delayed_bugs.clear();
1357 self.delayed_bugs.shrink_to_fit();
1358 }
1359
1360 #[allow(deprecated)]
1363 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
1364 if is_lint {
1365 self.lint_err_guars.push(guar);
1366 } else {
1367 if let Some(taint) = taint {
1368 taint.set(Some(guar));
1369 }
1370 self.err_guars.push(guar);
1371 }
1372 self.panic_if_treat_err_as_bug();
1373 Some(guar)
1374 } else {
1375 None
1376 }
1377 })
1378 }
1379
1380 fn treat_err_as_bug(&self) -> bool {
1381 self.flags
1382 .treat_err_as_bug
1383 .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() >= c.get())
1384 }
1385
1386 fn treat_next_err_as_bug(&self) -> bool {
1388 self.flags
1389 .treat_err_as_bug
1390 .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() + 1 >= c.get())
1391 }
1392
1393 fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
1394 self.err_guars.get(0).copied().or_else(|| {
1395 if let Some((_diag, guar)) = self
1396 .stashed_diagnostics
1397 .values()
1398 .flat_map(|stashed_diagnostics| stashed_diagnostics.values())
1399 .find(|(diag, guar)| guar.is_some() && diag.is_lint.is_none())
1400 {
1401 *guar
1402 } else {
1403 None
1404 }
1405 })
1406 }
1407
1408 fn has_errors(&self) -> Option<ErrorGuaranteed> {
1409 self.err_guars.get(0).copied().or_else(|| self.lint_err_guars.get(0).copied()).or_else(
1410 || {
1411 self.stashed_diagnostics.values().find_map(|stashed_diagnostics| {
1412 stashed_diagnostics.values().find_map(|(_, guar)| *guar)
1413 })
1414 },
1415 )
1416 }
1417
1418 fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
1419 self.has_errors().or_else(|| self.delayed_bugs.get(0).map(|(_, guar)| guar).copied())
1420 }
1421
1422 fn eagerly_translate<'a>(
1424 &self,
1425 message: DiagMessage,
1426 args: impl Iterator<Item = DiagArg<'a>>,
1427 ) -> DiagMessage {
1428 DiagMessage::Str(Cow::from(self.eagerly_translate_to_string(message, args)))
1429 }
1430
1431 fn eagerly_translate_to_string<'a>(
1433 &self,
1434 message: DiagMessage,
1435 args: impl Iterator<Item = DiagArg<'a>>,
1436 ) -> String {
1437 let args = args.map(|(name, val)| (name.clone(), val.clone())).collect();
1438 format_diag_message(&message, &args).to_string()
1439 }
1440
1441 fn eagerly_translate_for_subdiag(
1442 &self,
1443 diag: &DiagInner,
1444 msg: impl Into<DiagMessage>,
1445 ) -> DiagMessage {
1446 self.eagerly_translate(msg.into(), diag.args.iter())
1447 }
1448
1449 fn flush_delayed(&mut self) {
1450 if !self.stashed_diagnostics.is_empty() {
::core::panicking::panic("assertion failed: self.stashed_diagnostics.is_empty()")
};assert!(self.stashed_diagnostics.is_empty());
1454
1455 if !self.err_guars.is_empty() {
1456 return;
1458 }
1459
1460 if self.delayed_bugs.is_empty() {
1461 return;
1463 }
1464
1465 let bugs: Vec<_> =
1466 std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect();
1467
1468 let backtrace = std::env::var_os("RUST_BACKTRACE").as_deref() != Some(OsStr::new("0"));
1469 let decorate = backtrace || self.ice_file.is_none();
1470 let mut out = self
1471 .ice_file
1472 .as_ref()
1473 .and_then(|file| std::fs::File::options().create(true).append(true).open(file).ok());
1474
1475 let note1 = "no errors encountered even though delayed bugs were created";
1480 let note2 = "those delayed bugs will now be shown as internal compiler errors";
1481 self.emit_diagnostic(DiagInner::new(Note, note1), None);
1482 self.emit_diagnostic(DiagInner::new(Note, note2), None);
1483
1484 for bug in bugs {
1485 if let Some(out) = &mut out {
1486 _ = 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!(
1487 out,
1488 "delayed bug: {}\n{}\n",
1489 bug.inner
1490 .messages
1491 .iter()
1492 .filter_map(|(msg, _)| msg.as_str())
1493 .collect::<String>(),
1494 &bug.note
1495 );
1496 }
1497
1498 let mut bug = if decorate { bug.decorate(self) } else { bug.inner };
1499
1500 if bug.level != DelayedBug {
1502 bug.arg("level", bug.level);
1509 let msg = rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"))msg!(
1510 "`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"
1511 );
1512 let msg = self.eagerly_translate_for_subdiag(&bug, msg); bug.sub(Note, msg, bug.span.primary_span().unwrap().into());
1514 }
1515 bug.level = Bug;
1516
1517 self.emit_diagnostic(bug, None);
1518 }
1519
1520 panic::panic_any(DelayedBugPanic);
1522 }
1523
1524 fn panic_if_treat_err_as_bug(&self) {
1525 if self.treat_err_as_bug() {
1526 let n = self.flags.treat_err_as_bug.map(|c| c.get()).unwrap();
1527 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());
1528 if n == 1 {
1529 {
::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`");
1530 } else {
1531 {
::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}`");
1532 }
1533 }
1534 }
1535}
1536
1537struct DelayedDiagInner {
1538 inner: DiagInner,
1539 note: Backtrace,
1540}
1541
1542impl DelayedDiagInner {
1543 fn with_backtrace(diagnostic: DiagInner, backtrace: Backtrace) -> Self {
1544 DelayedDiagInner { inner: diagnostic, note: backtrace }
1545 }
1546
1547 fn decorate(self, dcx: &DiagCtxtInner) -> DiagInner {
1548 let mut diag = self.inner;
1552 let msg = match self.note.status() {
1553 BacktraceStatus::Captured => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("delayed at {$emitted_at}\n {$note}"))msg!(
1554 "delayed at {$emitted_at}
1555 {$note}"
1556 ),
1557 _ => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("delayed at {$emitted_at} - {$note}"))msg!("delayed at {$emitted_at} - {$note}"),
1560 };
1561 diag.arg("emitted_at", diag.emitted_at.clone());
1562 diag.arg("note", self.note);
1563 let msg = dcx.eagerly_translate_for_subdiag(&diag, msg); diag.sub(Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into());
1565 diag
1566 }
1567}
1568
1569#[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)]
1589pub enum Level {
1590 Bug,
1592
1593 Fatal,
1596
1597 Error,
1600
1601 DelayedBug,
1606
1607 ForceWarning,
1613
1614 Warning,
1617
1618 Note,
1620
1621 OnceNote,
1623
1624 Help,
1626
1627 OnceHelp,
1629
1630 FailureNote,
1633
1634 Allow,
1636
1637 Expect,
1639}
1640
1641impl fmt::Display for Level {
1642 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1643 self.to_str().fmt(f)
1644 }
1645}
1646
1647impl Level {
1648 fn color(self) -> anstyle::Style {
1649 match self {
1650 Bug | Fatal | Error | DelayedBug => AnsiColor::BrightRed.on_default(),
1651 ForceWarning | Warning => {
1652 if falsecfg!(windows) {
1653 AnsiColor::BrightYellow.on_default()
1654 } else {
1655 AnsiColor::Yellow.on_default()
1656 }
1657 }
1658 Note | OnceNote => AnsiColor::BrightGreen.on_default(),
1659 Help | OnceHelp => AnsiColor::BrightCyan.on_default(),
1660 FailureNote => anstyle::Style::new(),
1661 Allow | Expect => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1662 }
1663 }
1664
1665 pub fn to_str(self) -> &'static str {
1666 match self {
1667 Bug | DelayedBug => "error: internal compiler error",
1668 Fatal | Error => "error",
1669 ForceWarning | Warning => "warning",
1670 Note | OnceNote => "note",
1671 Help | OnceHelp => "help",
1672 FailureNote => "failure-note",
1673 Allow | Expect => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1674 }
1675 }
1676
1677 pub fn is_failure_note(&self) -> bool {
1678 #[allow(non_exhaustive_omitted_patterns)] match *self {
FailureNote => true,
_ => false,
}matches!(*self, FailureNote)
1679 }
1680}
1681
1682impl IntoDiagArg for Level {
1683 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
1684 DiagArgValue::Str(Cow::from(self.to_string()))
1685 }
1686}
1687
1688#[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)]
1689pub enum Style {
1690 MainHeaderMsg,
1691 HeaderMsg,
1692 LineAndColumn,
1693 LineNumber,
1694 Quotation,
1695 UnderlinePrimary,
1696 UnderlineSecondary,
1697 LabelPrimary,
1698 LabelSecondary,
1699 NoStyle,
1700 Level(Level),
1701 Highlight,
1702 Addition,
1703 Removal,
1704}
1705
1706pub fn elided_lifetime_in_path_suggestion(
1708 source_map: &SourceMap,
1709 n: usize,
1710 path_span: Span,
1711 incl_angl_brckt: bool,
1712 insertion_span: Span,
1713) -> ElidedLifetimeInPathSubdiag {
1714 let expected = ExpectedLifetimeParameter { span: path_span, count: n };
1715 let indicate = source_map.is_span_accessible(insertion_span).then(|| {
1717 let anon_lts = ::alloc::vec::from_elem("'_", n)vec!["'_"; n].join(", ");
1718 let suggestion =
1719 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}, ") };
1720
1721 IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion }
1722 });
1723
1724 ElidedLifetimeInPathSubdiag { expected, indicate }
1725}
1726
1727pub fn a_or_an(s: &str) -> &'static str {
1731 let mut chars = s.chars();
1732 let Some(mut first_alpha_char) = chars.next() else {
1733 return "a";
1734 };
1735 if first_alpha_char == '`' {
1736 let Some(next) = chars.next() else {
1737 return "a";
1738 };
1739 first_alpha_char = next;
1740 }
1741 if ["a", "e", "i", "o", "u", "&"].contains(&&first_alpha_char.to_lowercase().to_string()[..]) {
1742 "an"
1743 } else {
1744 "a"
1745 }
1746}
1747
1748#[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)]
1749pub enum TerminalUrl {
1750 No,
1751 Yes,
1752 Auto,
1753}