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",
        );

        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)
    })
}
