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