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