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, FluentBundle, IntoDiagArg,
58 LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, fallback_fluent_bundle,
59 fluent_bundle, into_diag_arg_using_display,
60};
61use rustc_hashes::Hash128;
62use rustc_lint_defs::LintExpectationId;
63pub use rustc_lint_defs::{Applicability, listify, pluralize};
64pub use rustc_macros::msg;
65use rustc_macros::{Decodable, Encodable};
66pub use rustc_span::ErrorGuaranteed;
67pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker, catch_fatal_errors};
68use rustc_span::source_map::SourceMap;
69use rustc_span::{DUMMY_SP, Span};
70use tracing::debug;
71
72use crate::emitter::TimingEvent;
73use crate::timings::TimingRecord;
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 {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_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 {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_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 let translator = inner.emitter.translator().clone();
483 inner.emitter = Box::new(emitter::SilentEmitter { translator });
484 }
485
486 pub fn set_emitter(&self, emitter: Box<dyn Emitter + DynSend>) {
487 self.inner.borrow_mut().emitter = emitter;
488 }
489
490 pub fn eagerly_translate<'a>(
492 &self,
493 message: DiagMessage,
494 args: impl Iterator<Item = DiagArg<'a>>,
495 ) -> DiagMessage {
496 let inner = self.inner.borrow();
497 inner.eagerly_translate(message, args)
498 }
499
500 pub fn eagerly_translate_to_string<'a>(
502 &self,
503 message: DiagMessage,
504 args: impl Iterator<Item = DiagArg<'a>>,
505 ) -> String {
506 let inner = self.inner.borrow();
507 inner.eagerly_translate_to_string(message, args)
508 }
509
510 pub fn can_emit_warnings(&self) -> bool {
514 self.inner.borrow_mut().flags.can_emit_warnings
515 }
516
517 pub fn reset_err_count(&self) {
523 let mut inner = self.inner.borrow_mut();
526 let DiagCtxtInner {
527 flags: _,
528 err_guars,
529 lint_err_guars,
530 delayed_bugs,
531 deduplicated_err_count,
532 deduplicated_warn_count,
533 emitter: _,
534 must_produce_diag,
535 has_printed,
536 suppressed_expected_diag,
537 taught_diagnostics,
538 emitted_diagnostic_codes,
539 emitted_diagnostics,
540 stashed_diagnostics,
541 future_breakage_diagnostics,
542 fulfilled_expectations,
543 ice_file: _,
544 } = inner.deref_mut();
545
546 *err_guars = Default::default();
549 *lint_err_guars = Default::default();
550 *delayed_bugs = Default::default();
551 *deduplicated_err_count = 0;
552 *deduplicated_warn_count = 0;
553 *must_produce_diag = None;
554 *has_printed = false;
555 *suppressed_expected_diag = false;
556 *taught_diagnostics = Default::default();
557 *emitted_diagnostic_codes = Default::default();
558 *emitted_diagnostics = Default::default();
559 *stashed_diagnostics = Default::default();
560 *future_breakage_diagnostics = Default::default();
561 *fulfilled_expectations = Default::default();
562 }
563
564 pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> {
565 DiagCtxtHandle { dcx: self, tainted_with_errors: None }
566 }
567
568 pub fn taintable_handle<'a>(
572 &'a self,
573 tainted_with_errors: &'a Cell<Option<ErrorGuaranteed>>,
574 ) -> DiagCtxtHandle<'a> {
575 DiagCtxtHandle { dcx: self, tainted_with_errors: Some(tainted_with_errors) }
576 }
577}
578
579impl<'a> DiagCtxtHandle<'a> {
580 pub fn stash_diagnostic(
602 &self,
603 span: Span,
604 key: StashKey,
605 diag: DiagInner,
606 ) -> Option<ErrorGuaranteed> {
607 let guar = match diag.level {
608 Bug | Fatal => {
609 self.span_bug(
610 span,
611 ::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),
612 );
613 }
614 Error => Some(self.span_delayed_bug(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("stashing {0:?}", key))
})format!("stashing {key:?}"))),
618 DelayedBug => {
619 return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors);
620 }
621 ForceWarning | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
622 | Expect => None,
623 };
624
625 self.inner
629 .borrow_mut()
630 .stashed_diagnostics
631 .entry(key)
632 .or_default()
633 .insert(span.with_parent(None), (diag, guar));
634
635 guar
636 }
637
638 pub fn steal_non_err(self, span: Span, key: StashKey) -> Option<Diag<'a, ()>> {
642 let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
644 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
645 )?;
646 if !!diag.is_error() {
::core::panicking::panic("assertion failed: !diag.is_error()")
};assert!(!diag.is_error());
647 if !guar.is_none() {
::core::panicking::panic("assertion failed: guar.is_none()")
};assert!(guar.is_none());
648 Some(Diag::new_diagnostic(self, diag))
649 }
650
651 pub fn try_steal_modify_and_emit_err<F>(
656 self,
657 span: Span,
658 key: StashKey,
659 mut modify_err: F,
660 ) -> Option<ErrorGuaranteed>
661 where
662 F: FnMut(&mut Diag<'_>),
663 {
664 let err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
666 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
667 );
668 err.map(|(err, guar)| {
669 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);
671 if !guar.is_some() {
::core::panicking::panic("assertion failed: guar.is_some()")
};assert!(guar.is_some());
672 let mut err = Diag::<ErrorGuaranteed>::new_diagnostic(self, err);
673 modify_err(&mut err);
674 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);
675 err.emit()
676 })
677 }
678
679 pub fn try_steal_replace_and_emit_err(
683 self,
684 span: Span,
685 key: StashKey,
686 new_err: Diag<'_>,
687 ) -> ErrorGuaranteed {
688 let old_err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
690 |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
691 );
692 match old_err {
693 Some((old_err, guar)) => {
694 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);
695 if !guar.is_some() {
::core::panicking::panic("assertion failed: guar.is_some()")
};assert!(guar.is_some());
696 Diag::<ErrorGuaranteed>::new_diagnostic(self, old_err).cancel();
699 }
700 None => {}
701 };
702 new_err.emit()
703 }
704
705 pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool {
706 let inner = self.inner.borrow();
707 if let Some(stashed_diagnostics) = inner.stashed_diagnostics.get(&key)
708 && !stashed_diagnostics.is_empty()
709 {
710 stashed_diagnostics.contains_key(&span.with_parent(None))
711 } else {
712 false
713 }
714 }
715
716 pub fn emit_stashed_diagnostics(&self) -> Option<ErrorGuaranteed> {
718 self.inner.borrow_mut().emit_stashed_diagnostics()
719 }
720
721 #[inline]
723 pub fn err_count(&self) -> usize {
724 let inner = self.inner.borrow();
725 inner.err_guars.len()
726 + inner.lint_err_guars.len()
727 + inner
728 .stashed_diagnostics
729 .values()
730 .map(|a| a.values().filter(|(_, guar)| guar.is_some()).count())
731 .sum::<usize>()
732 }
733
734 pub fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
737 self.inner.borrow().has_errors_excluding_lint_errors()
738 }
739
740 pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
742 self.inner.borrow().has_errors()
743 }
744
745 pub fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
748 self.inner.borrow().has_errors_or_delayed_bugs()
749 }
750
751 pub fn print_error_count(&self) {
752 let mut inner = self.inner.borrow_mut();
753
754 if !inner.stashed_diagnostics.is_empty() {
::core::panicking::panic("assertion failed: inner.stashed_diagnostics.is_empty()")
};assert!(inner.stashed_diagnostics.is_empty());
757
758 if inner.treat_err_as_bug() {
759 return;
760 }
761
762 let warnings = match inner.deduplicated_warn_count {
763 0 => Cow::from(""),
764 1 => Cow::from("1 warning emitted"),
765 count => Cow::from(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} warnings emitted", count))
})format!("{count} warnings emitted")),
766 };
767 let errors = match inner.deduplicated_err_count {
768 0 => Cow::from(""),
769 1 => Cow::from("aborting due to 1 previous error"),
770 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")),
771 };
772
773 match (errors.len(), warnings.len()) {
774 (0, 0) => return,
775 (0, _) => {
776 inner.emit_diagnostic(
779 DiagInner::new(ForceWarning, DiagMessage::Str(warnings)),
780 None,
781 );
782 }
783 (_, 0) => {
784 inner.emit_diagnostic(DiagInner::new(Error, errors), self.tainted_with_errors);
785 }
786 (_, _) => {
787 inner.emit_diagnostic(
788 DiagInner::new(Error, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}; {1}", errors, warnings))
})format!("{errors}; {warnings}")),
789 self.tainted_with_errors,
790 );
791 }
792 }
793
794 let can_show_explain = inner.emitter.should_show_explain();
795 let are_there_diagnostics = !inner.emitted_diagnostic_codes.is_empty();
796 if can_show_explain && are_there_diagnostics {
797 let mut error_codes = inner
798 .emitted_diagnostic_codes
799 .iter()
800 .filter_map(|&code| {
801 if crate::codes::try_find_description(code).is_ok() {
802 Some(code.to_string())
803 } else {
804 None
805 }
806 })
807 .collect::<Vec<_>>();
808 if !error_codes.is_empty() {
809 error_codes.sort();
810 if error_codes.len() > 1 {
811 let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
812 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!(
813 "Some errors have detailed explanations: {}{}",
814 error_codes[..limit].join(", "),
815 if error_codes.len() > 9 { "..." } else { "." }
816 );
817 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!(
818 "For more information about an error, try `rustc --explain {}`.",
819 &error_codes[0]
820 );
821 inner.emit_diagnostic(DiagInner::new(FailureNote, msg1), None);
822 inner.emit_diagnostic(DiagInner::new(FailureNote, msg2), None);
823 } else {
824 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!(
825 "For more information about this error, try `rustc --explain {}`.",
826 &error_codes[0]
827 );
828 inner.emit_diagnostic(DiagInner::new(FailureNote, msg), None);
829 }
830 }
831 }
832 }
833
834 pub fn abort_if_errors(&self) {
839 if let Some(guar) = self.has_errors() {
840 guar.raise_fatal();
841 }
842 }
843
844 pub fn must_teach(&self, code: ErrCode) -> bool {
850 self.inner.borrow_mut().taught_diagnostics.insert(code)
851 }
852
853 pub fn emit_diagnostic(&self, diagnostic: DiagInner) -> Option<ErrorGuaranteed> {
854 self.inner.borrow_mut().emit_diagnostic(diagnostic, self.tainted_with_errors)
855 }
856
857 pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
858 self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type);
859 }
860
861 pub fn emit_timing_section_start(&self, record: TimingRecord) {
862 self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::Start);
863 }
864
865 pub fn emit_timing_section_end(&self, record: TimingRecord) {
866 self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::End);
867 }
868
869 pub fn emit_future_breakage_report(&self) {
870 let inner = &mut *self.inner.borrow_mut();
871 let diags = std::mem::take(&mut inner.future_breakage_diagnostics);
872 if !diags.is_empty() {
873 inner.emitter.emit_future_breakage_report(diags);
874 }
875 }
876
877 pub fn emit_unused_externs(
878 &self,
879 lint_level: rustc_lint_defs::Level,
880 loud: bool,
881 unused_externs: &[&str],
882 ) {
883 let mut inner = self.inner.borrow_mut();
884
885 if loud && lint_level.is_error() {
896 #[allow(deprecated)]
899 inner.lint_err_guars.push(ErrorGuaranteed::unchecked_error_guaranteed());
900 inner.panic_if_treat_err_as_bug();
901 }
902
903 inner.emitter.emit_unused_externs(lint_level, unused_externs)
904 }
905
906 #[must_use]
909 pub fn steal_fulfilled_expectation_ids(&self) -> FxIndexSet<LintExpectationId> {
910 std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations)
911 }
912
913 pub fn flush_delayed(&self) {
918 self.inner.borrow_mut().flush_delayed();
919 }
920
921 #[track_caller]
924 pub fn set_must_produce_diag(&self) {
925 if !self.inner.borrow().must_produce_diag.is_none() {
{
::core::panicking::panic_fmt(format_args!("should only need to collect a backtrace once"));
}
};assert!(
926 self.inner.borrow().must_produce_diag.is_none(),
927 "should only need to collect a backtrace once"
928 );
929 self.inner.borrow_mut().must_produce_diag = Some(Backtrace::capture());
930 }
931}
932
933impl<'a> DiagCtxtHandle<'a> {
938 #[track_caller]
939 pub fn struct_bug(self, msg: impl Into<Cow<'static, str>>) -> Diag<'a, BugAbort> {
940 Diag::new(self, Bug, msg.into())
941 }
942
943 #[track_caller]
944 pub fn bug(self, msg: impl Into<Cow<'static, str>>) -> ! {
945 self.struct_bug(msg).emit()
946 }
947
948 #[track_caller]
949 pub fn struct_span_bug(
950 self,
951 span: impl Into<MultiSpan>,
952 msg: impl Into<Cow<'static, str>>,
953 ) -> Diag<'a, BugAbort> {
954 self.struct_bug(msg).with_span(span)
955 }
956
957 #[track_caller]
958 pub fn span_bug(self, span: impl Into<MultiSpan>, msg: impl Into<Cow<'static, str>>) -> ! {
959 self.struct_span_bug(span, msg.into()).emit()
960 }
961
962 #[track_caller]
963 pub fn create_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> Diag<'a, BugAbort> {
964 bug.into_diag(self, Bug)
965 }
966
967 #[track_caller]
968 pub fn emit_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> ! {
969 self.create_bug(bug).emit()
970 }
971
972 #[track_caller]
973 pub fn struct_fatal(self, msg: impl Into<DiagMessage>) -> Diag<'a, FatalAbort> {
974 Diag::new(self, Fatal, msg)
975 }
976
977 #[track_caller]
978 pub fn fatal(self, msg: impl Into<DiagMessage>) -> ! {
979 self.struct_fatal(msg).emit()
980 }
981
982 #[track_caller]
983 pub fn struct_span_fatal(
984 self,
985 span: impl Into<MultiSpan>,
986 msg: impl Into<DiagMessage>,
987 ) -> Diag<'a, FatalAbort> {
988 self.struct_fatal(msg).with_span(span)
989 }
990
991 #[track_caller]
992 pub fn span_fatal(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) -> ! {
993 self.struct_span_fatal(span, msg).emit()
994 }
995
996 #[track_caller]
997 pub fn create_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> Diag<'a, FatalAbort> {
998 fatal.into_diag(self, Fatal)
999 }
1000
1001 #[track_caller]
1002 pub fn emit_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> ! {
1003 self.create_fatal(fatal).emit()
1004 }
1005
1006 #[track_caller]
1007 pub fn create_almost_fatal(
1008 self,
1009 fatal: impl Diagnostic<'a, FatalError>,
1010 ) -> Diag<'a, FatalError> {
1011 fatal.into_diag(self, Fatal)
1012 }
1013
1014 #[track_caller]
1015 pub fn emit_almost_fatal(self, fatal: impl Diagnostic<'a, FatalError>) -> FatalError {
1016 self.create_almost_fatal(fatal).emit()
1017 }
1018
1019 #[track_caller]
1021 pub fn struct_err(self, msg: impl Into<DiagMessage>) -> Diag<'a> {
1022 Diag::new(self, Error, msg)
1023 }
1024
1025 #[track_caller]
1026 pub fn err(self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
1027 self.struct_err(msg).emit()
1028 }
1029
1030 #[track_caller]
1031 pub fn struct_span_err(
1032 self,
1033 span: impl Into<MultiSpan>,
1034 msg: impl Into<DiagMessage>,
1035 ) -> Diag<'a> {
1036 self.struct_err(msg).with_span(span)
1037 }
1038
1039 #[track_caller]
1040 pub fn span_err(
1041 self,
1042 span: impl Into<MultiSpan>,
1043 msg: impl Into<DiagMessage>,
1044 ) -> ErrorGuaranteed {
1045 self.struct_span_err(span, msg).emit()
1046 }
1047
1048 #[track_caller]
1049 pub fn create_err(self, err: impl Diagnostic<'a>) -> Diag<'a> {
1050 err.into_diag(self, Error)
1051 }
1052
1053 #[track_caller]
1054 pub fn emit_err(self, err: impl Diagnostic<'a>) -> ErrorGuaranteed {
1055 self.create_err(err).emit()
1056 }
1057
1058 #[track_caller]
1060 pub fn delayed_bug(self, msg: impl Into<Cow<'static, str>>) -> ErrorGuaranteed {
1061 Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).emit()
1062 }
1063
1064 #[track_caller]
1069 pub fn span_delayed_bug(
1070 self,
1071 sp: impl Into<MultiSpan>,
1072 msg: impl Into<Cow<'static, str>>,
1073 ) -> ErrorGuaranteed {
1074 Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).with_span(sp).emit()
1075 }
1076
1077 #[track_caller]
1078 pub fn struct_warn(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1079 Diag::new(self, Warning, msg)
1080 }
1081
1082 #[track_caller]
1083 pub fn warn(self, msg: impl Into<DiagMessage>) {
1084 self.struct_warn(msg).emit()
1085 }
1086
1087 #[track_caller]
1088 pub fn struct_span_warn(
1089 self,
1090 span: impl Into<MultiSpan>,
1091 msg: impl Into<DiagMessage>,
1092 ) -> Diag<'a, ()> {
1093 self.struct_warn(msg).with_span(span)
1094 }
1095
1096 #[track_caller]
1097 pub fn span_warn(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
1098 self.struct_span_warn(span, msg).emit()
1099 }
1100
1101 #[track_caller]
1102 pub fn create_warn(self, warning: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
1103 warning.into_diag(self, Warning)
1104 }
1105
1106 #[track_caller]
1107 pub fn emit_warn(self, warning: impl Diagnostic<'a, ()>) {
1108 self.create_warn(warning).emit()
1109 }
1110
1111 #[track_caller]
1112 pub fn struct_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1113 Diag::new(self, Note, msg)
1114 }
1115
1116 #[track_caller]
1117 pub fn note(&self, msg: impl Into<DiagMessage>) {
1118 self.struct_note(msg).emit()
1119 }
1120
1121 #[track_caller]
1122 pub fn struct_span_note(
1123 self,
1124 span: impl Into<MultiSpan>,
1125 msg: impl Into<DiagMessage>,
1126 ) -> Diag<'a, ()> {
1127 self.struct_note(msg).with_span(span)
1128 }
1129
1130 #[track_caller]
1131 pub fn span_note(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
1132 self.struct_span_note(span, msg).emit()
1133 }
1134
1135 #[track_caller]
1136 pub fn create_note(self, note: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
1137 note.into_diag(self, Note)
1138 }
1139
1140 #[track_caller]
1141 pub fn emit_note(self, note: impl Diagnostic<'a, ()>) {
1142 self.create_note(note).emit()
1143 }
1144
1145 #[track_caller]
1146 pub fn struct_help(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1147 Diag::new(self, Help, msg)
1148 }
1149
1150 #[track_caller]
1151 pub fn struct_failure_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1152 Diag::new(self, FailureNote, msg)
1153 }
1154
1155 #[track_caller]
1156 pub fn struct_allow(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
1157 Diag::new(self, Allow, msg)
1158 }
1159
1160 #[track_caller]
1161 pub fn struct_expect(self, msg: impl Into<DiagMessage>, id: LintExpectationId) -> Diag<'a, ()> {
1162 Diag::new(self, Expect, msg).with_lint_id(id)
1163 }
1164}
1165
1166impl DiagCtxtInner {
1171 fn new(emitter: Box<DynEmitter>) -> Self {
1172 Self {
1173 flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
1174 err_guars: Vec::new(),
1175 lint_err_guars: Vec::new(),
1176 delayed_bugs: Vec::new(),
1177 deduplicated_err_count: 0,
1178 deduplicated_warn_count: 0,
1179 emitter,
1180 must_produce_diag: None,
1181 has_printed: false,
1182 suppressed_expected_diag: false,
1183 taught_diagnostics: Default::default(),
1184 emitted_diagnostic_codes: Default::default(),
1185 emitted_diagnostics: Default::default(),
1186 stashed_diagnostics: Default::default(),
1187 future_breakage_diagnostics: Vec::new(),
1188 fulfilled_expectations: Default::default(),
1189 ice_file: None,
1190 }
1191 }
1192
1193 fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
1195 let mut guar = None;
1196 let has_errors = !self.err_guars.is_empty();
1197 for (_, stashed_diagnostics) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
1198 for (_, (diag, _guar)) in stashed_diagnostics {
1199 if !diag.is_error() {
1200 if !diag.is_force_warn() && has_errors {
1204 continue;
1205 }
1206 }
1207 guar = guar.or(self.emit_diagnostic(diag, None));
1208 }
1209 }
1210 guar
1211 }
1212
1213 fn emit_diagnostic(
1215 &mut self,
1216 mut diagnostic: DiagInner,
1217 taint: Option<&Cell<Option<ErrorGuaranteed>>>,
1218 ) -> Option<ErrorGuaranteed> {
1219 if diagnostic.has_future_breakage() {
1220 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);
1224 self.future_breakage_diagnostics.push(diagnostic.clone());
1225 }
1226
1227 match diagnostic.level {
1231 Bug => {}
1232 Fatal | Error => {
1233 if self.treat_next_err_as_bug() {
1234 diagnostic.level = Bug;
1236 }
1237 }
1238 DelayedBug => {
1239 if self.flags.eagerly_emit_delayed_bugs {
1244 if self.treat_next_err_as_bug() {
1246 diagnostic.level = Bug;
1247 } else {
1248 diagnostic.level = Error;
1249 }
1250 } else {
1251 return if let Some(guar) = self.has_errors() {
1254 Some(guar)
1255 } else {
1256 let backtrace = std::backtrace::Backtrace::capture();
1260 #[allow(deprecated)]
1264 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
1265 self.delayed_bugs
1266 .push((DelayedDiagInner::with_backtrace(diagnostic, backtrace), guar));
1267 Some(guar)
1268 };
1269 }
1270 }
1271 ForceWarning if diagnostic.lint_id.is_none() => {} Warning => {
1273 if !self.flags.can_emit_warnings {
1274 if diagnostic.has_future_breakage() {
1276 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1278 }
1279 return None;
1280 }
1281 }
1282 Note | Help | FailureNote => {}
1283 OnceNote | OnceHelp => {
::core::panicking::panic_fmt(format_args!("bad level: {0:?}",
diagnostic.level));
}panic!("bad level: {:?}", diagnostic.level),
1284 Allow => {
1285 if diagnostic.has_future_breakage() {
1287 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1289 self.suppressed_expected_diag = true;
1290 }
1291 return None;
1292 }
1293 Expect | ForceWarning => {
1294 self.fulfilled_expectations.insert(diagnostic.lint_id.unwrap());
1295 if let Expect = diagnostic.level {
1296 TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
1298 self.suppressed_expected_diag = true;
1299 return None;
1300 }
1301 }
1302 }
1303
1304 TRACK_DIAGNOSTIC(diagnostic, &mut |mut diagnostic| {
1305 if let Some(code) = diagnostic.code {
1306 self.emitted_diagnostic_codes.insert(code);
1307 }
1308
1309 let already_emitted = {
1310 let mut hasher = StableHasher::new();
1311 diagnostic.hash(&mut hasher);
1312 let diagnostic_hash = hasher.finish();
1313 !self.emitted_diagnostics.insert(diagnostic_hash)
1314 };
1315
1316 let is_error = diagnostic.is_error();
1317 let is_lint = diagnostic.is_lint.is_some();
1318
1319 if !(self.flags.deduplicate_diagnostics && already_emitted) {
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(&["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);
1323 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_errors/src/lib.rs:1323",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1323u32),
::tracing_core::__macro_support::Option::Some("rustc_errors"),
::tracing_core::field::FieldSet::new(&["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);
1324
1325 let not_yet_emitted = |sub: &mut Subdiag| {
1326 {
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:1326",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1326u32),
::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);
1327 if sub.level != OnceNote && sub.level != OnceHelp {
1328 return true;
1329 }
1330 let mut hasher = StableHasher::new();
1331 sub.hash(&mut hasher);
1332 let diagnostic_hash = hasher.finish();
1333 {
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:1333",
"rustc_errors", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1333u32),
::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);
1334 self.emitted_diagnostics.insert(diagnostic_hash)
1335 };
1336 diagnostic.children.retain_mut(not_yet_emitted);
1337 if already_emitted {
1338 let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`";
1339 diagnostic.sub(Note, msg, MultiSpan::new());
1340 }
1341
1342 if is_error {
1343 self.deduplicated_err_count += 1;
1344 } else if #[allow(non_exhaustive_omitted_patterns)] match diagnostic.level {
ForceWarning | Warning => true,
_ => false,
}matches!(diagnostic.level, ForceWarning | Warning) {
1345 self.deduplicated_warn_count += 1;
1346 }
1347 self.has_printed = true;
1348
1349 self.emitter.emit_diagnostic(diagnostic);
1350 }
1351
1352 if is_error {
1353 if !self.delayed_bugs.is_empty() {
1358 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);
1359 self.delayed_bugs.clear();
1360 self.delayed_bugs.shrink_to_fit();
1361 }
1362
1363 #[allow(deprecated)]
1366 let guar = ErrorGuaranteed::unchecked_error_guaranteed();
1367 if is_lint {
1368 self.lint_err_guars.push(guar);
1369 } else {
1370 if let Some(taint) = taint {
1371 taint.set(Some(guar));
1372 }
1373 self.err_guars.push(guar);
1374 }
1375 self.panic_if_treat_err_as_bug();
1376 Some(guar)
1377 } else {
1378 None
1379 }
1380 })
1381 }
1382
1383 fn treat_err_as_bug(&self) -> bool {
1384 self.flags
1385 .treat_err_as_bug
1386 .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() >= c.get())
1387 }
1388
1389 fn treat_next_err_as_bug(&self) -> bool {
1391 self.flags
1392 .treat_err_as_bug
1393 .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() + 1 >= c.get())
1394 }
1395
1396 fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
1397 self.err_guars.get(0).copied().or_else(|| {
1398 if let Some((_diag, guar)) = self
1399 .stashed_diagnostics
1400 .values()
1401 .flat_map(|stashed_diagnostics| stashed_diagnostics.values())
1402 .find(|(diag, guar)| guar.is_some() && diag.is_lint.is_none())
1403 {
1404 *guar
1405 } else {
1406 None
1407 }
1408 })
1409 }
1410
1411 fn has_errors(&self) -> Option<ErrorGuaranteed> {
1412 self.err_guars.get(0).copied().or_else(|| self.lint_err_guars.get(0).copied()).or_else(
1413 || {
1414 self.stashed_diagnostics.values().find_map(|stashed_diagnostics| {
1415 stashed_diagnostics.values().find_map(|(_, guar)| *guar)
1416 })
1417 },
1418 )
1419 }
1420
1421 fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
1422 self.has_errors().or_else(|| self.delayed_bugs.get(0).map(|(_, guar)| guar).copied())
1423 }
1424
1425 fn eagerly_translate<'a>(
1427 &self,
1428 message: DiagMessage,
1429 args: impl Iterator<Item = DiagArg<'a>>,
1430 ) -> DiagMessage {
1431 DiagMessage::Str(Cow::from(self.eagerly_translate_to_string(message, args)))
1432 }
1433
1434 fn eagerly_translate_to_string<'a>(
1436 &self,
1437 message: DiagMessage,
1438 args: impl Iterator<Item = DiagArg<'a>>,
1439 ) -> String {
1440 let args = crate::translation::to_fluent_args(args);
1441 self.emitter
1442 .translator()
1443 .translate_message(&message, &args)
1444 .map_err(Report::new)
1445 .unwrap()
1446 .to_string()
1447 }
1448
1449 fn eagerly_translate_for_subdiag(
1450 &self,
1451 diag: &DiagInner,
1452 msg: impl Into<DiagMessage>,
1453 ) -> DiagMessage {
1454 self.eagerly_translate(msg.into(), diag.args.iter())
1455 }
1456
1457 fn flush_delayed(&mut self) {
1458 if !self.stashed_diagnostics.is_empty() {
::core::panicking::panic("assertion failed: self.stashed_diagnostics.is_empty()")
};assert!(self.stashed_diagnostics.is_empty());
1462
1463 if !self.err_guars.is_empty() {
1464 return;
1466 }
1467
1468 if self.delayed_bugs.is_empty() {
1469 return;
1471 }
1472
1473 let bugs: Vec<_> =
1474 std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect();
1475
1476 let backtrace = std::env::var_os("RUST_BACKTRACE").as_deref() != Some(OsStr::new("0"));
1477 let decorate = backtrace || self.ice_file.is_none();
1478 let mut out = self
1479 .ice_file
1480 .as_ref()
1481 .and_then(|file| std::fs::File::options().create(true).append(true).open(file).ok());
1482
1483 let note1 = "no errors encountered even though delayed bugs were created";
1488 let note2 = "those delayed bugs will now be shown as internal compiler errors";
1489 self.emit_diagnostic(DiagInner::new(Note, note1), None);
1490 self.emit_diagnostic(DiagInner::new(Note, note2), None);
1491
1492 for bug in bugs {
1493 if let Some(out) = &mut out {
1494 _ = 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!(
1495 out,
1496 "delayed bug: {}\n{}\n",
1497 bug.inner
1498 .messages
1499 .iter()
1500 .filter_map(|(msg, _)| msg.as_str())
1501 .collect::<String>(),
1502 &bug.note
1503 );
1504 }
1505
1506 let mut bug = if decorate { bug.decorate(self) } else { bug.inner };
1507
1508 if bug.level != DelayedBug {
1510 bug.arg("level", bug.level);
1517 let msg = rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"))msg!(
1518 "`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"
1519 );
1520 let msg = self.eagerly_translate_for_subdiag(&bug, msg); bug.sub(Note, msg, bug.span.primary_span().unwrap().into());
1522 }
1523 bug.level = Bug;
1524
1525 self.emit_diagnostic(bug, None);
1526 }
1527
1528 panic::panic_any(DelayedBugPanic);
1530 }
1531
1532 fn panic_if_treat_err_as_bug(&self) {
1533 if self.treat_err_as_bug() {
1534 let n = self.flags.treat_err_as_bug.map(|c| c.get()).unwrap();
1535 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());
1536 if n == 1 {
1537 {
::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`");
1538 } else {
1539 {
::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}`");
1540 }
1541 }
1542 }
1543}
1544
1545struct DelayedDiagInner {
1546 inner: DiagInner,
1547 note: Backtrace,
1548}
1549
1550impl DelayedDiagInner {
1551 fn with_backtrace(diagnostic: DiagInner, backtrace: Backtrace) -> Self {
1552 DelayedDiagInner { inner: diagnostic, note: backtrace }
1553 }
1554
1555 fn decorate(self, dcx: &DiagCtxtInner) -> DiagInner {
1556 let mut diag = self.inner;
1560 let msg = match self.note.status() {
1561 BacktraceStatus::Captured => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("delayed at {$emitted_at}\n {$note}"))msg!(
1562 "delayed at {$emitted_at}
1563 {$note}"
1564 ),
1565 _ => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("delayed at {$emitted_at} - {$note}"))msg!("delayed at {$emitted_at} - {$note}"),
1568 };
1569 diag.arg("emitted_at", diag.emitted_at.clone());
1570 diag.arg("note", self.note);
1571 let msg = dcx.eagerly_translate_for_subdiag(&diag, msg); diag.sub(Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into());
1573 diag
1574 }
1575}
1576
1577#[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_receiver_is_total_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)]
1597pub enum Level {
1598 Bug,
1600
1601 Fatal,
1604
1605 Error,
1608
1609 DelayedBug,
1614
1615 ForceWarning,
1621
1622 Warning,
1625
1626 Note,
1628
1629 OnceNote,
1631
1632 Help,
1634
1635 OnceHelp,
1637
1638 FailureNote,
1641
1642 Allow,
1644
1645 Expect,
1647}
1648
1649impl fmt::Display for Level {
1650 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1651 self.to_str().fmt(f)
1652 }
1653}
1654
1655impl Level {
1656 fn color(self) -> anstyle::Style {
1657 match self {
1658 Bug | Fatal | Error | DelayedBug => AnsiColor::BrightRed.on_default(),
1659 ForceWarning | Warning => {
1660 if falsecfg!(windows) {
1661 AnsiColor::BrightYellow.on_default()
1662 } else {
1663 AnsiColor::Yellow.on_default()
1664 }
1665 }
1666 Note | OnceNote => AnsiColor::BrightGreen.on_default(),
1667 Help | OnceHelp => AnsiColor::BrightCyan.on_default(),
1668 FailureNote => anstyle::Style::new(),
1669 Allow | Expect => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1670 }
1671 }
1672
1673 pub fn to_str(self) -> &'static str {
1674 match self {
1675 Bug | DelayedBug => "error: internal compiler error",
1676 Fatal | Error => "error",
1677 ForceWarning | Warning => "warning",
1678 Note | OnceNote => "note",
1679 Help | OnceHelp => "help",
1680 FailureNote => "failure-note",
1681 Allow | Expect => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1682 }
1683 }
1684
1685 pub fn is_failure_note(&self) -> bool {
1686 #[allow(non_exhaustive_omitted_patterns)] match *self {
FailureNote => true,
_ => false,
}matches!(*self, FailureNote)
1687 }
1688}
1689
1690impl IntoDiagArg for Level {
1691 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
1692 DiagArgValue::Str(Cow::from(self.to_string()))
1693 }
1694}
1695
1696#[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_receiver_is_total_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)]
1697pub enum Style {
1698 MainHeaderMsg,
1699 HeaderMsg,
1700 LineAndColumn,
1701 LineNumber,
1702 Quotation,
1703 UnderlinePrimary,
1704 UnderlineSecondary,
1705 LabelPrimary,
1706 LabelSecondary,
1707 NoStyle,
1708 Level(Level),
1709 Highlight,
1710 Addition,
1711 Removal,
1712}
1713
1714pub fn elided_lifetime_in_path_suggestion(
1716 source_map: &SourceMap,
1717 n: usize,
1718 path_span: Span,
1719 incl_angl_brckt: bool,
1720 insertion_span: Span,
1721) -> ElidedLifetimeInPathSubdiag {
1722 let expected = ExpectedLifetimeParameter { span: path_span, count: n };
1723 let indicate = source_map.is_span_accessible(insertion_span).then(|| {
1725 let anon_lts = ::alloc::vec::from_elem("'_", n)vec!["'_"; n].join(", ");
1726 let suggestion =
1727 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}, ") };
1728
1729 IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion }
1730 });
1731
1732 ElidedLifetimeInPathSubdiag { expected, indicate }
1733}
1734
1735pub fn a_or_an(s: &str) -> &'static str {
1739 let mut chars = s.chars();
1740 let Some(mut first_alpha_char) = chars.next() else {
1741 return "a";
1742 };
1743 if first_alpha_char == '`' {
1744 let Some(next) = chars.next() else {
1745 return "a";
1746 };
1747 first_alpha_char = next;
1748 }
1749 if ["a", "e", "i", "o", "u", "&"].contains(&&first_alpha_char.to_lowercase().to_string()[..]) {
1750 "an"
1751 } else {
1752 "a"
1753 }
1754}
1755
1756#[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)]
1757pub enum TerminalUrl {
1758 No,
1759 Yes,
1760 Auto,
1761}