use std::borrow::Cow;
use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::panic;
use std::path::PathBuf;
use std::thread::panicking;

use rustc_data_structures::fx::FxIndexMap;
use rustc_error_messages::{DiagArgName, DiagArgValue, IntoDiagArg};
use rustc_lint_defs::{Applicability, LintExpectationId};
use rustc_macros::{Decodable, Encodable};
use rustc_span::source_map::Spanned;
use rustc_span::{DUMMY_SP, Span, Symbol};
use tracing::debug;

use crate::snippet::Style;
use crate::{
    CodeSuggestion, DiagCtxtHandle, DiagMessage, ErrCode, ErrorGuaranteed, ExplicitBug, Level,
    MultiSpan, StashKey, SubdiagMessage, Substitution, SubstitutionPart, SuggestionStyle,
    Suggestions,
};

pub type DiagArgMap = FxIndexMap<DiagArgName, DiagArgValue>;

/// Trait for types that `Diag::emit` can return as a "guarantee" (or "proof")
/// token that the emission happened.
pub trait EmissionGuarantee: Sized {
    /// This exists so that bugs and fatal errors can both result in `!` (an
    /// abort) when emitted, but have different aborting behaviour.
    type EmitResult = Self;

    /// Implementation of `Diag::emit`, fully controlled by each `impl` of
    /// `EmissionGuarantee`, to make it impossible to create a value of
    /// `Self::EmitResult` without actually performing the emission.
    #[track_caller]
    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult;
}

impl EmissionGuarantee for ErrorGuaranteed {
    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult {
        diag.emit_producing_error_guaranteed()
    }
}

impl EmissionGuarantee for () {
    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult {
        diag.emit_producing_nothing();
    }
}

/// Marker type which enables implementation of `create_bug` and `emit_bug` functions for
/// bug diagnostics.
#[derive(Copy, Clone)]
pub struct BugAbort;

impl EmissionGuarantee for BugAbort {
    type EmitResult = !;

    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult {
        diag.emit_producing_nothing();
        panic::panic_any(ExplicitBug);
    }
}

/// Marker type which enables implementation of `create_fatal` and `emit_fatal` functions for
/// fatal diagnostics.
#[derive(Copy, Clone)]
pub struct FatalAbort;

impl EmissionGuarantee for FatalAbort {
    type EmitResult = !;

    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult {
        diag.emit_producing_nothing();
        crate::FatalError.raise()
    }
}

impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
    fn emit_producing_guarantee(diag: Diag<'_, Self>) -> Self::EmitResult {
        diag.emit_producing_nothing();
        rustc_span::fatal_error::FatalError
    }
}

/// Trait implemented by error types. This is rarely implemented manually. Instead, use
/// `#[derive(Diagnostic)]` -- see [rustc_macros::Diagnostic].
///
/// When implemented manually, it should be generic over the emission
/// guarantee, i.e.:
/// ```ignore (fragment)
/// impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for Foo { ... }
/// ```
/// rather than being specific:
/// ```ignore (fragment)
/// impl<'a> Diagnostic<'a> for Bar { ... }  // the default type param is `ErrorGuaranteed`
/// impl<'a> Diagnostic<'a, ()> for Baz { ... }
/// ```
/// There are two reasons for this.
/// - A diagnostic like `Foo` *could* be emitted at any level -- `level` is
///   passed in to `into_diag` from outside. Even if in practice it is
///   always emitted at a single level, we let the diagnostic creation/emission
///   site determine the level (by using `create_err`, `emit_warn`, etc.)
///   rather than the `Diagnostic` impl.
/// - Derived impls are always generic, and it's good for the hand-written
///   impls to be consistent with them.
#[rustc_diagnostic_item = "Diagnostic"]
pub trait Diagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> {
    /// Write out as a diagnostic out of `DiagCtxt`.
    #[must_use]
    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G>;
}

impl<'a, T, G> Diagnostic<'a, G> for Spanned<T>
where
    T: Diagnostic<'a, G>,
    G: EmissionGuarantee,
{
    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
        self.node.into_diag(dcx, level).with_span(self.span)
    }
}

/// Trait implemented by error types. This should not be implemented manually. Instead, use
/// `#[derive(Subdiagnostic)]` -- see [rustc_macros::Subdiagnostic].
#[rustc_diagnostic_item = "Subdiagnostic"]
pub trait Subdiagnostic
where
    Self: Sized,
{
    /// Add a subdiagnostic to an existing diagnostic.
    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>);
}

/// Trait implemented by lint types. This should not be implemented manually. Instead, use
/// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic].
#[rustc_diagnostic_item = "LintDiagnostic"]
pub trait LintDiagnostic<'a, G: EmissionGuarantee> {
    /// Decorate a lint with the information from this type.
    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>);
}

pub trait LintDiagnosticBox<'a, G: EmissionGuarantee> {
    fn decorate_lint_box<'b>(self: Box<Self>, diag: &'b mut Diag<'a, G>);
}

impl<'a, G: EmissionGuarantee, D: LintDiagnostic<'a, G>> LintDiagnosticBox<'a, G> for D {
    fn decorate_lint_box<'b>(self: Box<Self>, diag: &'b mut Diag<'a, G>) {
        self.decorate_lint(diag);
    }
}

#[derive(Clone, Debug, Encodable, Decodable)]
pub(crate) struct DiagLocation {
    file: Cow<'static, str>,
    line: u32,
    col: u32,
}

impl DiagLocation {
    #[track_caller]
    fn caller() -> Self {
        let loc = panic::Location::caller();
        DiagLocation { file: loc.file().into(), line: loc.line(), col: loc.column() }
    }
}

impl fmt::Display for DiagLocation {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}:{}:{}", self.file, self.line, self.col)
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
pub struct IsLint {
    /// The lint name.
    pub(crate) name: String,
    /// Indicates whether this lint should show up in cargo's future breakage report.
    has_future_breakage: bool,
}

#[derive(Debug, PartialEq, Eq)]
pub struct DiagStyledString(pub Vec<StringPart>);

