Skip to main content

rustc_errors/
diagnostic.rs

1use std::borrow::Cow;
2use std::fmt::{self, Debug};
3use std::hash::{Hash, Hasher};
4use std::marker::PhantomData;
5use std::ops::{Deref, DerefMut};
6use std::panic;
7use std::path::PathBuf;
8use std::thread::panicking;
9
10use rustc_ast::attr::version::RustcVersion;
11use rustc_data_structures::sync::{DynSend, DynSync};
12use rustc_error_messages::{DiagArgMap, DiagArgName, DiagArgValue, IntoDiagArg};
13use rustc_lint_defs::{Applicability, LintExpectationId};
14use rustc_macros::{Decodable, Encodable};
15use rustc_span::{DUMMY_SP, Span, Spanned, Symbol};
16use tracing::debug;
17
18use crate::{
19    CodeSuggestion, DiagCtxtHandle, DiagMessage, ErrCode, ErrorGuaranteed, ExplicitBug, Level,
20    MultiSpan, StashKey, Style, Substitution, SubstitutionPart, SuggestionStyle, Suggestions,
21};
22
23/// Trait for types that `Diag::emit` can return as a "guarantee" (or "proof")
24/// token that the emission happened.
25pub trait EmissionGuarantee: Sized {
26    /// This exists so that bugs and fatal errors can both result in `!` (an
27    /// abort) when emitted, but have different aborting behaviour.
28    type EmitResult = Self;
29
30    /// Implementation of `Diag::emit`, fully controlled by each `impl` of
31    /// `EmissionGuarantee`, to make it impossible to create a value of
32    /// `Self::EmitResult` without actually performing the emission.
33    #[track_caller]
34    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult;
35}
36
37impl EmissionGuarantee for ErrorGuaranteed {
38    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult {
39        diag.emit_producing_error_guaranteed()
40    }
41}
42
43impl EmissionGuarantee for () {
44    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult {
45        diag.emit_producing_nothing();
46    }
47}
48
49/// Marker type which enables implementation of `create_bug` and `emit_bug` functions for
50/// bug diagnostics.
51#[derive(#[automatically_derived]
impl ::core::marker::Copy for BugAbort { }Copy, #[automatically_derived]
impl ::core::clone::Clone for BugAbort {
    #[inline]
    fn clone(&self) -> BugAbort { *self }
}Clone)]
52pub struct BugAbort;
53
54impl EmissionGuarantee for BugAbort {
55    type EmitResult = !;
56
57    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult {
58        diag.emit_producing_nothing();
59        panic::panic_any(ExplicitBug);
60    }
61}
62
63/// Marker type which enables implementation of `create_fatal` and `emit_fatal` functions for
64/// fatal diagnostics.
65#[derive(#[automatically_derived]
impl ::core::marker::Copy for FatalAbort { }Copy, #[automatically_derived]
impl ::core::clone::Clone for FatalAbort {
    #[inline]
    fn clone(&self) -> FatalAbort { *self }
}Clone)]
66pub struct FatalAbort;
67
68impl EmissionGuarantee for FatalAbort {
69    type EmitResult = !;
70
71    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult {
72        diag.emit_producing_nothing();
73        crate::FatalError.raise()
74    }
75}
76
77impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
78    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult {
79        diag.emit_producing_nothing();
80        rustc_span::fatal_error::FatalError
81    }
82}
83
84/// Trait implemented by error types. This is rarely implemented manually. Instead, use
85/// `#[derive(Diagnostic)]` -- see [rustc_macros::Diagnostic].
86///
87/// When implemented manually, it should be generic over the emission
88/// guarantee, i.e.:
89/// ```ignore (fragment)
90/// impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for Foo { ... }
91/// ```
92/// rather than being specific:
93/// ```ignore (fragment)
94/// impl<'a> Diagnostic<'a> for Bar { ... }  // the default type param is `ErrorGuaranteed`
95/// impl<'a> Diagnostic<'a, ()> for Baz { ... }
96/// ```
97/// There are two reasons for this.
98/// - A diagnostic like `Foo` *could* be emitted at any level -- `level` is
99///   passed in to `into_diag` from outside. Even if in practice it is
100///   always emitted at a single level, we let the diagnostic creation/emission
101///   site determine the level (by using `create_err`, `emit_warn`, etc.)
102///   rather than the `Diagnostic` impl.
103/// - Derived impls are always generic, and it's good for the hand-written
104///   impls to be consistent with them.
105#[rustc_diagnostic_item = "Diagnostic"]
106pub trait Diagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> {
107    /// Write out as a diagnostic out of `DiagCtxt`.
108    #[must_use]
109    #[track_caller]
110    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G>;
111}
112
113impl<'a, T, G> Diagnostic<'a, G> for Spanned<T>
114where
115    T: Diagnostic<'a, G>,
116    G: EmissionGuarantee,
117{
118    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
119        self.node.into_diag(dcx, level).with_span(self.span)
120    }
121}
122
123impl<'a> Diagnostic<'a, ()>
124    for Box<
125        dyn for<'b> FnOnce(DiagCtxtHandle<'b>, Level) -> Diag<'b, ()> + DynSync + DynSend + 'static,
126    >
127{
128    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
129        self(dcx, level)
130    }
131}
132
133/// Type used to emit diagnostic through a closure instead of implementing the `Diagnostic` trait.
134pub struct DiagDecorator<F: FnOnce(&mut Diag<'_, ()>)>(pub F);
135
136impl<'a, F: FnOnce(&mut Diag<'_, ()>)> Diagnostic<'a, ()> for DiagDecorator<F> {
137    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
138        let mut diag = Diag::new(dcx, level, "");
139        (self.0)(&mut diag);
140        diag
141    }
142}
143
144/// Trait implemented by error types. This should not be implemented manually. Instead, use
145/// `#[derive(Subdiagnostic)]` -- see [rustc_macros::Subdiagnostic].
146#[rustc_diagnostic_item = "Subdiagnostic"]
147pub trait Subdiagnostic {
148    /// Add a subdiagnostic to an existing diagnostic.
149    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>);
150}
151
152#[derive(#[automatically_derived]
impl ::core::clone::Clone for DiagLocation {
    #[inline]
    fn clone(&self) -> DiagLocation {
        DiagLocation {
            file: ::core::clone::Clone::clone(&self.file),
            line: ::core::clone::Clone::clone(&self.line),
            col: ::core::clone::Clone::clone(&self.col),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for DiagLocation {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "DiagLocation",
            "file", &self.file, "line", &self.line, "col", &&self.col)
    }
}Debug, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for DiagLocation {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    DiagLocation {
                        file: ref __binding_0,
                        line: ref __binding_1,
                        col: 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 DiagLocation {
            fn decode(__decoder: &mut __D) -> Self {
                DiagLocation {
                    file: ::rustc_serialize::Decodable::decode(__decoder),
                    line: ::rustc_serialize::Decodable::decode(__decoder),
                    col: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable)]
153pub struct DiagLocation {
154    file: Cow<'static, str>,
155    line: u32,
156    col: u32,
157}
158
159impl DiagLocation {
160    #[track_caller]
161    pub fn caller() -> Self {
162        let loc = panic::Location::caller();
163        DiagLocation { file: loc.file().into(), line: loc.line(), col: loc.column() }
164    }
165}
166
167impl fmt::Display for DiagLocation {
168    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169        f.write_fmt(format_args!("{0}:{1}:{2}", self.file, self.line, self.col))write!(f, "{}:{}:{}", self.file, self.line, self.col)
170    }
171}
172
173#[derive(#[automatically_derived]
impl ::core::clone::Clone for IsLint {
    #[inline]
    fn clone(&self) -> IsLint {
        IsLint {
            name: ::core::clone::Clone::clone(&self.name),
            has_future_breakage: ::core::clone::Clone::clone(&self.has_future_breakage),
            rust_version: ::core::clone::Clone::clone(&self.rust_version),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for IsLint {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "IsLint",
            "name", &self.name, "has_future_breakage",
            &self.has_future_breakage, "rust_version", &&self.rust_version)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for IsLint {
    #[inline]
    fn eq(&self, other: &IsLint) -> bool {
        self.has_future_breakage == other.has_future_breakage &&
                self.name == other.name &&
            self.rust_version == other.rust_version
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for IsLint {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<String>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
        let _: ::core::cmp::AssertParamIsEq<Option<RustcVersion>>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for IsLint {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.name, state);
        ::core::hash::Hash::hash(&self.has_future_breakage, state);
        ::core::hash::Hash::hash(&self.rust_version, state)
    }
}Hash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for IsLint {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    IsLint {
                        name: ref __binding_0,
                        has_future_breakage: ref __binding_1,
                        rust_version: 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 IsLint {
            fn decode(__decoder: &mut __D) -> Self {
                IsLint {
                    name: ::rustc_serialize::Decodable::decode(__decoder),
                    has_future_breakage: ::rustc_serialize::Decodable::decode(__decoder),
                    rust_version: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable)]
174pub struct IsLint {
175    /// The lint name.
176    pub(crate) name: String,
177    /// Indicates whether this lint should show up in cargo's future breakage report.
178    has_future_breakage: bool,
179    /// Indicates the minimum rust version this lint applies to
180    rust_version: Option<RustcVersion>,
181}
182
183#[derive(#[automatically_derived]
impl ::core::fmt::Debug for DiagStyledString {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "DiagStyledString", &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for DiagStyledString {
    #[inline]
    fn eq(&self, other: &DiagStyledString) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for DiagStyledString {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Vec<StringPart>>;
    }
}Eq)]
184pub struct DiagStyledString(pub Vec<StringPart>);
185
186impl DiagStyledString {
187    pub fn new() -> DiagStyledString {
188        DiagStyledString(::alloc::vec::Vec::new()vec![])
189    }
190    pub fn push_normal<S: Into<String>>(&mut self, t: S) {
191        self.0.push(StringPart::normal(t));
192    }
193    pub fn push_highlighted<S: Into<String>>(&mut self, t: S) {
194        self.0.push(StringPart::highlighted(t));
195    }
196    pub fn push<S: Into<String>>(&mut self, t: S, highlight: bool) {
197        if highlight {
198            self.push_highlighted(t);
199        } else {
200            self.push_normal(t);
201        }
202    }
203    pub fn normal<S: Into<String>>(t: S) -> DiagStyledString {
204        DiagStyledString(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [StringPart::normal(t)]))vec![StringPart::normal(t)])
205    }
206
207    pub fn highlighted<S: Into<String>>(t: S) -> DiagStyledString {
208        DiagStyledString(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [StringPart::highlighted(t)]))vec![StringPart::highlighted(t)])
209    }
210
211    pub fn content(&self) -> String {
212        self.0.iter().map(|x| x.content.as_str()).collect::<String>()
213    }
214
215    /// Merge segments of the same style.
216    pub fn compact(&mut self) {
217        let segments = std::mem::take(&mut self.0);
218        let mut iter = segments.into_iter();
219        let Some(mut prev) = iter.next() else { return };
220        while let Some(segment) = iter.next() {
221            if prev.style == segment.style {
222                prev.content.push_str(&segment.content);
223            } else {
224                self.0.push(prev);
225                prev = segment;
226            }
227        }
228        self.0.push(prev);
229    }
230
231    /// Remove the middle of all long segments for shorter rendering.
232    pub fn shorten(&mut self) {
233        self.compact();
234        /// The marker for removed text.
235        const ELLIPSIS: &str = "...";
236        /// How many chars at the start and end will remain.
237        const PADDING: usize = 6;
238        /// The distance after which it is not worth it to reduce the text.
239        const DELTA: usize = 3;
240
241        for segment in self.0.iter_mut() {
242            let char_len = segment.content.chars().count();
243            if char_len > PADDING * 2 + ELLIPSIS.chars().count() + DELTA
244                && let Some((left, _)) = segment.content.char_indices().nth(PADDING)
245                && let Some((right, _)) = segment.content.char_indices().nth(char_len - PADDING)
246            {
247                segment.content.replace_range(left..right, ELLIPSIS);
248            }
249        }
250    }
251}
252
253#[derive(#[automatically_derived]
impl ::core::fmt::Debug for StringPart {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "StringPart",
            "content", &self.content, "style", &&self.style)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for StringPart {
    #[inline]
    fn eq(&self, other: &StringPart) -> bool {
        self.content == other.content && self.style == other.style
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for StringPart {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<String>;
        let _: ::core::cmp::AssertParamIsEq<Style>;
    }
}Eq)]
254pub struct StringPart {
255    content: String,
256    style: Style,
257}
258
259impl StringPart {
260    pub fn normal<S: Into<String>>(content: S) -> StringPart {
261        StringPart { content: content.into(), style: Style::NoStyle }
262    }
263
264    pub fn highlighted<S: Into<String>>(content: S) -> StringPart {
265        StringPart { content: content.into(), style: Style::Highlight }
266    }
267}
268
269/// The main part of a diagnostic. Note that `Diag`, which wraps this type, is
270/// used for most operations, and should be used instead whenever possible.
271/// This type should only be used when `Diag`'s lifetime causes difficulties,
272/// e.g. when storing diagnostics within `DiagCtxt`.
273#[must_use]
274#[derive(#[automatically_derived]
impl ::core::clone::Clone for DiagInner {
    #[inline]
    fn clone(&self) -> DiagInner {
        DiagInner {
            level: ::core::clone::Clone::clone(&self.level),
            messages: ::core::clone::Clone::clone(&self.messages),
            code: ::core::clone::Clone::clone(&self.code),
            lint_id: ::core::clone::Clone::clone(&self.lint_id),
            span: ::core::clone::Clone::clone(&self.span),
            children: ::core::clone::Clone::clone(&self.children),
            suggestions: ::core::clone::Clone::clone(&self.suggestions),
            args: ::core::clone::Clone::clone(&self.args),
            sort_span: ::core::clone::Clone::clone(&self.sort_span),
            is_lint: ::core::clone::Clone::clone(&self.is_lint),
            long_ty_path: ::core::clone::Clone::clone(&self.long_ty_path),
            emitted_at: ::core::clone::Clone::clone(&self.emitted_at),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for DiagInner {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["level", "messages", "code", "lint_id", "span", "children",
                        "suggestions", "args", "sort_span", "is_lint",
                        "long_ty_path", "emitted_at"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.level, &self.messages, &self.code, &self.lint_id,
                        &self.span, &self.children, &self.suggestions, &self.args,
                        &self.sort_span, &self.is_lint, &self.long_ty_path,
                        &&self.emitted_at];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "DiagInner",
            names, values)
    }
}Debug, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for DiagInner {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    DiagInner {
                        level: ref __binding_0,
                        messages: ref __binding_1,
                        code: ref __binding_2,
                        lint_id: ref __binding_3,
                        span: ref __binding_4,
                        children: ref __binding_5,
                        suggestions: ref __binding_6,
                        args: ref __binding_7,
                        sort_span: ref __binding_8,
                        is_lint: ref __binding_9,
                        long_ty_path: ref __binding_10,
                        emitted_at: ref __binding_11 } => {
                        ::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);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_4,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_5,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_6,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_7,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_8,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_9,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_10,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_11,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for DiagInner {
            fn decode(__decoder: &mut __D) -> Self {
                DiagInner {
                    level: ::rustc_serialize::Decodable::decode(__decoder),
                    messages: ::rustc_serialize::Decodable::decode(__decoder),
                    code: ::rustc_serialize::Decodable::decode(__decoder),
                    lint_id: ::rustc_serialize::Decodable::decode(__decoder),
                    span: ::rustc_serialize::Decodable::decode(__decoder),
                    children: ::rustc_serialize::Decodable::decode(__decoder),
                    suggestions: ::rustc_serialize::Decodable::decode(__decoder),
                    args: ::rustc_serialize::Decodable::decode(__decoder),
                    sort_span: ::rustc_serialize::Decodable::decode(__decoder),
                    is_lint: ::rustc_serialize::Decodable::decode(__decoder),
                    long_ty_path: ::rustc_serialize::Decodable::decode(__decoder),
                    emitted_at: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable)]
275pub struct DiagInner {
276    // NOTE(eddyb) this is private to disallow arbitrary after-the-fact changes,
277    // outside of what methods in this crate themselves allow.
278    pub(crate) level: Level,
279
280    pub messages: Vec<(DiagMessage, Style)>,
281    pub code: Option<ErrCode>,
282    pub lint_id: Option<LintExpectationId>,
283    pub span: MultiSpan,
284    pub children: Vec<Subdiag>,
285    pub suggestions: Suggestions,
286    pub args: DiagArgMap,
287
288    /// This is not used for highlighting or rendering any error message. Rather, it can be used
289    /// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
290    /// `span` if there is one. Otherwise, it is `DUMMY_SP`.
291    pub sort_span: Span,
292
293    pub is_lint: Option<IsLint>,
294
295    pub long_ty_path: Option<PathBuf>,
296    /// With `-Ztrack_diagnostics` enabled,
297    /// we print where in rustc this error was emitted.
298    pub emitted_at: DiagLocation,
299}
300
301impl DiagInner {
302    #[track_caller]
303    pub fn new<M: Into<DiagMessage>>(level: Level, message: M) -> Self {
304        DiagInner::new_with_messages(level, ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(message.into(), Style::NoStyle)]))vec![(message.into(), Style::NoStyle)])
305    }
306
307    #[track_caller]
308    pub fn new_with_messages(level: Level, messages: Vec<(DiagMessage, Style)>) -> Self {
309        DiagInner {
310            level,
311            lint_id: None,
312            messages,
313            code: None,
314            span: MultiSpan::new(),
315            children: ::alloc::vec::Vec::new()vec![],
316            suggestions: Suggestions::Enabled(::alloc::vec::Vec::new()vec![]),
317            args: Default::default(),
318            sort_span: DUMMY_SP,
319            is_lint: None,
320            long_ty_path: None,
321            emitted_at: DiagLocation::caller(),
322        }
323    }
324
325    #[inline(always)]
326    pub fn level(&self) -> Level {
327        self.level
328    }
329
330    pub fn is_error(&self) -> bool {
331        match self.level {
332            Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => true,
333
334            Level::ForceWarning
335            | Level::Warning
336            | Level::Note
337            | Level::OnceNote
338            | Level::Help
339            | Level::OnceHelp
340            | Level::FailureNote
341            | Level::Allow
342            | Level::Expect => false,
343        }
344    }
345
346    /// Indicates whether this diagnostic should show up in cargo's future breakage report.
347    pub(crate) fn has_future_breakage(&self) -> bool {
348        #[allow(non_exhaustive_omitted_patterns)] match self.is_lint {
    Some(IsLint { has_future_breakage: true, .. }) => true,
    _ => false,
}matches!(self.is_lint, Some(IsLint { has_future_breakage: true, .. }))
349    }
350
351    /// Indicates the minimum rust version this lint applies to.
352    pub(crate) fn rust_version(&self) -> Option<RustcVersion> {
353        self.is_lint.as_ref().and_then(|is| is.rust_version)
354    }
355
356    pub(crate) fn is_force_warn(&self) -> bool {
357        match self.level {
358            Level::ForceWarning => {
359                if !self.is_lint.is_some() {
    ::core::panicking::panic("assertion failed: self.is_lint.is_some()")
};assert!(self.is_lint.is_some());
360                true
361            }
362            _ => false,
363        }
364    }
365
366    pub(crate) fn sub(&mut self, level: Level, message: impl Into<DiagMessage>, span: MultiSpan) {
367        let sub = Subdiag { level, messages: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(message.into(), Style::NoStyle)]))vec![(message.into(), Style::NoStyle)], span };
368        self.children.push(sub);
369    }
370
371    pub(crate) fn arg(&mut self, name: impl Into<DiagArgName>, arg: impl IntoDiagArg) {
372        let name = name.into();
373        let value = arg.into_diag_arg(&mut self.long_ty_path);
374        // This assertion is to avoid subdiagnostics overwriting an existing diagnostic arg.
375        if true {
    if !(!self.args.contains_key(&name) ||
                self.args.get(&name) == Some(&value)) {
        {
            ::core::panicking::panic_fmt(format_args!("arg {0} already exists",
                    name));
        }
    };
};debug_assert!(
376            !self.args.contains_key(&name) || self.args.get(&name) == Some(&value),
377            "arg {} already exists",
378            name
379        );
380        self.args.insert(name, value);
381    }
382
383    pub fn remove_arg(&mut self, name: &str) {
384        self.args.swap_remove(name);
385    }
386
387    pub fn emitted_at_sub_diag(&self) -> Subdiag {
388        let track = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("-Ztrack-diagnostics: created at {0}",
                self.emitted_at))
    })format!("-Ztrack-diagnostics: created at {}", self.emitted_at);
389        Subdiag {
390            level: crate::Level::Note,
391            messages: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(DiagMessage::Str(Cow::Owned(track)), Style::NoStyle)]))vec![(DiagMessage::Str(Cow::Owned(track)), Style::NoStyle)],
392            span: MultiSpan::new(),
393        }
394    }
395
396    /// Fields used for Hash, and PartialEq trait.
397    fn keys(
398        &self,
399    ) -> (
400        &Level,
401        &[(DiagMessage, Style)],
402        &Option<ErrCode>,
403        &MultiSpan,
404        &[Subdiag],
405        &Suggestions,
406        Vec<(&DiagArgName, &DiagArgValue)>,
407        &Option<IsLint>,
408    ) {
409        (
410            &self.level,
411            &self.messages,
412            &self.code,
413            &self.span,
414            &self.children,
415            &self.suggestions,
416            self.args.iter().collect(),
417            // omit self.sort_span
418            &self.is_lint,
419            // omit self.emitted_at
420        )
421    }
422}
423
424impl Hash for DiagInner {
425    fn hash<H>(&self, state: &mut H)
426    where
427        H: Hasher,
428    {
429        self.keys().hash(state);
430    }
431}
432
433impl PartialEq for DiagInner {
434    fn eq(&self, other: &Self) -> bool {
435        self.keys() == other.keys()
436    }
437}
438
439/// A "sub"-diagnostic attached to a parent diagnostic.
440/// For example, a note attached to an error.
441#[derive(#[automatically_derived]
impl ::core::clone::Clone for Subdiag {
    #[inline]
    fn clone(&self) -> Subdiag {
        Subdiag {
            level: ::core::clone::Clone::clone(&self.level),
            messages: ::core::clone::Clone::clone(&self.messages),
            span: ::core::clone::Clone::clone(&self.span),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Subdiag {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "Subdiag",
            "level", &self.level, "messages", &self.messages, "span",
            &&self.span)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Subdiag {
    #[inline]
    fn eq(&self, other: &Subdiag) -> bool {
        self.level == other.level && self.messages == other.messages &&
            self.span == other.span
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Subdiag {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.level, state);
        ::core::hash::Hash::hash(&self.messages, state);
        ::core::hash::Hash::hash(&self.span, state)
    }
}Hash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for Subdiag {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    Subdiag {
                        level: ref __binding_0,
                        messages: ref __binding_1,
                        span: 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 Subdiag {
            fn decode(__decoder: &mut __D) -> Self {
                Subdiag {
                    level: ::rustc_serialize::Decodable::decode(__decoder),
                    messages: ::rustc_serialize::Decodable::decode(__decoder),
                    span: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable)]
442pub struct Subdiag {
443    pub level: Level,
444    pub messages: Vec<(DiagMessage, Style)>,
445    pub span: MultiSpan,
446}
447
448/// Used for emitting structured error messages and other diagnostic information.
449/// Wraps a `DiagInner`, adding some useful things.
450/// - The `dcx` field, allowing it to (a) emit itself, and (b) do a drop check
451///   that it has been emitted or cancelled.
452/// - The `EmissionGuarantee`, which determines the type returned from `emit`.
453///
454/// Each constructed `Diag` must be consumed by a function such as `emit`,
455/// `cancel`, `delay_as_bug`, or `into_diag`. A panic occurs if a `Diag`
456/// is dropped without being consumed by one of these functions.
457///
458/// If there is some state in a downstream crate you would like to access in
459/// the methods of `Diag` here, consider extending `DiagCtxtFlags`.
460#[must_use]
461pub struct Diag<'a, G: EmissionGuarantee = ErrorGuaranteed> {
462    pub dcx: DiagCtxtHandle<'a>,
463
464    /// Why the `Option`? It is always `Some` until the `Diag` is consumed via
465    /// `emit`, `cancel`, etc. At that point it is consumed and replaced with
466    /// `None`. Then `drop` checks that it is `None`; if not, it panics because
467    /// a diagnostic was built but not used.
468    ///
469    /// Why the Box? `DiagInner` is a large type, and `Diag` is often used as a
470    /// return value, especially within the frequently-used `PResult` type. In
471    /// theory, return value optimization (RVO) should avoid unnecessary
472    /// copying. In practice, it does not (at the time of writing).
473    diag: Option<Box<DiagInner>>,
474
475    _marker: PhantomData<G>,
476}
477
478// Cloning a `Diag` is a recipe for a diagnostic being emitted twice, which
479// would be bad.
480impl<G> !Clone for Diag<'_, G> {}
481
482const _: [(); 3 * size_of::<usize>()] =
    [(); ::std::mem::size_of::<Diag<'_, ()>>()];rustc_data_structures::static_assert_size!(Diag<'_, ()>, 3 * size_of::<usize>());
483
484impl<G: EmissionGuarantee> Deref for Diag<'_, G> {
485    type Target = DiagInner;
486
487    fn deref(&self) -> &DiagInner {
488        self.diag.as_ref().unwrap()
489    }
490}
491
492impl<G: EmissionGuarantee> DerefMut for Diag<'_, G> {
493    fn deref_mut(&mut self) -> &mut DiagInner {
494        self.diag.as_mut().unwrap()
495    }
496}
497
498impl<G: EmissionGuarantee> Debug for Diag<'_, G> {
499    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
500        self.diag.fmt(f)
501    }
502}
503
504/// `Diag` impls many `&mut self -> &mut Self` methods. Each one modifies an
505/// existing diagnostic, either in a standalone fashion, e.g.
506/// `err.code(code);`, or in a chained fashion to make multiple modifications,
507/// e.g. `err.code(code).span(span);`.
508///
509/// This macro creates an equivalent `self -> Self` method, with a `with_`
510/// prefix. This can be used in a chained fashion when making a new diagnostic,
511/// e.g. `let err = struct_err(msg).with_code(code);`, or emitting a new
512/// diagnostic, e.g. `struct_err(msg).with_code(code).emit();`.
513///
514/// Although the latter method can be used to modify an existing diagnostic,
515/// e.g. `err = err.with_code(code);`, this should be avoided because the former
516/// method gives shorter code, e.g. `err.code(code);`.
517///
518/// Note: the `with_` methods are added only when needed. If you want to use
519/// one and it's not defined, feel free to add it.
520///
521/// Note: any doc comments must be within the `with_fn!` call.
522macro_rules! with_fn {
523    {
524        $with_f:ident,
525        $(#[$attrs:meta])*
526        pub fn $f:ident(&mut $self:ident, $($name:ident: $ty:ty),* $(,)?) -> &mut Self {
527            $($body:tt)*
528        }
529    } => {
530        // The original function.
531        $(#[$attrs])*
532        #[doc = concat!("See [`Diag::", stringify!($f), "()`].")]
533        pub fn $f(&mut $self, $($name: $ty),*) -> &mut Self {
534            $($body)*
535        }
536
537        // The `with_*` variant.
538        $(#[$attrs])*
539        #[doc = concat!("See [`Diag::", stringify!($f), "()`].")]
540        pub fn $with_f(mut $self, $($name: $ty),*) -> Self {
541            $self.$f($($name),*);
542            $self
543        }
544    };
545}
546
547impl<'a, G: EmissionGuarantee> Diag<'a, G> {
548    #[track_caller]
549    pub fn new(dcx: DiagCtxtHandle<'a>, level: Level, message: impl Into<DiagMessage>) -> Self {
550        Self::new_diagnostic(dcx, DiagInner::new(level, message))
551    }
552
553    /// Allow moving diagnostics between different error tainting contexts
554    pub fn with_dcx(mut self, dcx: DiagCtxtHandle<'_>) -> Diag<'_, G> {
555        Diag { dcx, diag: self.diag.take(), _marker: PhantomData }
556    }
557
558    /// Creates a new `Diag` with an already constructed diagnostic.
559    #[track_caller]
560    pub(crate) fn new_diagnostic(dcx: DiagCtxtHandle<'a>, diag: DiagInner) -> Self {
561        {
    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/diagnostic.rs:561",
                        "rustc_errors::diagnostic", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/diagnostic.rs"),
                        ::tracing_core::__macro_support::Option::Some(561u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_errors::diagnostic"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("Created new diagnostic")
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("Created new diagnostic");
562        Self { dcx, diag: Some(Box::new(diag)), _marker: PhantomData }
563    }
564
565    /// Delay emission of this diagnostic as a bug.
566    ///
567    /// This can be useful in contexts where an error indicates a bug but
568    /// typically this only happens when other compilation errors have already
569    /// happened. In those cases this can be used to defer emission of this
570    /// diagnostic as a bug in the compiler only if no other errors have been
571    /// emitted.
572    ///
573    /// In the meantime, though, callsites are required to deal with the "bug"
574    /// locally in whichever way makes the most sense.
575    #[track_caller]
576    pub fn downgrade_to_delayed_bug(&mut self) {
577        if !#[allow(non_exhaustive_omitted_patterns)] match self.level {
            Level::Error | Level::DelayedBug => true,
            _ => false,
        } {
    {
        ::core::panicking::panic_fmt(format_args!("downgrade_to_delayed_bug: cannot downgrade {0:?} to DelayedBug: not an error",
                self.level));
    }
};assert!(
578            matches!(self.level, Level::Error | Level::DelayedBug),
579            "downgrade_to_delayed_bug: cannot downgrade {:?} to DelayedBug: not an error",
580            self.level
581        );
582        self.level = Level::DelayedBug;
583    }
584
585    /// Make emitting this diagnostic fatal
586    ///
587    /// Changes the level of this diagnostic to Fatal, and importantly also changes the emission guarantee.
588    /// This is sound for errors that would otherwise be printed, but now simply exit the process instead.
589    /// This function still gives an emission guarantee, the guarantee is now just that it exits fatally.
590    /// For delayed bugs this is different, since those are buffered. If we upgrade one to fatal, another
591    /// might now be ignored.
592    #[track_caller]
593    pub fn upgrade_to_fatal(mut self) -> Diag<'a, FatalAbort> {
594        if !#[allow(non_exhaustive_omitted_patterns)] match self.level {
            Level::Error => true,
            _ => false,
        } {
    {
        ::core::panicking::panic_fmt(format_args!("upgrade_to_fatal: cannot upgrade {0:?} to Fatal: not an error",
                self.level));
    }
};assert!(
595            matches!(self.level, Level::Error),
596            "upgrade_to_fatal: cannot upgrade {:?} to Fatal: not an error",
597            self.level
598        );
599        self.level = Level::Fatal;
600
601        // Take is okay since we immediately rewrap it in another diagnostic.
602        // i.e. we do emit it despite defusing the original diagnostic's drop bomb.
603        let diag = self.diag.take();
604        Diag { dcx: self.dcx, diag, _marker: PhantomData }
605    }
606
607    #[doc = r" Appends a labeled span to the diagnostic."]
#[doc = r""]
#[doc =
r" Labels are used to convey additional context for the diagnostic's primary span. They will"]
#[doc =
r" be shown together with the original diagnostic's span, *not* with spans added by"]
#[doc =
r" `span_note`, `span_help`, etc. Therefore, if the primary span is not displayable (because"]
#[doc =
r" the span is `DUMMY_SP` or the source code isn't found), labels will not be displayed"]
#[doc = r" either."]
#[doc = r""]
#[doc =
r" Implementation-wise, the label span is pushed onto the [`MultiSpan`] that was created when"]
#[doc =
r" the diagnostic was constructed. However, the label span is *not* considered a"]
#[doc =
r#" ["primary span"][`MultiSpan`]; only the `Span` supplied when creating the diagnostic is"#]
#[doc = r" primary."]
#[doc = "See [`Diag::span_label()`]."]
pub fn span_label(&mut self, span: Span, label: impl Into<DiagMessage>)
    -> &mut Self {
    self.span.push_span_label(span, label.into());
    self
}
#[doc = r" Appends a labeled span to the diagnostic."]
#[doc = r""]
#[doc =
r" Labels are used to convey additional context for the diagnostic's primary span. They will"]
#[doc =
r" be shown together with the original diagnostic's span, *not* with spans added by"]
#[doc =
r" `span_note`, `span_help`, etc. Therefore, if the primary span is not displayable (because"]
#[doc =
r" the span is `DUMMY_SP` or the source code isn't found), labels will not be displayed"]
#[doc = r" either."]
#[doc = r""]
#[doc =
r" Implementation-wise, the label span is pushed onto the [`MultiSpan`] that was created when"]
#[doc =
r" the diagnostic was constructed. However, the label span is *not* considered a"]
#[doc =
r#" ["primary span"][`MultiSpan`]; only the `Span` supplied when creating the diagnostic is"#]
#[doc = r" primary."]
#[doc = "See [`Diag::span_label()`]."]
pub fn with_span_label(mut self, span: Span, label: impl Into<DiagMessage>)
    -> Self {
    self.span_label(span, label);
    self
}with_fn! { with_span_label,
608    /// Appends a labeled span to the diagnostic.
609    ///
610    /// Labels are used to convey additional context for the diagnostic's primary span. They will
611    /// be shown together with the original diagnostic's span, *not* with spans added by
612    /// `span_note`, `span_help`, etc. Therefore, if the primary span is not displayable (because
613    /// the span is `DUMMY_SP` or the source code isn't found), labels will not be displayed
614    /// either.
615    ///
616    /// Implementation-wise, the label span is pushed onto the [`MultiSpan`] that was created when
617    /// the diagnostic was constructed. However, the label span is *not* considered a
618    /// ["primary span"][`MultiSpan`]; only the `Span` supplied when creating the diagnostic is
619    /// primary.
620    pub fn span_label(&mut self, span: Span, label: impl Into<DiagMessage>) -> &mut Self {
621        self.span.push_span_label(span, label.into());
622        self
623    } }
624
625    #[doc = r" Labels all the given spans with the provided label."]
#[doc = r" See [`Self::span_label()`] for more information."]
#[doc = "See [`Diag::span_labels()`]."]
pub fn span_labels(&mut self, spans: impl IntoIterator<Item = Span>,
    label: &str) -> &mut Self {
    for span in spans { self.span_label(span, label.to_string()); }
    self
}
#[doc = r" Labels all the given spans with the provided label."]
#[doc = r" See [`Self::span_label()`] for more information."]
#[doc = "See [`Diag::span_labels()`]."]
pub fn with_span_labels(mut self, spans: impl IntoIterator<Item = Span>,
    label: &str) -> Self {
    self.span_labels(spans, label);
    self
}with_fn! { with_span_labels,
626    /// Labels all the given spans with the provided label.
627    /// See [`Self::span_label()`] for more information.
628    pub fn span_labels(&mut self, spans: impl IntoIterator<Item = Span>, label: &str) -> &mut Self {
629        for span in spans {
630            self.span_label(span, label.to_string());
631        }
632        self
633    } }
634
635    pub fn replace_span_with(&mut self, after: Span, keep_label: bool) -> &mut Self {
636        let before = self.span.clone();
637        self.span(after);
638        for span_label in before.span_labels() {
639            if let Some(label) = span_label.label {
640                if span_label.is_primary && keep_label {
641                    self.span.push_span_label(after, label);
642                } else {
643                    self.span.push_span_label(span_label.span, label);
644                }
645            }
646        }
647        self
648    }
649
650    pub fn note_expected_found(
651        &mut self,
652        expected_label: &str,
653        expected: DiagStyledString,
654        found_label: &str,
655        found: DiagStyledString,
656    ) -> &mut Self {
657        self.note_expected_found_extra(
658            expected_label,
659            expected,
660            found_label,
661            found,
662            DiagStyledString::normal(""),
663            DiagStyledString::normal(""),
664        )
665    }
666
667    pub fn note_expected_found_extra(
668        &mut self,
669        expected_label: &str,
670        expected: DiagStyledString,
671        found_label: &str,
672        found: DiagStyledString,
673        expected_extra: DiagStyledString,
674        found_extra: DiagStyledString,
675    ) -> &mut Self {
676        let expected_label = expected_label.to_string();
677        let expected_label = if expected_label.is_empty() {
678            "expected".to_string()
679        } else {
680            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected {0}", expected_label))
    })format!("expected {expected_label}")