impl DiagStyledString {
    pub fn new() -> DiagStyledString {
        DiagStyledString(vec![])
    }
    pub fn push_normal<S: Into<String>>(&mut self, t: S) {
        self.0.push(StringPart::normal(t));
    }
    pub fn push_highlighted<S: Into<String>>(&mut self, t: S) {
        self.0.push(StringPart::highlighted(t));
    }
    pub fn push<S: Into<String>>(&mut self, t: S, highlight: bool) {
        if highlight {
            self.push_highlighted(t);
        } else {
            self.push_normal(t);
        }
    }
    pub fn normal<S: Into<String>>(t: S) -> DiagStyledString {
        DiagStyledString(vec![StringPart::normal(t)])
    }

    pub fn highlighted<S: Into<String>>(t: S) -> DiagStyledString {
        DiagStyledString(vec![StringPart::highlighted(t)])
    }

    pub fn content(&self) -> String {
        self.0.iter().map(|x| x.content.as_str()).collect::<String>()
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct StringPart {
    content: String,
    style: Style,
}

impl StringPart {
    pub fn normal<S: Into<String>>(content: S) -> StringPart {
        StringPart { content: content.into(), style: Style::NoStyle }
    }

    pub fn highlighted<S: Into<String>>(content: S) -> StringPart {
        StringPart { content: content.into(), style: Style::Highlight }
    }
}

/// The main part of a diagnostic. Note that `Diag`, which wraps this type, is
/// used for most operations, and should be used instead whenever possible.
/// This type should only be used when `Diag`'s lifetime causes difficulties,
/// e.g. when storing diagnostics within `DiagCtxt`.
#[must_use]
#[derive(Clone, Debug, Encodable, Decodable)]
pub struct DiagInner {
    // NOTE(eddyb) this is private to disallow arbitrary after-the-fact changes,
    // outside of what methods in this crate themselves allow.
    pub(crate) level: Level,

    pub messages: Vec<(DiagMessage, Style)>,
    pub code: Option<ErrCode>,
    pub lint_id: Option<LintExpectationId>,
    pub span: MultiSpan,
    pub children: Vec<Subdiag>,
    pub suggestions: Suggestions,
    pub args: DiagArgMap,

    // This is used to store args and restore them after a subdiagnostic is rendered.
    pub reserved_args: DiagArgMap,

    /// This is not used for highlighting or rendering any error message. Rather, it can be used
    /// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
    /// `span` if there is one. Otherwise, it is `DUMMY_SP`.
    pub sort_span: Span,

    pub is_lint: Option<IsLint>,

    pub long_ty_path: Option<PathBuf>,
    /// With `-Ztrack_diagnostics` enabled,
    /// we print where in rustc this error was emitted.
    pub(crate) emitted_at: DiagLocation,
}

impl DiagInner {
    #[track_caller]
    pub fn new<M: Into<DiagMessage>>(level: Level, message: M) -> Self {
        DiagInner::new_with_messages(level, vec![(message.into(), Style::NoStyle)])
    }

    #[track_caller]
    pub fn new_with_messages(level: Level, messages: Vec<(DiagMessage, Style)>) -> Self {
        DiagInner {
            level,
            lint_id: None,
            messages,
            code: None,
            span: MultiSpan::new(),
            children: vec![],
            suggestions: Suggestions::Enabled(vec![]),
            args: Default::default(),
            reserved_args: Default::default(),
            sort_span: DUMMY_SP,
            is_lint: None,
            long_ty_path: None,
            emitted_at: DiagLocation::caller(),
        }
    }

    #[inline(always)]
    pub fn level(&self) -> Level {
        self.level
    }

    pub fn is_error(&self) -> bool {
        match self.level {
            Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => true,

            Level::ForceWarning
            | Level::Warning
            | Level::Note
            | Level::OnceNote
            | Level::Help
            | Level::OnceHelp
            | Level::FailureNote
            | Level::Allow
            | Level::Expect => false,
        }
    }

    /// Indicates whether this diagnostic should show up in cargo's future breakage report.
    pub(crate) fn has_future_breakage(&self) -> bool {
        matches!(self.is_lint, Some(IsLint { has_future_breakage: true, .. }))
    }

    pub(crate) fn is_force_warn(&self) -> bool {
        match self.level {
            Level::ForceWarning => {
                assert!(self.is_lint.is_some());
                true
            }
            _ => false,
        }
    }

    // See comment on `Diag::subdiagnostic_message_to_diagnostic_message`.
    pub(crate) fn subdiagnostic_message_to_diagnostic_message(
        &self,
        attr: impl Into<SubdiagMessage>,
    ) -> DiagMessage {
        let msg =
            self.messages.iter().map(|(msg, _)| msg).next().expect("diagnostic with no messages");
        msg.with_subdiagnostic_message(attr.into())
    }

    pub(crate) fn sub(
        &mut self,
        level: Level,
        message: impl Into<SubdiagMessage>,
        span: MultiSpan,
    ) {
        let sub = Subdiag {
            level,
            messages: vec![(
                self.subdiagnostic_message_to_diagnostic_message(message),
                Style::NoStyle,
            )],
            span,
        };
        self.children.push(sub);
    }

    pub(crate) fn arg(&mut self, name: impl Into<DiagArgName>, arg: impl IntoDiagArg) {
        let name = name.into();
        let value = arg.into_diag_arg(&mut self.long_ty_path);
        // This assertion is to avoid subdiagnostics overwriting an existing diagnostic arg.
        debug_assert!(
            !self.args.contains_key(&name) || self.args.get(&name) == Some(&value),
            "arg {} already exists",
            name
        );
        self.args.insert(name, value);
    }

    pub fn remove_arg(&mut self, name: &str) {
        self.args.swap_remove(name);
    }

    pub fn store_args(&mut self) {
        self.reserved_args = self.args.clone();
    }

    pub fn restore_args(&mut self) {
        self.args = std::mem::take(&mut self.reserved_args);
    }

    pub fn emitted_at_sub_diag(&self) -> Subdiag {
        let track = format!("-Ztrack-diagnostics: created at {}", self.emitted_at);
        Subdiag {
            level: crate::Level::Note,
            messages: vec![(DiagMessage::Str(Cow::Owned(track)), Style::NoStyle)],
            span: MultiSpan::new(),
        }
    }

    /// Fields used for Hash, and PartialEq trait.
    fn keys(
        &self,
    ) -> (
        &Level,
        &[(DiagMessage, Style)],
        &Option<ErrCode>,
        &MultiSpan,
        &[Subdiag],
        &Suggestions,
        Vec<(&DiagArgName, &DiagArgValue)>,
        &Option<IsLint>,
    ) {
        (
            &self.level,
            &self.messages,
            &self.code,
            &self.span,
            &self.children,
            &self.suggestions,
            self.args.iter().collect(),
            // omit self.sort_span
            &self.is_lint,
            // omit self.emitted_at
        )
    }
}

impl Hash for DiagInner {
    fn hash<H>(&self, state: &mut H)
    where
        H: Hasher,
    {
        self.keys().hash(state);
    }
}

impl PartialEq for DiagInner {
    fn eq(&self, other: &Self) -> bool {
        self.keys() == other.keys()
    }
}

/// A "sub"-diagnostic attached to a parent diagnostic.
/// For example, a note attached to an error.
#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
pub struct Subdiag {
    pub level: Level,
    pub messages: Vec<(DiagMessage, Style)>,
    pub span: MultiSpan,
}

/// Used for emitting structured error messages and other diagnostic information.
/// Wraps a `DiagInner`, adding some useful things.
/// - The `dcx` field, allowing it to (a) emit itself, and (b) do a drop check
///   that it has been emitted or cancelled.
/// - The `EmissionGuarantee`, which determines the type returned from `emit`.
///
/// Each constructed `Diag` must be consumed by a function such as `emit`,
/// `cancel`, `delay_as_bug`, or `into_diag`. A panic occurs if a `Diag`
/// is dropped without being consumed by one of these functions.
///
/// If there is some state in a downstream crate you would like to access in
/// the methods of `Diag` here, consider extending `DiagCtxtFlags`.
#[must_use]
pub struct Diag<'a, G: EmissionGuarantee = ErrorGuaranteed> {
    pub dcx: DiagCtxtHandle<'a>,

    /// Why the `Option`? It is always `Some` until the `Diag` is consumed via
    /// `emit`, `cancel`, etc. At that point it is consumed and replaced with
    /// `None`. Then `drop` checks that it is `None`; if not, it panics because
    /// a diagnostic was built but not used.
    ///
    /// Why the Box? `DiagInner` is a large type, and `Diag` is often used as a
    /// return value, especially within the frequently-used `PResult` type. In
    /// theory, return value optimization (RVO) should avoid unnecessary
    /// copying. In practice, it does not (at the time of writing).
    diag: Option<Box<DiagInner>>,

    _marker: PhantomData<G>,
}

// Cloning a `Diag` is a recipe for a diagnostic being emitted twice, which
// would be bad.
impl<G> !Clone for Diag<'_, G> {}

rustc_data_structures::static_assert_size!(Diag<'_, ()>, 3 * size_of::<usize>());

impl<G: EmissionGuarantee> Deref for Diag<'_, G> {
    type Target = DiagInner;

    fn deref(&self) -> &DiagInner {
        self.diag.as_ref().unwrap()
    }
}

impl<G: EmissionGuarantee> DerefMut for Diag<'_, G> {
    fn deref_mut(&mut self) -> &mut DiagInner {
        self.diag.as_mut().unwrap()
    }
}

impl<G: EmissionGuarantee> Debug for Diag<'_, G> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.diag.fmt(f)
    }
}

/// `Diag` impls many `&mut self -> &mut Self` methods. Each one modifies an
/// existing diagnostic, either in a standalone fashion, e.g.
/// `err.code(code);`, or in a chained fashion to make multiple modifications,
/// e.g. `err.code(code).span(span);`.
///
/// This macro creates an equivalent `self -> Self` method, with a `with_`
/// prefix. This can be used in a chained fashion when making a new diagnostic,
/// e.g. `let err = struct_err(msg).with_code(code);`, or emitting a new
/// diagnostic, e.g. `struct_err(msg).with_code(code).emit();`.
///
/// Although the latter method can be used to modify an existing diagnostic,
/// e.g. `err = err.with_code(code);`, this should be avoided because the former
/// method gives shorter code, e.g. `err.code(code);`.
///
/// Note: the `with_` methods are added only when needed. If you want to use
/// one and it's not defined, feel free to add it.
///
/// Note: any doc comments must be within the `with_fn!` call.
macro_rules! with_fn {
    {
        $with_f:ident,
        $(#[$attrs:meta])*
        pub fn $f:ident(&mut $self:ident, $($name:ident: $ty:ty),* $(,)?) -> &mut Self {
            $($body:tt)*
        }
    } => {
        // The original function.
        $(#[$attrs])*
        #[doc = concat!("See [`Diag::", stringify!($f), "()`].")]
        pub fn $f(&mut $self, $($name: $ty),*) -> &mut Self {
            $($body)*
        }

        // The `with_*` variant.
        $(#[$attrs])*
        #[doc = concat!("See [`Diag::", stringify!($f), "()`].")]
        pub fn $with_f(mut $self, $($name: $ty),*) -> Self {
            $self.$f($($name),*);
            $self
        }
    };
}

impl<'a, G: EmissionGuarantee> Diag<'a, G> {
    #[rustc_lint_diagnostics]
    #[track_caller]
    pub fn new(dcx: DiagCtxtHandle<'a>, level: Level, message: impl Into<DiagMessage>) -> Self {
        Self::new_diagnostic(dcx, DiagInner::new(level, message))
    }

    /// Allow moving diagnostics between different error tainting contexts
    pub fn with_dcx(mut self, dcx: DiagCtxtHandle<'_>) -> Diag<'_, G> {
        Diag { dcx, diag: self.diag.take(), _marker: PhantomData }
    }

    /// Creates a new `Diag` with an already constructed diagnostic.
    #[track_caller]
    pub(crate) fn new_diagnostic(dcx: DiagCtxtHandle<'a>, diag: DiagInner) -> Self {
        debug!("Created new diagnostic");
        Self { dcx, diag: Some(Box::new(diag)), _marker: PhantomData }
    }

    /// Delay emission of this diagnostic as a bug.
    ///
    /// This can be useful in contexts where an error indicates a bug but
    /// typically this only happens when other compilation errors have already
    /// happened. In those cases this can be used to defer emission of this
    /// diagnostic as a bug in the compiler only if no other errors have been
    /// emitted.
    ///
    /// In the meantime, though, callsites are required to deal with the "bug"
    /// locally in whichever way makes the most sense.
    #[rustc_lint_diagnostics]
    #[track_caller]
    pub fn downgrade_to_delayed_bug(&mut self) {
        assert!(
            matches!(self.level, Level::Error | Level::DelayedBug),
            "downgrade_to_delayed_bug: cannot downgrade {:?} to DelayedBug: not an error",
            self.level
        );
        self.level = Level::DelayedBug;
    }

    /// Make emitting this diagnostic fatal
    ///
    /// Changes the level of this diagnostic to Fatal, and importantly also changes the emission guarantee.
    /// This is sound for errors that would otherwise be printed, but now simply exit the process instead.
    /// This function still gives an emission guarantee, the guarantee is now just that it exits fatally.
    /// For delayed bugs this is different, since those are buffered. If we upgrade one to fatal, another
    /// might now be ignored.
    #[rustc_lint_diagnostics]
    #[track_caller]
    pub fn upgrade_to_fatal(mut self) -> Diag<'a, FatalAbort> {
        assert!(
            matches!(self.level, Level::Error),
            "upgrade_to_fatal: cannot upgrade {:?} to Fatal: not an error",
            self.level
        );
        self.level = Level::Fatal;

        // Take is okay since we immediately rewrap it in another diagnostic.
        // i.e. we do emit it despite defusing the original diagnostic's drop bomb.
        let diag = self.diag.take();
        Diag { dcx: self.dcx, diag, _marker: PhantomData }
    }

    with_fn! { with_span_label,
    /// Appends a labeled span to the diagnostic.
    ///
    /// Labels are used to convey additional context for the diagnostic's primary span. They will
    /// be shown together with the original diagnostic's span, *not* with spans added by
    /// `span_note`, `span_help`, etc. Therefore, if the primary span is not displayable (because
    /// the span is `DUMMY_SP` or the source code isn't found), labels will not be displayed
    /// either.
    ///
    /// Implementation-wise, the label span is pushed onto the [`MultiSpan`] that was created when
    /// the diagnostic was constructed. However, the label span is *not* considered a
    /// ["primary span"][`MultiSpan`]; only the `Span` supplied when creating the diagnostic is
    /// primary.
    #[rustc_lint_diagnostics]
    pub fn span_label(&mut self, span: Span, label: impl Into<SubdiagMessage>) -> &mut Self {
        let msg = self.subdiagnostic_message_to_diagnostic_message(label);
        self.span.push_span_label(span, msg);
        self
    } }

    with_fn! { with_span_labels,
    /// Labels all the given spans with the provided label.
    /// See [`Self::span_label()`] for more information.
    #[rustc_lint_diagnostics]
    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
    } }

    #[rustc_lint_diagnostics]
    pub fn replace_span_with(&mut self, after: Span, keep_label: bool) -> &mut Self {
        let before = self.span.clone();
        self.span(after);
        for span_label in before.span_labels() {
            if let Some(label) = span_label.label {
                if span_label.is_primary && keep_label {
                    self.span.push_span_label(after, label);
                } else {
                    self.span.push_span_label(span_label.span, label);
                }
            }
        }
        self
    }

    #[rustc_lint_diagnostics]
    pub fn note_expected_found(
        &mut self,
        expected_label: &str,
        expected: DiagStyledString,
        found_label: &str,
        found: DiagStyledString,
    ) -> &mut Self {
        self.note_expected_found_extra(
            expected_label,
            expected,
            found_label,
            found,
            DiagStyledString::normal(""),
            DiagStyledString::normal(""),
        )
    }

    #[rustc_lint_diagnostics]
    pub fn note_expected_found_extra(
        &mut self,
        expected_label: &str,
        expected: DiagStyledString,
        found_label: &str,
        found: DiagStyledString,
        expected_extra: DiagStyledString,
        found_extra: DiagStyledString,
    ) -> &mut Self {
        let expected_label = expected_label.to_string();
        let expected_label = if expected_label.is_empty() {
            "expected".to_string()
        } else {
            format!("expected {expected_label}")
        };
        let found_label = found_label.to_string();
        let found_label = if found_label.is_empty() {
            "found".to_string()
        } else {
            format!("found {found_label}")
        };
        let (found_padding, expected_padding) = if expected_label.len() > found_label.len() {
            (expected_label.len() - found_label.len(), 0)
        } else {
            (0, found_label.len() - expected_label.len())
        };
        let mut msg = vec![StringPart::normal(format!(
            "{}{} `",
            " ".repeat(expected_padding),
            expected_label
        ))];
        msg.extend(expected.0);
        msg.push(StringPart::normal(format!("`")));
        msg.extend(expected_extra.0);
        msg.push(StringPart::normal(format!("\n")));
        msg.push(StringPart::normal(format!("{}{} `", " ".repeat(found_padding), found_label)));
        msg.extend(found.0);
        msg.push(StringPart::normal(format!("`")));
        msg.extend(found_extra.0);

        // For now, just attach these as notes.
        self.highlighted_note(msg);
        self
    }

    #[rustc_lint_diagnostics]
    pub fn note_trait_signature(&mut self, name: Symbol, signature: String) -> &mut Self {
        self.highlighted_note(vec![
            StringPart::normal(format!("`{name}` from trait: `")),
            StringPart::highlighted(signature),
            StringPart::normal("`"),
        ]);
        self
    }

    with_fn! { with_note,
    /// Add a note attached to this diagnostic.
    #[rustc_lint_diagnostics]
    pub fn note(&mut self, msg: impl Into<SubdiagMessage>) -> &mut Self {
        self.sub(Level::Note, msg, MultiSpan::new());
        self
    } }

    #[rustc_lint_diagnostics]
    pub fn highlighted_note(&mut self, msg: Vec<StringPart>) -> &mut Self {
        self.sub_with_highlights(Level::Note, msg, MultiSpan::new());
        self
    }

    #[rustc_lint_diagnostics]
    pub fn highlighted_span_note(
        &mut self,
        span: impl Into<MultiSpan>,
        msg: Vec<StringPart>,
    ) -> &mut Self {
        self.sub_with_highlights(Level::Note, msg, span.into());
        self
    }

    /// This is like [`Diag::note()`], but it's only printed once.
    #[rustc_lint_diagnostics]
    pub fn note_once(&mut self, msg: impl Into<SubdiagMessage>) -> &mut Self {
        self.sub(Level::OnceNote, msg, MultiSpan::new());
        self
    }

    with_fn! { with_span_note,
    /// Prints the span with a note above it.
    /// This is like [`Diag::note()`], but it gets its own span.
    #[rustc_lint_diagnostics]
    pub fn span_note(
        &mut self,
        sp: impl Into<MultiSpan>,
        msg: impl Into<SubdiagMessage>,
    ) -> &mut Self {
        self.sub(Level::Note, msg, sp.into());
        self
    } }

    /// Prints the span with a note above it.
    /// This is like [`Diag::note_once()`], but it gets its own span.
    #[rustc_lint_diagnostics]
    pub fn span_note_once<S: Into<MultiSpan>>(
        &mut self,
        sp: S,
        msg: impl Into<SubdiagMessage>,
    ) -> &mut Self {
        self.sub(Level::OnceNote, msg, sp.into());
        self
    }

    with_fn! { with_warn,
    /// Add a warning attached to this diagnostic.
    #[rustc_lint_diagnostics]
    pub fn warn(&mut self, msg: impl Into<SubdiagMessage>) -> &mut Self {
        self.sub(Level::Warning, msg, MultiSpan::new());
        self
    } }

    /// Prints the span with a warning above it.
    /// This is like [`Diag::warn()`], but it gets its own span.
    #[rustc_lint_diagnostics]
    pub fn span_warn<S: Into<MultiSpan>>(
        &mut self,
        sp: S,
        msg: impl Into<SubdiagMessage>,
    ) -> &mut Self {
        self.sub(Level::Warning, msg, sp.into());
        self
    }

    with_fn! { with_help,
    /// Add a help message attached to this diagnostic.
    #[rustc_lint_diagnostics]
    pub fn help(&mut self, msg: impl Into<SubdiagMessage>) -> &mut Self {
        self.sub(Level::Help, msg, MultiSpan::new());
        self
    } }

    /// This is like [`Diag::help()`], but it's only printed once.
    #[rustc_lint_diagnostics]
    pub fn help_once(&mut self, msg: impl Into<SubdiagMessage>) -> &mut Self {
        self.sub(Level::OnceHelp, msg, MultiSpan::new());
        self
    }

    /// Add a help message attached to this diagnostic with a customizable highlighted message.
    #[rustc_lint_diagnostics]
    pub fn highlighted_help(&mut self, msg: Vec<StringPart>) -> &mut Self {
        self.sub_with_highlights(Level::Help, msg, MultiSpan::new());
        self
    }

    /// Add a help message attached to this diagnostic with a customizable highlighted message.
    #[rustc_lint_diagnostics]
    pub fn highlighted_span_help(
        &mut self,
        span: impl Into<MultiSpan>,
        msg: Vec<StringPart>,
    ) -> &mut Self {
        self.sub_with_highlights(Level::Help, msg, span.into());
        self
    }

    with_fn! { with_span_help,
    /// Prints the span with some help above it.
    /// This is like [`Diag::help()`], but it gets its own span.
    #[rustc_lint_diagnostics]
    pub fn span_help(
        &mut self,
        sp: impl Into<MultiSpan>,
        msg: impl Into<SubdiagMessage>,
    ) -> &mut Self {
        self.sub(Level::Help, msg, sp.into());
        self
    } }

    /// Disallow attaching suggestions to this diagnostic.
    /// Any suggestions attached e.g. with the `span_suggestion_*` methods
    /// (before and after the call to `disable_suggestions`) will be ignored.
    #[rustc_lint_diagnostics]
    pub fn disable_suggestions(&mut self) -> &mut Self {
        self.suggestions = Suggestions::Disabled;
        self
    }

    /// Prevent new suggestions from being added to this diagnostic.
    ///
    /// Suggestions added before the call to `.seal_suggestions()` will be preserved
    /// and new suggestions will be ignored.
    #[rustc_lint_diagnostics]
    pub fn seal_suggestions(&mut self) -> &mut Self {
        if let Suggestions::Enabled(suggestions) = &mut self.suggestions {
            let suggestions_slice = std::mem::take(suggestions).into_boxed_slice();
            self.suggestions = Suggestions::Sealed(suggestions_slice);
        }
        self
    }

    /// Helper for pushing to `self.suggestions`.
    ///
    /// A new suggestion is added if suggestions are enabled for this diagnostic.
    /// Otherwise, they are ignored.
    #[rustc_lint_diagnostics]
    fn push_suggestion(&mut self, suggestion: CodeSuggestion) {
        for subst in &suggestion.substitutions {
            for part in &subst.parts {
                let span = part.span;
                let call_site = span.ctxt().outer_expn_data().call_site;
                if span.in_derive_expansion() && span.overlaps_or_adjacent(call_site) {
                    // Ignore if spans is from derive macro.
                    return;
                }
            }
        }

        if let Suggestions::Enabled(suggestions) = &mut self.suggestions {
            suggestions.push(suggestion);
        }
    }

    with_fn! { with_multipart_suggestion,
    /// Show a suggestion that has multiple parts to it.
    /// In other words, multiple changes need to be applied as part of this suggestion.
    #[rustc_lint_diagnostics]
    pub fn multipart_suggestion(
        &mut self,
        msg: impl Into<SubdiagMessage>,
        suggestion: Vec<(Span, String)>,
        applicability: Applicability,
    ) -> &mut Self {
        self.multipart_suggestion_with_style(
            msg,
            suggestion,
            applicability,
            SuggestionStyle::ShowCode,
        )
    } }

    /// Show a suggestion that has multiple parts to it, always as its own subdiagnostic.
    /// In other words, multiple changes need to be applied as part of this suggestion.
    #[rustc_lint_diagnostics]
    pub fn multipart_suggestion_verbose(
        &mut self,
        msg: impl Into<SubdiagMessage>,
        suggestion: Vec<(Span, String)>,
        applicability: Applicability,
    ) -> &mut Self {
        self.multipart_suggestion_with_style(
            msg,
            suggestion,
            applicability,
            SuggestionStyle::ShowAlways,
        )
    }

    /// [`Diag::multipart_suggestion()`] but you can set the [`SuggestionStyle`].
    #[rustc_lint_diagnostics]
    pub fn multipart_suggestion_with_style(
        &mut self,
        msg: impl Into<SubdiagMessage>,
        mut suggestion: Vec<(Span, String)>,
        applicability: Applicability,
        style: SuggestionStyle,
    ) -> &mut Self {
        let mut seen = crate::FxHashSet::default();
        suggestion.retain(|(span, msg)| seen.insert((span.lo(), span.hi(), msg.clone())));

        let parts = suggestion
            .into_iter()
            .map(|(span, snippet)| SubstitutionPart { snippet, span })
            .collect::<Vec<_>>();

        assert!(!parts.is_empty());
        debug_assert_eq!(
            parts.iter().find(|part| part.span.is_empty() && part.snippet.is_empty()),
            None,
            "Span must not be empty and have no suggestion",
        );
        debug_assert_eq!(
            parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)),
            None,
            "suggestion must not have overlapping parts",
        );

        self.push_suggestion(CodeSuggestion {
            substitutions: vec![Substitution { parts }],
            msg: self.subdiagnostic_message_to_diagnostic_message(msg),
            style,
            applicability,
        });
        self
    }

    /// Prints out a message with for a multipart suggestion without showing the suggested code.
    ///
    /// This is intended to be used for suggestions that are obvious in what the changes need to
    /// be from the message, showing the span label inline would be visually unpleasant
    /// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't
    /// improve understandability.
    #[rustc_lint_diagnostics]
    pub fn tool_only_multipart_suggestion(
        &mut self,
        msg: impl Into<SubdiagMessage>,
        suggestion: Vec<(Span, String)>,
        applicability: Applicability,
    ) -> &mut Self {
        self.multipart_suggestion_with_style(
            msg,
            suggestion,
            applicability,
            SuggestionStyle::CompletelyHidden,
        )
    }

    with_fn! { with_span_suggestion,
    /// Prints out a message with a suggested edit of the code.
    ///
    /// In case of short messages and a simple suggestion, rustc displays it as a label:
    ///
    /// ```text
    /// try adding parentheses: `(tup.0).1`
    /// ```
    ///
    /// The message
    ///
    /// * should not end in any punctuation (a `:` is added automatically)
    /// * should not be a question (avoid language like "did you mean")
    /// * should not contain any phrases like "the following", "as shown", etc.
    /// * may look like "to do xyz, use" or "to do xyz, use abc"
    /// * may contain a name of a function, variable, or type, but not whole expressions
    ///
    /// See [`CodeSuggestion`] for more information.
    #[rustc_lint_diagnostics]
    pub fn span_suggestion(
        &mut self,
        sp: Span,
        msg: impl Into<SubdiagMessage>,
        suggestion: impl ToString,
        applicability: Applicability,
    ) -> &mut Self {
        self.span_suggestion_with_style(
            sp,
            msg,
            suggestion,
            applicability,
            SuggestionStyle::ShowCode,
        );
        self
    } }

    /// [`Diag::span_suggestion()`] but you can set the [`SuggestionStyle`].
    #[rustc_lint_diagnostics]
    pub fn span_suggestion_with_style(
        &mut self,
        sp: Span,
        msg: impl Into<SubdiagMessage>,
        suggestion: impl ToString,
        applicability: Applicability,
        style: SuggestionStyle,
    ) -> &mut Self {
        debug_assert!(
            !(sp.is_empty() && suggestion.to_string().is_empty()),
            "Span must not be empty and have no suggestion"
        );
        self.push_suggestion(CodeSuggestion {
            substitutions: vec![Substitution {
                parts: vec![SubstitutionPart { snippet: suggestion.to_string(), span: sp }],
            }],
            msg: self.subdiagnostic_message_to_diagnostic_message(msg),
            style,
            applicability,
        });
        self
    }

    with_fn! { with_span_suggestion_verbose,
    /// Always show the suggested change.
    #[rustc_lint_diagnostics]
    pub fn span_suggestion_verbose(
        &mut self,
        sp: Span,
        msg: impl Into<SubdiagMessage>,
        suggestion: impl ToString,
        applicability: Applicability,
    ) -> &mut Self {
        self.span_suggestion_with_style(
            sp,
            msg,
            suggestion,
            applicability,
            SuggestionStyle::ShowAlways,
        );
        self
    } }

    with_fn! { with_span_suggestions,
    /// Prints out a message with multiple suggested edits of the code.
    /// See also [`Diag::span_suggestion()`].
    #[rustc_lint_diagnostics]
    pub fn span_suggestions(
        &mut self,
        sp: Span,
        msg: impl Into<SubdiagMessage>,
        suggestions: impl IntoIterator<Item = String>,
        applicability: Applicability,
    ) -> &mut Self {
        self.span_suggestions_with_style(
            sp,
            msg,
            suggestions,
            applicability,
            SuggestionStyle::ShowCode,
        )
    } }

    #[rustc_lint_diagnostics]
    pub fn span_suggestions_with_style(
        &mut self,
        sp: Span,
        msg: impl Into<SubdiagMessage>,
        suggestions: impl IntoIterator<Item = String>,
        applicability: Applicability,
        style: SuggestionStyle,
    ) -> &mut Self {
        let substitutions = suggestions
            .into_iter()
            .map(|snippet| {
                debug_assert!(
                    !(sp.is_empty() && snippet.is_empty()),
                    "Span `{sp:?}` must not be empty and have no suggestion"
                );
                Substitution { parts: vec![SubstitutionPart { snippet, span: sp }] }
            })
            .collect();
        self.push_suggestion(CodeSuggestion {
            substitutions,
            msg: self.subdiagnostic_message_to_diagnostic_message(msg),
            style,
            applicability,
        });
        self
    }

    /// Prints out a message with multiple suggested edits of the code, where each edit consists of
    /// multiple parts.
    /// See also [`Diag::multipart_suggestion()`].
    #[rustc_lint_diagnostics]
    pub fn multipart_suggestions(
        &mut self,
        msg: impl Into<SubdiagMessage>,
        suggestions: impl IntoIterator<Item = Vec<(Span, String)>>,
        applicability: Applicability,
    ) -> &mut Self {
        let substitutions = suggestions
            .into_iter()
            .map(|sugg| {
                let mut parts = sugg
                    .into_iter()
                    .map(|(span, snippet)| SubstitutionPart { snippet, span })
                    .collect::<Vec<_>>();

                parts.sort_unstable_by_key(|part| part.span);

                assert!(!parts.is_empty());
                debug_assert_eq!(
                    parts.iter().find(|part| part.span.is_empty() && part.snippet.is_empty()),
                    None,
                    "Span must not be empty and have no suggestion",
                );
                debug_assert_eq!(
                    parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)),
                    None,
                    "suggestion must not have overlapping parts",
                );

                Substitution { parts }
            })
            .collect();

        self.push_suggestion(CodeSuggestion {
            substitutions,
            msg: self.subdiagnostic_message_to_diagnostic_message(msg),
            style: SuggestionStyle::ShowAlways,
            applicability,
        });
        self
    }

    with_fn! { with_span_suggestion_short,
    /// Prints out a message with a suggested edit of the code. If the suggestion is presented
    /// inline, it will only show the message and not the suggestion.
    ///
    /// See [`CodeSuggestion`] for more information.
    #[rustc_lint_diagnostics]
    pub fn span_suggestion_short(
        &mut self,
        sp: Span,
        msg: impl Into<SubdiagMessage>,
        suggestion: impl ToString,
        applicability: Applicability,
    ) -> &mut Self {
        self.span_suggestion_with_style(
            sp,
            msg,
            suggestion,
            applicability,
            SuggestionStyle::HideCodeInline,
        );
        self
    } }

    /// Prints out a message for a suggestion without showing the suggested code.
    ///
    /// This is intended to be used for suggestions that are obvious in what the changes need to
    /// be from the message, showing the span label inline would be visually unpleasant
    /// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't
    /// improve understandability.
    #[rustc_lint_diagnostics]
    pub fn span_suggestion_hidden(
        &mut self,
        sp: Span,
        msg: impl Into<SubdiagMessage>,
        suggestion: impl ToString,
        applicability: Applicability,
    ) -> &mut Self {
        self.span_suggestion_with_style(
            sp,
            msg,
            suggestion,
            applicability,
            SuggestionStyle::HideCodeAlways,
        );
        self
    }

    with_fn! { with_tool_only_span_suggestion,
    /// Adds a suggestion to the JSON output that will not be shown in the CLI.
    ///
    /// This is intended to be used for suggestions that are *very* obvious in what the changes
    /// need to be from the message, but we still want other tools to be able to apply them.
    #[rustc_lint_diagnostics]
    pub fn tool_only_span_suggestion(
        &mut self,
        sp: Span,
        msg: impl Into<SubdiagMessage>,
        suggestion: impl ToString,
        applicability: Applicability,
    ) -> &mut Self {
        self.span_suggestion_with_style(
            sp,
            msg,
            suggestion,
            applicability,
            SuggestionStyle::CompletelyHidden,
        );
        self
    } }

    /// Add a subdiagnostic from a type that implements `Subdiagnostic` (see
    /// [rustc_macros::Subdiagnostic]). Performs eager translation of any translatable messages
    /// used in the subdiagnostic, so suitable for use with repeated messages (i.e. re-use of
    /// interpolated variables).
    #[rustc_lint_diagnostics]
    pub fn subdiagnostic(&mut self, subdiagnostic: impl Subdiagnostic) -> &mut Self {
        subdiagnostic.add_to_diag(self);
        self
    }

    /// Fluent variables are not namespaced from each other, so when
    /// `Diagnostic`s and `Subdiagnostic`s use the same variable name,
    /// one value will clobber the other. Eagerly translating the
    /// diagnostic uses the variables defined right then, before the
    /// clobbering occurs.
    pub fn eagerly_translate(&self, msg: impl Into<SubdiagMessage>) -> SubdiagMessage {
        let args = self.args.iter();
        let msg = self.subdiagnostic_message_to_diagnostic_message(msg.into());
        self.dcx.eagerly_translate(msg, args)
    }

    with_fn! { with_span,
    /// Add a span.
    #[rustc_lint_diagnostics]
    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
    } }

    #[rustc_lint_diagnostics]
    pub fn is_lint(&mut self, name: String, has_future_breakage: bool) -> &mut Self {
        self.is_lint = Some(IsLint { name, has_future_breakage });
        self
    }

    with_fn! { with_code,
    /// Add an error code.
    #[rustc_lint_diagnostics]
    pub fn code(&mut self, code: ErrCode) -> &mut Self {
        self.code = Some(code);
        self
    } }

    with_fn! { with_lint_id,
    /// Add an argument.
    #[rustc_lint_diagnostics]
    pub fn lint_id(
        &mut self,
        id: LintExpectationId,
    ) -> &mut Self {
        self.lint_id = Some(id);
        self
    } }

    with_fn! { with_primary_message,
    /// Add a primary message.
    #[rustc_lint_diagnostics]
    pub fn primary_message(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
        self.messages[0] = (msg.into(), Style::NoStyle);
        self
    } }

    with_fn! { with_arg,
    /// Add an argument.
    #[rustc_lint_diagnostics]
    pub fn arg(
        &mut self,
        name: impl Into<DiagArgName>,
        arg: impl IntoDiagArg,
    ) -> &mut Self {
        self.deref_mut().arg(name, arg);
        self
    } }

    /// Helper function that takes a `SubdiagMessage` and returns a `DiagMessage` by
    /// combining it with the primary message of the diagnostic (if translatable, otherwise it just
    /// passes the user's string along).
    pub(crate) fn subdiagnostic_message_to_diagnostic_message(
        &self,
        attr: impl Into<SubdiagMessage>,
    ) -> DiagMessage {
        self.deref().subdiagnostic_message_to_diagnostic_message(attr)
    }

    /// Convenience function for internal use, clients should use one of the
    /// public methods above.
    ///
    /// Used by `proc_macro_server` for implementing `server::Diagnostic`.
    pub fn sub(&mut self, level: Level, message: impl Into<SubdiagMessage>, span: MultiSpan) {
        self.deref_mut().sub(level, message, span);
    }

    /// Convenience function for internal use, clients should use one of the
    /// public methods above.
    fn sub_with_highlights(&mut self, level: Level, messages: Vec<StringPart>, span: MultiSpan) {
        let messages = messages
            .into_iter()
            .map(|m| (self.subdiagnostic_message_to_diagnostic_message(m.content), m.style))
            .collect();
        let sub = Subdiag { level, messages, span };
        self.children.push(sub);
    }

    /// Takes the diagnostic. For use by methods that consume the Diag: `emit`,
    /// `cancel`, etc. Afterwards, `drop` is the only code that will be run on
    /// `self`.
    fn take_diag(&mut self) -> DiagInner {
        if let Some(path) = &self.long_ty_path {
            self.note(format!(
                "the full name for the type has been written to '{}'",
                path.display()
            ));
            self.note("consider using `--verbose` to print the full type name to the console");
        }
        *self.diag.take().unwrap()
    }

    /// This method allows us to access the path of the file where "long types" are written to.
    ///
    /// When calling `Diag::emit`, as part of that we will check if a `long_ty_path` has been set,
    /// and if it has been then we add a note mentioning the file where the "long types" were
    /// written to.
    ///
    /// When calling `tcx.short_string()` after a `Diag` is constructed, the preferred way of doing
    /// so is `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that
    /// keeps the existence of a "long type" anywhere in the diagnostic, so the note telling the
    /// user where we wrote the file to is only printed once at most, *and* it makes it much harder
    /// to forget to set it.
    ///
    /// If the diagnostic hasn't been created before a "short ty string" is created, then you should
    /// ensure that this method is called to set it `*diag.long_ty_path() = path`.
    ///
    /// As a rule of thumb, if you see or add at least one `tcx.short_string()` call anywhere, in a
    /// scope, `diag.long_ty_path()` should be called once somewhere close by.
    pub fn long_ty_path(&mut self) -> &mut Option<PathBuf> {
        &mut self.long_ty_path
    }

    pub fn with_long_ty_path(mut self, long_ty_path: Option<PathBuf>) -> Self {
        self.long_ty_path = long_ty_path;
        self
    }

    /// Most `emit_producing_guarantee` functions use this as a starting point.
    fn emit_producing_nothing(mut self) {
        let diag = self.take_diag();
        self.dcx.emit_diagnostic(diag);
    }

    /// `ErrorGuaranteed::emit_producing_guarantee` uses this.
    fn emit_producing_error_guaranteed(mut self) -> ErrorGuaranteed {
        let diag = self.take_diag();

        // The only error levels that produce `ErrorGuaranteed` are
        // `Error` and `DelayedBug`. But `DelayedBug` should never occur here
        // because delayed bugs have their level changed to `Bug` when they are
        // actually printed, so they produce an ICE.
        //
        // (Also, even though `level` isn't `pub`, the whole `DiagInner` could
        // be overwritten with a new one thanks to `DerefMut`. So this assert
        // protects against that, too.)
        assert!(
            matches!(diag.level, Level::Error | Level::DelayedBug),
            "invalid diagnostic level ({:?})",
            diag.level,
        );

        let guar = self.dcx.emit_diagnostic(diag);
        guar.unwrap()
    }

    /// Emit and consume the diagnostic.
    #[track_caller]
    pub fn emit(self) -> G::EmitResult {
        G::emit_producing_guarantee(self)
    }

    /// Emit the diagnostic unless `delay` is true,
    /// in which case the emission will be delayed as a bug.
    ///
    /// See `emit` and `delay_as_bug` for details.
    #[track_caller]
    pub fn emit_unless_delay(mut self, delay: bool) -> G::EmitResult {
        if delay {
            self.downgrade_to_delayed_bug();
        }
        self.emit()
    }

    /// Cancel and consume the diagnostic. (A diagnostic must either be emitted or
    /// cancelled or it will panic when dropped).
    pub fn cancel(mut self) {
        self.diag = None;
        drop(self);
    }

    /// See `DiagCtxt::stash_diagnostic` for details.
    pub fn stash(mut self, span: Span, key: StashKey) -> Option<ErrorGuaranteed> {
        let diag = self.take_diag();
        self.dcx.stash_diagnostic(span, key, diag)
    }

    /// Delay emission of this diagnostic as a bug.
    ///
    /// This can be useful in contexts where an error indicates a bug but
    /// typically this only happens when other compilation errors have already
    /// happened. In those cases this can be used to defer emission of this
    /// diagnostic as a bug in the compiler only if no other errors have been
    /// emitted.
    ///
    /// In the meantime, though, callsites are required to deal with the "bug"
    /// locally in whichever way makes the most sense.
    #[track_caller]
    pub fn delay_as_bug(mut self) -> G::EmitResult {
        self.downgrade_to_delayed_bug();
        self.emit()
    }

    pub fn remove_arg(&mut self, name: &str) {
        if let Some(diag) = self.diag.as_mut() {
            diag.remove_arg(name);
        }
    }
}

/// Destructor bomb: every `Diag` must be consumed (emitted, cancelled, etc.)
/// or we emit a bug.
impl<G: EmissionGuarantee> Drop for Diag<'_, G> {
    fn drop(&mut self) {
        match self.diag.take() {
            Some(diag) if !panicking() => {
                self.dcx.emit_diagnostic(DiagInner::new(
                    Level::Bug,
                    DiagMessage::from("the following error was constructed but not emitted"),
                ));
                self.dcx.emit_diagnostic(*diag);
                panic!("error was constructed but not emitted");
            }
            _ => {}
        }
    }
}

#[macro_export]
macro_rules! struct_span_code_err {
    ($dcx:expr, $span:expr, $code:expr, $($message:tt)*) => ({
        $dcx.struct_span_err($span, format!($($message)*)).with_code($code)
    })
}