681        };
682        let found_label = found_label.to_string();
683        let found_label = if found_label.is_empty() {
684            "found".to_string()
685        } else {
686            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("found {0}", found_label))
    })format!("found {found_label}")
687        };
688        let (found_padding, expected_padding) = if expected_label.len() > found_label.len() {
689            (expected_label.len() - found_label.len(), 0)
690        } else {
691            (0, found_label.len() - expected_label.len())
692        };
693        let mut msg = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [StringPart::normal(::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("{0}{1} `",
                                    " ".repeat(expected_padding), expected_label))
                        }))]))vec![StringPart::normal(format!(
694            "{}{} `",
695            " ".repeat(expected_padding),
696            expected_label
697        ))];
698        msg.extend(expected.0);
699        msg.push(StringPart::normal(::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("`")) })format!("`")));
700        msg.extend(expected_extra.0);
701        msg.push(StringPart::normal(::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("\n")) })format!("\n")));
702        msg.push(StringPart::normal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1} `",
                " ".repeat(found_padding), found_label))
    })format!("{}{} `", " ".repeat(found_padding), found_label)));
703        msg.extend(found.0);
704        msg.push(StringPart::normal(::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("`")) })format!("`")));
705        msg.extend(found_extra.0);
706
707        // For now, just attach these as notes.
708        self.highlighted_note(msg);
709        self
710    }
711
712    pub fn note_trait_signature(&mut self, name: Symbol, signature: String) -> &mut Self {
713        self.highlighted_note(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [StringPart::normal(::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!("`{0}` from trait: `",
                                    name))
                        })), StringPart::highlighted(signature),
                StringPart::normal("`")]))vec![
714            StringPart::normal(format!("`{name}` from trait: `")),
715            StringPart::highlighted(signature),
716            StringPart::normal("`"),
717        ]);
718        self
719    }
720
721    #[doc = r" Add a note attached to this diagnostic."]
#[doc = "See [`Diag::note()`]."]
pub fn note(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
    self.sub(Level::Note, msg, MultiSpan::new());
    self
}
#[doc = r" Add a note attached to this diagnostic."]
#[doc = "See [`Diag::note()`]."]
pub fn with_note(mut self, msg: impl Into<DiagMessage>) -> Self {
    self.note(msg);
    self
}with_fn! { with_note,
722    /// Add a note attached to this diagnostic.
723    pub fn note(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
724        self.sub(Level::Note, msg, MultiSpan::new());
725        self
726    } }
727
728    pub fn highlighted_note(&mut self, msg: Vec<StringPart>) -> &mut Self {
729        self.sub_with_highlights(Level::Note, msg, MultiSpan::new());
730        self
731    }
732
733    pub fn highlighted_span_note(
734        &mut self,
735        span: impl Into<MultiSpan>,
736        msg: Vec<StringPart>,
737    ) -> &mut Self {
738        self.sub_with_highlights(Level::Note, msg, span.into());
739        self
740    }
741
742    /// This is like [`Diag::note()`], but it's only printed once.
743    pub fn note_once(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
744        self.sub(Level::OnceNote, msg, MultiSpan::new());
745        self
746    }
747
748    #[doc = r" Prints the span with a note above it."]
#[doc = r" This is like [`Diag::note()`], but it gets its own span."]
#[doc = "See [`Diag::span_note()`]."]
pub fn span_note(&mut self, sp: impl Into<MultiSpan>,
    msg: impl Into<DiagMessage>) -> &mut Self {
    self.sub(Level::Note, msg, sp.into());
    self
}
#[doc = r" Prints the span with a note above it."]
#[doc = r" This is like [`Diag::note()`], but it gets its own span."]
#[doc = "See [`Diag::span_note()`]."]
pub fn with_span_note(mut self, sp: impl Into<MultiSpan>,
    msg: impl Into<DiagMessage>) -> Self {
    self.span_note(sp, msg);
    self
}with_fn! { with_span_note,
749    /// Prints the span with a note above it.
750    /// This is like [`Diag::note()`], but it gets its own span.
751    pub fn span_note(
752        &mut self,
753        sp: impl Into<MultiSpan>,
754        msg: impl Into<DiagMessage>,
755    ) -> &mut Self {
756        self.sub(Level::Note, msg, sp.into());
757        self
758    } }
759
760    /// Prints the span with a note above it.
761    /// This is like [`Diag::note_once()`], but it gets its own span.
762    pub fn span_note_once<S: Into<MultiSpan>>(
763        &mut self,
764        sp: S,
765        msg: impl Into<DiagMessage>,
766    ) -> &mut Self {
767        self.sub(Level::OnceNote, msg, sp.into());
768        self
769    }
770
771    #[doc = r" Add a warning attached to this diagnostic."]
#[doc = "See [`Diag::warn()`]."]
pub fn warn(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
    self.sub(Level::Warning, msg, MultiSpan::new());
    self
}
#[doc = r" Add a warning attached to this diagnostic."]
#[doc = "See [`Diag::warn()`]."]
pub fn with_warn(mut self, msg: impl Into<DiagMessage>) -> Self {
    self.warn(msg);
    self
}with_fn! { with_warn,
772    /// Add a warning attached to this diagnostic.
773    pub fn warn(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
774        self.sub(Level::Warning, msg, MultiSpan::new());
775        self
776    } }
777
778    /// Prints the span with a warning above it.
779    /// This is like [`Diag::warn()`], but it gets its own span.
780    pub fn span_warn<S: Into<MultiSpan>>(
781        &mut self,
782        sp: S,
783        msg: impl Into<DiagMessage>,
784    ) -> &mut Self {
785        self.sub(Level::Warning, msg, sp.into());
786        self
787    }
788
789    #[doc = r" Add a help message attached to this diagnostic."]
#[doc = "See [`Diag::help()`]."]
pub fn help(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
    self.sub(Level::Help, msg, MultiSpan::new());
    self
}
#[doc = r" Add a help message attached to this diagnostic."]
#[doc = "See [`Diag::help()`]."]
pub fn with_help(mut self, msg: impl Into<DiagMessage>) -> Self {
    self.help(msg);
    self
}with_fn! { with_help,
790    /// Add a help message attached to this diagnostic.
791    pub fn help(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
792        self.sub(Level::Help, msg, MultiSpan::new());
793        self
794    } }
795
796    /// This is like [`Diag::help()`], but it's only printed once.
797    pub fn help_once(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
798        self.sub(Level::OnceHelp, msg, MultiSpan::new());
799        self
800    }
801
802    /// Add a help message attached to this diagnostic with a customizable highlighted message.
803    pub fn highlighted_help(&mut self, msg: Vec<StringPart>) -> &mut Self {
804        self.sub_with_highlights(Level::Help, msg, MultiSpan::new());
805        self
806    }
807
808    /// Add a help message attached to this diagnostic with a customizable highlighted message.
809    pub fn highlighted_span_help(
810        &mut self,
811        span: impl Into<MultiSpan>,
812        msg: Vec<StringPart>,
813    ) -> &mut Self {
814        self.sub_with_highlights(Level::Help, msg, span.into());
815        self
816    }
817
818    #[doc = r" Prints the span with some help above it."]
#[doc = r" This is like [`Diag::help()`], but it gets its own span."]
#[doc = "See [`Diag::span_help()`]."]
pub fn span_help(&mut self, sp: impl Into<MultiSpan>,
    msg: impl Into<DiagMessage>) -> &mut Self {
    self.sub(Level::Help, msg, sp.into());
    self
}
#[doc = r" Prints the span with some help above it."]
#[doc = r" This is like [`Diag::help()`], but it gets its own span."]
#[doc = "See [`Diag::span_help()`]."]
pub fn with_span_help(mut self, sp: impl Into<MultiSpan>,
    msg: impl Into<DiagMessage>) -> Self {
    self.span_help(sp, msg);
    self
}with_fn! { with_span_help,
819    /// Prints the span with some help above it.
820    /// This is like [`Diag::help()`], but it gets its own span.
821    pub fn span_help(
822        &mut self,
823        sp: impl Into<MultiSpan>,
824        msg: impl Into<DiagMessage>,
825    ) -> &mut Self {
826        self.sub(Level::Help, msg, sp.into());
827        self
828    } }
829
830    /// Disallow attaching suggestions to this diagnostic.
831    /// Any suggestions attached e.g. with the `span_suggestion_*` methods
832    /// (before and after the call to `disable_suggestions`) will be ignored.
833    pub fn disable_suggestions(&mut self) -> &mut Self {
834        self.suggestions = Suggestions::Disabled;
835        self
836    }
837
838    /// Prevent new suggestions from being added to this diagnostic.
839    ///
840    /// Suggestions added before the call to `.seal_suggestions()` will be preserved
841    /// and new suggestions will be ignored.
842    pub fn seal_suggestions(&mut self) -> &mut Self {
843        if let Suggestions::Enabled(suggestions) = &mut self.suggestions {
844            let suggestions_slice = std::mem::take(suggestions).into_boxed_slice();
845            self.suggestions = Suggestions::Sealed(suggestions_slice);
846        }
847        self
848    }
849
850    /// Helper for pushing to `self.suggestions`.
851    ///
852    /// A new suggestion is added if suggestions are enabled for this diagnostic.
853    /// Otherwise, they are ignored.
854    fn push_suggestion(&mut self, suggestion: CodeSuggestion) {
855        for subst in &suggestion.substitutions {
856            for part in &subst.parts {
857                let span = part.span;
858                let call_site = span.ctxt().outer_expn_data().call_site;
859                if span.in_derive_expansion() && span.overlaps_or_adjacent(call_site) {
860                    // Ignore if spans is from derive macro.
861                    return;
862                }
863            }
864        }
865
866        if let Suggestions::Enabled(suggestions) = &mut self.suggestions {
867            suggestions.push(suggestion);
868        }
869    }
870
871    #[doc =
r" Show a suggestion that has multiple parts to it, always as its own subdiagnostic."]
#[doc =
r" In other words, multiple changes need to be applied as part of this suggestion."]
#[doc = "See [`Diag::multipart_suggestion()`]."]
pub fn multipart_suggestion(&mut self, msg: impl Into<DiagMessage>,
    suggestion: Vec<(Span, String)>, applicability: Applicability)
    -> &mut Self {
    self.multipart_suggestion_with_style(msg, suggestion, applicability,
        SuggestionStyle::ShowAlways)
}
#[doc =
r" Show a suggestion that has multiple parts to it, always as its own subdiagnostic."]
#[doc =
r" In other words, multiple changes need to be applied as part of this suggestion."]
#[doc = "See [`Diag::multipart_suggestion()`]."]
pub fn with_multipart_suggestion(mut self, msg: impl Into<DiagMessage>,
    suggestion: Vec<(Span, String)>, applicability: Applicability) -> Self {
    self.multipart_suggestion(msg, suggestion, applicability);
    self
}with_fn! { with_multipart_suggestion,
872    /// Show a suggestion that has multiple parts to it, always as its own subdiagnostic.
873    /// In other words, multiple changes need to be applied as part of this suggestion.
874    pub fn multipart_suggestion(
875        &mut self,
876        msg: impl Into<DiagMessage>,
877        suggestion: Vec<(Span, String)>,
878        applicability: Applicability,
879    ) -> &mut Self {
880        self.multipart_suggestion_with_style(
881            msg,
882            suggestion,
883            applicability,
884            SuggestionStyle::ShowAlways,
885        )
886    } }
887
888    /// [`Diag::multipart_suggestion()`] but you can set the [`SuggestionStyle`].
889    pub fn multipart_suggestion_with_style(
890        &mut self,
891        msg: impl Into<DiagMessage>,
892        mut suggestion: Vec<(Span, String)>,
893        applicability: Applicability,
894        style: SuggestionStyle,
895    ) -> &mut Self {
896        let mut seen = crate::FxHashSet::default();
897        suggestion.retain(|(span, msg)| seen.insert((span.lo(), span.hi(), msg.clone())));
898
899        let parts = suggestion
900            .into_iter()
901            .map(|(span, snippet)| SubstitutionPart { snippet, span })
902            .collect::<Vec<_>>();
903
904        if !!parts.is_empty() {
    ::core::panicking::panic("assertion failed: !parts.is_empty()")
};assert!(!parts.is_empty());
905        if true {
    {
        match (&parts.iter().find(|part|
                            part.span.is_empty() && part.snippet.is_empty()), &None) {
            (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::Some(format_args!("Span must not be empty and have no suggestion")));
                }
            }
        }
    };
};debug_assert_eq!(
906            parts.iter().find(|part| part.span.is_empty() && part.snippet.is_empty()),
907            None,
908            "Span must not be empty and have no suggestion",
909        );
910        if true {
    {
        match (&parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)),
                &None) {
            (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::Some(format_args!("suggestion must not have overlapping parts")));
                }
            }
        }
    };
};debug_assert_eq!(
911            parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)),
912            None,
913            "suggestion must not have overlapping parts",
914        );
915
916        self.push_suggestion(CodeSuggestion {
917            substitutions: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [Substitution { parts }]))vec![Substitution { parts }],
918            msg: msg.into(),
919            style,
920            applicability,
921        });
922        self
923    }
924
925    /// Prints out a message with for a multipart suggestion without showing the suggested code.
926    ///
927    /// This is intended to be used for suggestions that are obvious in what the changes need to
928    /// be from the message, showing the span label inline would be visually unpleasant
929    /// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't
930    /// improve understandability.
931    pub fn tool_only_multipart_suggestion(
932        &mut self,
933        msg: impl Into<DiagMessage>,
934        suggestion: Vec<(Span, String)>,
935        applicability: Applicability,
936    ) -> &mut Self {
937        self.multipart_suggestion_with_style(
938            msg,
939            suggestion,
940            applicability,
941            SuggestionStyle::CompletelyHidden,
942        )
943    }
944
945    #[doc = r" Prints out a message with a suggested edit of the code."]
#[doc = r""]
#[doc =
r" In case of short messages and a simple suggestion, rustc displays it as a label:"]
#[doc = r""]
#[doc = r" ```text"]
#[doc = r" try adding parentheses: `(tup.0).1`"]
#[doc = r" ```"]
#[doc = r""]
#[doc = r" The message"]
#[doc = r""]
#[doc =
r" * should not end in any punctuation (a `:` is added automatically)"]
#[doc = r#" * should not be a question (avoid language like "did you mean")"#]
#[doc =
r#" * should not contain any phrases like "the following", "as shown", etc."#]
#[doc = r#" * may look like "to do xyz, use" or "to do xyz, use abc""#]
#[doc =
r" * may contain a name of a function, variable, or type, but not whole expressions"]
#[doc = r""]
#[doc = r" See [`CodeSuggestion`] for more information."]
#[doc = "See [`Diag::span_suggestion()`]."]
pub fn span_suggestion(&mut self, sp: Span, msg: impl Into<DiagMessage>,
    suggestion: impl ToString, applicability: Applicability) -> &mut Self {
    self.span_suggestion_with_style(sp, msg, suggestion, applicability,
        SuggestionStyle::ShowCode);
    self
}
#[doc = r" Prints out a message with a suggested edit of the code."]
#[doc = r""]
#[doc =
r" In case of short messages and a simple suggestion, rustc displays it as a label:"]
#[doc = r""]
#[doc = r" ```text"]
#[doc = r" try adding parentheses: `(tup.0).1`"]
#[doc = r" ```"]
#[doc = r""]
#[doc = r" The message"]
#[doc = r""]
#[doc =
r" * should not end in any punctuation (a `:` is added automatically)"]
#[doc = r#" * should not be a question (avoid language like "did you mean")"#]
#[doc =
r#" * should not contain any phrases like "the following", "as shown", etc."#]
#[doc = r#" * may look like "to do xyz, use" or "to do xyz, use abc""#]
#[doc =
r" * may contain a name of a function, variable, or type, but not whole expressions"]
#[doc = r""]
#[doc = r" See [`CodeSuggestion`] for more information."]
#[doc = "See [`Diag::span_suggestion()`]."]
pub fn with_span_suggestion(mut self, sp: Span, msg: impl Into<DiagMessage>,
    suggestion: impl ToString, applicability: Applicability) -> Self {
    self.span_suggestion(sp, msg, suggestion, applicability);
    self
}with_fn! { with_span_suggestion,
946    /// Prints out a message with a suggested edit of the code.
947    ///
948    /// In case of short messages and a simple suggestion, rustc displays it as a label:
949    ///
950    /// ```text
951    /// try adding parentheses: `(tup.0).1`
952    /// ```
953    ///
954    /// The message
955    ///
956    /// * should not end in any punctuation (a `:` is added automatically)
957    /// * should not be a question (avoid language like "did you mean")
958    /// * should not contain any phrases like "the following", "as shown", etc.
959    /// * may look like "to do xyz, use" or "to do xyz, use abc"
960    /// * may contain a name of a function, variable, or type, but not whole expressions
961    ///
962    /// See [`CodeSuggestion`] for more information.
963    pub fn span_suggestion(
964        &mut self,
965        sp: Span,
966        msg: impl Into<DiagMessage>,
967        suggestion: impl ToString,
968        applicability: Applicability,
969    ) -> &mut Self {
970        self.span_suggestion_with_style(
971            sp,
972            msg,
973            suggestion,
974            applicability,
975            SuggestionStyle::ShowCode,
976        );
977        self
978    } }
979
980    #[doc =
r" [`Diag::span_suggestion()`] but you can set the [`SuggestionStyle`]."]
#[doc = "See [`Diag::span_suggestion_with_style()`]."]
pub fn span_suggestion_with_style(&mut self, sp: Span,
    msg: impl Into<DiagMessage>, suggestion: impl ToString,
    applicability: Applicability, style: SuggestionStyle) -> &mut Self {
    if true {
        if !!(sp.is_empty() && suggestion.to_string().is_empty()) {
            {
                ::core::panicking::panic_fmt(format_args!("Span must not be empty and have no suggestion"));
            }
        };
    };
    self.push_suggestion(CodeSuggestion {
            substitutions: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                    [Substitution {
                                parts: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                                        [SubstitutionPart {
                                                    snippet: suggestion.to_string(),
                                                    span: sp,
                                                }])),
                            }])),
            msg: msg.into(),
            style,
            applicability,
        });
    self
}
#[doc =
r" [`Diag::span_suggestion()`] but you can set the [`SuggestionStyle`]."]
#[doc = "See [`Diag::span_suggestion_with_style()`]."]
pub fn with_span_suggestion_with_style(mut self, sp: Span,
    msg: impl Into<DiagMessage>, suggestion: impl ToString,
    applicability: Applicability, style: SuggestionStyle) -> Self {
    self.span_suggestion_with_style(sp, msg, suggestion, applicability,
        style);
    self
}with_fn! { with_span_suggestion_with_style,
981    /// [`Diag::span_suggestion()`] but you can set the [`SuggestionStyle`].
982    pub fn span_suggestion_with_style(
983        &mut self,
984        sp: Span,
985        msg: impl Into<DiagMessage>,
986        suggestion: impl ToString,
987        applicability: Applicability,
988        style: SuggestionStyle,
989    ) -> &mut Self {
990        debug_assert!(
991            !(sp.is_empty() && suggestion.to_string().is_empty()),
992            "Span must not be empty and have no suggestion"
993        );
994        self.push_suggestion(CodeSuggestion {
995            substitutions: vec![Substitution {
996                parts: vec![SubstitutionPart { snippet: suggestion.to_string(), span: sp }],
997            }],
998            msg: msg.into(),
999            style,
1000            applicability,
1001        });
1002        self
1003    } }
1004
1005    #[doc = r" Always show the suggested change."]
#[doc = "See [`Diag::span_suggestion_verbose()`]."]
pub fn span_suggestion_verbose(&mut self, sp: Span,
    msg: impl Into<DiagMessage>, suggestion: impl ToString,
    applicability: Applicability) -> &mut Self {
    self.span_suggestion_with_style(sp, msg, suggestion, applicability,
        SuggestionStyle::ShowAlways);
    self
}
#[doc = r" Always show the suggested change."]
#[doc = "See [`Diag::span_suggestion_verbose()`]."]
pub fn with_span_suggestion_verbose(mut self, sp: Span,
    msg: impl Into<DiagMessage>, suggestion: impl ToString,
    applicability: Applicability) -> Self {
    self.span_suggestion_verbose(sp, msg, suggestion, applicability);
    self
}with_fn! { with_span_suggestion_verbose,
1006    /// Always show the suggested change.
1007    pub fn span_suggestion_verbose(
1008        &mut self,
1009        sp: Span,
1010        msg: impl Into<DiagMessage>,
1011        suggestion: impl ToString,
1012        applicability: Applicability,
1013    ) -> &mut Self {
1014        self.span_suggestion_with_style(
1015            sp,
1016            msg,
1017            suggestion,
1018            applicability,
1019            SuggestionStyle::ShowAlways,
1020        );
1021        self
1022    } }
1023
1024    #[doc = r" Prints out a message with multiple suggested edits of the code."]
#[doc = r" See also [`Diag::span_suggestion()`]."]
#[doc = "See [`Diag::span_suggestions()`]."]
pub fn span_suggestions(&mut self, sp: Span, msg: impl Into<DiagMessage>,
    suggestions: impl IntoIterator<Item = String>,
    applicability: Applicability) -> &mut Self {
    self.span_suggestions_with_style(sp, msg, suggestions, applicability,
        SuggestionStyle::ShowAlways)
}
#[doc = r" Prints out a message with multiple suggested edits of the code."]
#[doc = r" See also [`Diag::span_suggestion()`]."]
#[doc = "See [`Diag::span_suggestions()`]."]
pub fn with_span_suggestions(mut self, sp: Span, msg: impl Into<DiagMessage>,
    suggestions: impl IntoIterator<Item = String>,
    applicability: Applicability) -> Self {
    self.span_suggestions(sp, msg, suggestions, applicability);
    self
}with_fn! { with_span_suggestions,
1025    /// Prints out a message with multiple suggested edits of the code.
1026    /// See also [`Diag::span_suggestion()`].
1027    pub fn span_suggestions(
1028        &mut self,
1029        sp: Span,
1030        msg: impl Into<DiagMessage>,
1031        suggestions: impl IntoIterator<Item = String>,
1032        applicability: Applicability,
1033    ) -> &mut Self {
1034        self.span_suggestions_with_style(
1035            sp,
1036            msg,
1037            suggestions,
1038            applicability,
1039            SuggestionStyle::ShowAlways,
1040        )
1041    } }
1042
1043    pub fn span_suggestions_with_style(
1044        &mut self,
1045        sp: Span,
1046        msg: impl Into<DiagMessage>,
1047        suggestions: impl IntoIterator<Item = String>,
1048        applicability: Applicability,
1049        style: SuggestionStyle,
1050    ) -> &mut Self {
1051        let substitutions = suggestions
1052            .into_iter()
1053            .map(|snippet| {
1054                if true {
    if !!(sp.is_empty() && snippet.is_empty()) {
        {
            ::core::panicking::panic_fmt(format_args!("Span `{0:?}` must not be empty and have no suggestion",
                    sp));
        }
    };
};debug_assert!(
1055                    !(sp.is_empty() && snippet.is_empty()),
1056                    "Span `{sp:?}` must not be empty and have no suggestion"
1057                );
1058                Substitution { parts: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [SubstitutionPart { snippet, span: sp }]))vec![SubstitutionPart { snippet, span: sp }] }
1059            })
1060            .collect();
1061        self.push_suggestion(CodeSuggestion {
1062            substitutions,
1063            msg: msg.into(),
1064            style,
1065            applicability,
1066        });
1067        self
1068    }
1069
1070    /// Prints out a message with multiple suggested edits of the code, where each edit consists of
1071    /// multiple parts.
1072    /// See also [`Diag::multipart_suggestion()`].
1073    pub fn multipart_suggestions(
1074        &mut self,
1075        msg: impl Into<DiagMessage>,
1076        suggestions: impl IntoIterator<Item = Vec<(Span, String)>>,
1077        applicability: Applicability,
1078    ) -> &mut Self {
1079        let substitutions = suggestions
1080            .into_iter()
1081            .map(|sugg| {
1082                let mut parts = sugg
1083                    .into_iter()
1084                    .map(|(span, snippet)| SubstitutionPart { snippet, span })
1085                    .collect::<Vec<_>>();
1086
1087                parts.sort_unstable_by_key(|part| part.span);
1088
1089                if !!parts.is_empty() {
    ::core::panicking::panic("assertion failed: !parts.is_empty()")
};assert!(!parts.is_empty());
1090                if true {
    {
        match (&parts.iter().find(|part|
                            part.span.is_empty() && part.snippet.is_empty()), &None) {
            (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::Some(format_args!("Span must not be empty and have no suggestion")));
                }
            }
        }
    };
};debug_assert_eq!(
1091                    parts.iter().find(|part| part.span.is_empty() && part.snippet.is_empty()),
1092                    None,
1093                    "Span must not be empty and have no suggestion",
1094                );
1095                if true {
    {
        match (&parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)),
                &None) {
            (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::Some(format_args!("suggestion must not have overlapping parts")));
                }
            }
        }
    };
};debug_assert_eq!(
1096                    parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)),
1097                    None,
1098                    "suggestion must not have overlapping parts",
1099                );
1100
1101                Substitution { parts }
1102            })
1103            .collect();
1104
1105        self.push_suggestion(CodeSuggestion {
1106            substitutions,
1107            msg: msg.into(),
1108            style: SuggestionStyle::ShowAlways,
1109            applicability,
1110        });
1111        self
1112    }
1113
1114    #[doc =
r" Prints out a message with a suggested edit of the code. If the suggestion is presented"]
#[doc = r" inline, it will only show the message and not the suggestion."]
#[doc = r""]
#[doc = r" See [`CodeSuggestion`] for more information."]
#[doc = "See [`Diag::span_suggestion_short()`]."]
pub fn span_suggestion_short(&mut self, sp: Span, msg: impl Into<DiagMessage>,
    suggestion: impl ToString, applicability: Applicability) -> &mut Self {
    self.span_suggestion_with_style(sp, msg, suggestion, applicability,
        SuggestionStyle::HideCodeInline);
    self
}
#[doc =
r" Prints out a message with a suggested edit of the code. If the suggestion is presented"]
#[doc = r" inline, it will only show the message and not the suggestion."]
#[doc = r""]
#[doc = r" See [`CodeSuggestion`] for more information."]
#[doc = "See [`Diag::span_suggestion_short()`]."]
pub fn with_span_suggestion_short(mut self, sp: Span,
    msg: impl Into<DiagMessage>, suggestion: impl ToString,
    applicability: Applicability) -> Self {
    self.span_suggestion_short(sp, msg, suggestion, applicability);
    self
}with_fn! { with_span_suggestion_short,
1115    /// Prints out a message with a suggested edit of the code. If the suggestion is presented
1116    /// inline, it will only show the message and not the suggestion.
1117    ///
1118    /// See [`CodeSuggestion`] for more information.
1119    pub fn span_suggestion_short(
1120        &mut self,
1121        sp: Span,
1122        msg: impl Into<DiagMessage>,
1123        suggestion: impl ToString,
1124        applicability: Applicability,
1125    ) -> &mut Self {
1126        self.span_suggestion_with_style(
1127            sp,
1128            msg,
1129            suggestion,
1130            applicability,
1131            SuggestionStyle::HideCodeInline,
1132        );
1133        self
1134    } }
1135
1136    /// Prints out a message for a suggestion without showing the suggested code.
1137    ///
1138    /// This is intended to be used for suggestions that are obvious in what the changes need to
1139    /// be from the message, showing the span label inline would be visually unpleasant
1140    /// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't
1141    /// improve understandability.
1142    pub fn span_suggestion_hidden(
1143        &mut self,
1144        sp: Span,
1145        msg: impl Into<DiagMessage>,
1146        suggestion: impl ToString,
1147        applicability: Applicability,
1148    ) -> &mut Self {
1149        self.span_suggestion_with_style(
1150            sp,
1151            msg,
1152            suggestion,
1153            applicability,
1154            SuggestionStyle::HideCodeAlways,
1155        );
1156        self
1157    }
1158
1159    #[doc =
r" Adds a suggestion to the JSON output that will not be shown in the CLI."]
#[doc = r""]
#[doc =
r" This is intended to be used for suggestions that are *very* obvious in what the changes"]
#[doc =
r" need to be from the message, but we still want other tools to be able to apply them."]
#[doc = "See [`Diag::tool_only_span_suggestion()`]."]
pub fn tool_only_span_suggestion(&mut self, sp: Span,
    msg: impl Into<DiagMessage>, suggestion: impl ToString,
    applicability: Applicability) -> &mut Self {
    self.span_suggestion_with_style(sp, msg, suggestion, applicability,
        SuggestionStyle::CompletelyHidden);
    self
}
#[doc =
r" Adds a suggestion to the JSON output that will not be shown in the CLI."]
#[doc = r""]
#[doc =
r" This is intended to be used for suggestions that are *very* obvious in what the changes"]
#[doc =
r" need to be from the message, but we still want other tools to be able to apply them."]
#[doc = "See [`Diag::tool_only_span_suggestion()`]."]
pub fn with_tool_only_span_suggestion(mut self, sp: Span,
    msg: impl Into<DiagMessage>, suggestion: impl ToString,
    applicability: Applicability) -> Self {
    self.tool_only_span_suggestion(sp, msg, suggestion, applicability);
    self
}with_fn! { with_tool_only_span_suggestion,
1160    /// Adds a suggestion to the JSON output that will not be shown in the CLI.
1161    ///
1162    /// This is intended to be used for suggestions that are *very* obvious in what the changes
1163    /// need to be from the message, but we still want other tools to be able to apply them.
1164    pub fn tool_only_span_suggestion(
1165        &mut self,
1166        sp: Span,
1167        msg: impl Into<DiagMessage>,
1168        suggestion: impl ToString,
1169        applicability: Applicability,
1170    ) -> &mut Self {
1171        self.span_suggestion_with_style(
1172            sp,
1173            msg,
1174            suggestion,
1175            applicability,
1176            SuggestionStyle::CompletelyHidden,
1177        );
1178        self
1179    } }
1180
1181    /// Add a subdiagnostic from a type that implements `Subdiagnostic` (see
1182    /// [rustc_macros::Subdiagnostic]). Performs eager formatting of any messages
1183    /// used in the subdiagnostic, so suitable for use with repeated messages (i.e. re-use of
1184    /// interpolated variables).
1185    pub fn subdiagnostic(&mut self, subdiagnostic: impl Subdiagnostic) -> &mut Self {
1186        subdiagnostic.add_to_diag(self);
1187        self
1188    }
1189
1190    #[doc = r" Add a span."]
#[doc = "See [`Diag::span()`]."]
pub fn span(&mut self, sp: impl Into<MultiSpan>) -> &mut Self {
    self.span = sp.into();
    if let Some(span) = self.span.primary_span() { self.sort_span = span; }
    self
}
#[doc = r" Add a span."]
#[doc = "See [`Diag::span()`]."]
pub fn with_span(mut self, sp: impl Into<MultiSpan>) -> Self {
    self.span(sp);
    self
}with_fn! { with_span,
1191    /// Add a span.
1192    pub fn span(&mut self, sp: impl Into<MultiSpan>) -> &mut Self {
1193        self.span = sp.into();
1194        if let Some(span) = self.span.primary_span() {
1195            self.sort_span = span;
1196        }
1197        self
1198    } }
1199
1200    pub fn is_lint(
1201        &mut self,
1202        name: String,
1203        has_future_breakage: bool,
1204        rust_version: Option<RustcVersion>,
1205    ) -> &mut Self {
1206        self.is_lint = Some(IsLint { name, has_future_breakage, rust_version });
1207        self
1208    }
1209
1210    #[doc = r" Add an error code."]
#[doc = "See [`Diag::code()`]."]
pub fn code(&mut self, code: ErrCode) -> &mut Self {
    self.code = Some(code);
    self
}
#[doc = r" Add an error code."]
#[doc = "See [`Diag::code()`]."]
pub fn with_code(mut self, code: ErrCode) -> Self { self.code(code); self }with_fn! { with_code,
1211    /// Add an error code.
1212    pub fn code(&mut self, code: ErrCode) -> &mut Self {
1213        self.code = Some(code);
1214        self
1215    } }
1216
1217    #[doc = r" Add an argument."]
#[doc = "See [`Diag::lint_id()`]."]
pub fn lint_id(&mut self, id: LintExpectationId) -> &mut Self {
    self.lint_id = Some(id);
    self
}
#[doc = r" Add an argument."]
#[doc = "See [`Diag::lint_id()`]."]
pub fn with_lint_id(mut self, id: LintExpectationId) -> Self {
    self.lint_id(id);
    self
}with_fn! { with_lint_id,
1218    /// Add an argument.
1219    pub fn lint_id(
1220        &mut self,
1221        id: LintExpectationId,
1222    ) -> &mut Self {
1223        self.lint_id = Some(id);
1224        self
1225    } }
1226
1227    #[doc = r" Add a primary message."]
#[doc = "See [`Diag::primary_message()`]."]
pub fn primary_message(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
    self.messages[0] = (msg.into(), Style::NoStyle);
    self
}
#[doc = r" Add a primary message."]
#[doc = "See [`Diag::primary_message()`]."]
pub fn with_primary_message(mut self, msg: impl Into<DiagMessage>) -> Self {
    self.primary_message(msg);
    self
}with_fn! { with_primary_message,
1228    /// Add a primary message.
1229    pub fn primary_message(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
1230        self.messages[0] = (msg.into(), Style::NoStyle);
1231        self
1232    } }
1233
1234    #[doc = r" Add an argument."]
#[doc = "See [`Diag::arg()`]."]
pub fn arg(&mut self, name: impl Into<DiagArgName>, arg: impl IntoDiagArg)
    -> &mut Self {
    self.deref_mut().arg(name, arg);
    self
}
#[doc = r" Add an argument."]
#[doc = "See [`Diag::arg()`]."]
pub fn with_arg(mut self, name: impl Into<DiagArgName>, arg: impl IntoDiagArg)
    -> Self {
    self.arg(name, arg);
    self
}with_fn! { with_arg,
1235    /// Add an argument.
1236    pub fn arg(
1237        &mut self,
1238        name: impl Into<DiagArgName>,
1239        arg: impl IntoDiagArg,
1240    ) -> &mut Self {
1241        self.deref_mut().arg(name, arg);
1242        self
1243    } }
1244
1245    /// Convenience function for internal use, clients should use one of the
1246    /// public methods above.
1247    ///
1248    /// Used by `proc_macro_server` for implementing `server::Diagnostic`.
1249    pub fn sub(&mut self, level: Level, message: impl Into<DiagMessage>, span: MultiSpan) {
1250        self.deref_mut().sub(level, message, span);
1251    }
1252
1253    /// Convenience function for internal use, clients should use one of the
1254    /// public methods above.
1255    fn sub_with_highlights(&mut self, level: Level, messages: Vec<StringPart>, span: MultiSpan) {
1256        let messages = messages.into_iter().map(|m| (m.content.into(), m.style)).collect();
1257        let sub = Subdiag { level, messages, span };
1258        self.children.push(sub);
1259    }
1260
1261    /// Takes the diagnostic. For use by methods that consume the Diag: `emit`,
1262    /// `cancel`, etc. Afterwards, `drop` is the only code that will be run on
1263    /// `self`.
1264    fn take_diag(&mut self) -> DiagInner {
1265        if let Some(path) = &self.long_ty_path {
1266            self.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the full name for the type has been written to \'{0}\'",
                path.display()))
    })format!(
1267                "the full name for the type has been written to '{}'",
1268                path.display()
1269            ));
1270            self.note("consider using `--verbose` to print the full type name to the console");
1271        }
1272        *self.diag.take().unwrap()
1273    }
1274
1275    /// This method allows us to access the path of the file where "long types" are written to.
1276    ///
1277    /// When calling `Diag::emit`, as part of that we will check if a `long_ty_path` has been set,
1278    /// and if it has been then we add a note mentioning the file where the "long types" were
1279    /// written to.
1280    ///
1281    /// When calling `tcx.short_string()` after a `Diag` is constructed, the preferred way of doing
1282    /// so is `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that
1283    /// keeps the existence of a "long type" anywhere in the diagnostic, so the note telling the
1284    /// user where we wrote the file to is only printed once at most, *and* it makes it much harder
1285    /// to forget to set it.
1286    ///
1287    /// If the diagnostic hasn't been created before a "short ty string" is created, then you should
1288    /// ensure that this method is called to set it `*diag.long_ty_path() = path`.
1289    ///
1290    /// As a rule of thumb, if you see or add at least one `tcx.short_string()` call anywhere, in a
1291    /// scope, `diag.long_ty_path()` should be called once somewhere close by.
1292    pub fn long_ty_path(&mut self) -> &mut Option<PathBuf> {
1293        &mut self.long_ty_path
1294    }
1295
1296    pub fn with_long_ty_path(mut self, long_ty_path: Option<PathBuf>) -> Self {
1297        self.long_ty_path = long_ty_path;
1298        self
1299    }
1300
1301    /// Most `emit_producing_guarantee` functions use this as a starting point.
1302    fn emit_producing_nothing(mut self) {
1303        let diag = self.take_diag();
1304        self.dcx.emit_diagnostic(diag);
1305    }
1306
1307    /// `ErrorGuaranteed::emit_producing_guarantee` uses this.
1308    fn emit_producing_error_guaranteed(mut self) -> ErrorGuaranteed {
1309        let diag = self.take_diag();
1310
1311        // The only error levels that produce `ErrorGuaranteed` are
1312        // `Error` and `DelayedBug`. But `DelayedBug` should never occur here
1313        // because delayed bugs have their level changed to `Bug` when they are
1314        // actually printed, so they produce an ICE.
1315        //
1316        // (Also, even though `level` isn't `pub`, the whole `DiagInner` could
1317        // be overwritten with a new one thanks to `DerefMut`. So this assert
1318        // protects against that, too.)
1319        if !#[allow(non_exhaustive_omitted_patterns)] match diag.level {
            Level::Error | Level::DelayedBug => true,
            _ => false,
        } {
    {
        ::core::panicking::panic_fmt(format_args!("invalid diagnostic level ({0:?})",
                diag.level));
    }
};assert!(
1320            matches!(diag.level, Level::Error | Level::DelayedBug),
1321            "invalid diagnostic level ({:?})",
1322            diag.level,
1323        );
1324
1325        let guar = self.dcx.emit_diagnostic(diag);
1326        guar.unwrap()
1327    }
1328
1329    /// Emit and consume the diagnostic.
1330    #[track_caller]
1331    pub fn emit(self) -> G::EmitResult {
1332        G::emit_producing_guarantee(self)
1333    }
1334
1335    /// Emit the diagnostic unless `delay` is true,
1336    /// in which case the emission will be delayed as a bug.
1337    ///
1338    /// See `emit` and `delay_as_bug` for details.
1339    #[track_caller]
1340    pub fn emit_unless_delay(mut self, delay: bool) -> G::EmitResult {
1341        if delay {
1342            self.downgrade_to_delayed_bug();
1343        }
1344        self.emit()
1345    }
1346
1347    /// Cancel and consume the diagnostic. (A diagnostic must either be emitted or
1348    /// cancelled or it will panic when dropped).
1349    pub fn cancel(mut self) {
1350        self.diag = None;
1351        drop(self);
1352    }
1353
1354    /// Cancels this diagnostic and returns its first message, if it exists.
1355    pub fn cancel_into_message(self) -> Option<String> {
1356        let s = self.diag.as_ref()?.messages.get(0)?.0.as_str().map(ToString::to_string);
1357        self.cancel();
1358        s
1359    }
1360
1361    /// See `DiagCtxt::stash_diagnostic` for details.
1362    pub fn stash(mut self, span: Span, key: StashKey) -> Option<ErrorGuaranteed> {
1363        let diag = self.take_diag();
1364        self.dcx.stash_diagnostic(span, key, diag)
1365    }
1366
1367    /// Delay emission of this diagnostic as a bug.
1368    ///
1369    /// This can be useful in contexts where an error indicates a bug but
1370    /// typically this only happens when other compilation errors have already
1371    /// happened. In those cases this can be used to defer emission of this
1372    /// diagnostic as a bug in the compiler only if no other errors have been
1373    /// emitted.
1374    ///
1375    /// In the meantime, though, callsites are required to deal with the "bug"
1376    /// locally in whichever way makes the most sense.
1377    #[track_caller]
1378    pub fn delay_as_bug(mut self) -> G::EmitResult {
1379        self.downgrade_to_delayed_bug();
1380        self.emit()
1381    }
1382}
1383
1384/// Destructor bomb: every `Diag` must be consumed (emitted, cancelled, etc.)
1385/// or we emit a bug.
1386impl<G: EmissionGuarantee> Drop for Diag<'_, G> {
1387    fn drop(&mut self) {
1388        match self.diag.take() {
1389            Some(diag) if !panicking() => {
1390                self.dcx.emit_diagnostic(DiagInner::new(
1391                    Level::Bug,
1392                    DiagMessage::from("the following error was constructed but not emitted"),
1393                ));
1394                self.dcx.emit_diagnostic(*diag);
1395                {
    ::core::panicking::panic_fmt(format_args!("error was constructed but not emitted"));
};panic!("error was constructed but not emitted");
1396            }
1397            _ => {}
1398        }
1399    }
1400}
1401
1402#[macro_export]
1403macro_rules! struct_span_code_err {
1404    ($dcx:expr, $span:expr, $code:expr, $($message:tt)*) => ({
1405        $dcx.struct_span_err($span, format!($($message)*)).with_code($code)
1406    })
1407}