//! Diagnostics creation and emission for `rustc`.
//!
//! This module contains the code for creating and emitting diagnostics.

// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(associated_type_defaults)]
#![feature(default_field_values)]
#![feature(macro_metavar_expr_concat)]
#![feature(negative_impls)]
// tidy-alphabetical-end

extern crate self as rustc_errors;

use std::backtrace::{Backtrace, BacktraceStatus};
use std::borrow::Cow;
use std::cell::Cell;
use std::ffi::OsStr;
use std::hash::Hash;
use std::io::Write;
use std::num::NonZero;
use std::ops::DerefMut;
use std::path::{Path, PathBuf};
use std::thread::ThreadId;
use std::{assert_matches, fmt, mem, panic};

use Level::*;
// Used by external projects such as `rust-gpu`.
// See https://github.com/rust-lang/rust/pull/115393.
pub use anstream::{AutoStream, ColorChoice};
pub use anstyle::{
    Ansi256Color, AnsiColor, Color, EffectIter, Effects, Reset, RgbColor, Style as Anstyle,
};
pub use codes::*;
pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer};
pub use diagnostic::{
    BugAbort, Diag, DiagDecorator, DiagInner, DiagLocation, DiagStyledString, Diagnostic,
    EmissionGuarantee, FatalAbort, StringPart, Subdiag, Subdiagnostic,
};
pub use diagnostic_impls::{
    DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
    IndicateAnonymousLifetime, SingleLabelManySpans,
};
pub use emitter::ColorConfig;
use emitter::{DynEmitter, Emitter};
use rustc_ast::attr::version::RustcVersion;
use rustc_data_structures::AtomicRef;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::stable_hash::StableHasher;
use rustc_data_structures::sync::{DynSend, Lock};
pub use rustc_error_messages::{
    DiagArg, DiagArgFromDisplay, DiagArgMap, DiagArgName, DiagArgValue, DiagMessage, IntoDiagArg,
    LanguageIdentifier, MultiSpan, SpanLabel, fluent_bundle, into_diag_arg_using_display,
};
use rustc_hashes::Hash128;
use rustc_lint_defs::LintExpectationId;
pub use rustc_lint_defs::{Applicability, listify, pluralize};
pub use rustc_macros::msg;
use rustc_macros::{Decodable, Encodable};
pub use rustc_span::ErrorGuaranteed;
pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker, catch_fatal_errors};
use rustc_span::source_map::SourceMap;
use rustc_span::{DUMMY_SP, Span};
use tracing::debug;

use crate::emitter::TimingEvent;
use crate::formatting::DiagMessageAddArg;
pub use crate::formatting::format_diag_message;
use crate::timings::TimingRecord;

pub mod annotate_snippet_emitter_writer;
pub mod codes;
mod decorate_diag;
mod diagnostic;
mod diagnostic_impls;
pub mod emitter;
pub mod formatting;
pub mod json;
mod lock;
pub mod markdown;
pub mod timings;

pub type PResult<'a, T> = Result<T, Diag<'a>>;

// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_pointer_width = "64")]
rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24);
#[cfg(target_pointer_width = "64")]
rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);

#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
pub enum SuggestionStyle {
    /// Hide the suggested code when displaying this suggestion inline.
    HideCodeInline,
    /// Always hide the suggested code but display the message.
    HideCodeAlways,
    /// Do not display this suggestion in the cli output, it is only meant for tools.
    CompletelyHidden,
    /// Always show the suggested code.
    /// This will *not* show the code if the suggestion is inline *and* the suggested code is
    /// empty.
    ShowCode,
    /// Always show the suggested code independently.
    ShowAlways,
}

impl SuggestionStyle {
    fn hide_inline(&self) -> bool {
        !matches!(*self, SuggestionStyle::ShowCode)
    }
}

/// Represents the help messages seen on a diagnostic.
#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
pub enum Suggestions {
    /// Indicates that new suggestions can be added or removed from this diagnostic.
    ///
    /// `DiagInner`'s new_* methods initialize the `suggestions` field with
    /// this variant. Also, this is the default variant for `Suggestions`.
    Enabled(Vec<CodeSuggestion>),
    /// Indicates that suggestions cannot be added or removed from this diagnostic.
    ///
    /// Gets toggled when `.seal_suggestions()` is called on the `DiagInner`.
    Sealed(Box<[CodeSuggestion]>),
    /// Indicates that no suggestion is available for this diagnostic.
    ///
    /// Gets toggled when `.disable_suggestions()` is called on the `DiagInner`.
    Disabled,
}

impl Suggestions {
    /// Returns the underlying list of suggestions.
    pub fn unwrap_tag(self) -> Vec<CodeSuggestion> {
        match self {
            Suggestions::Enabled(suggestions) => suggestions,
            Suggestions::Sealed(suggestions) => suggestions.into_vec(),
            Suggestions::Disabled => Vec::new(),
        }
    }

    pub fn len(&self) -> usize {
        match self {
            Suggestions::Enabled(suggestions) => suggestions.len(),
            Suggestions::Sealed(suggestions) => suggestions.len(),
            Suggestions::Disabled => 0,
        }
    }
}

impl Default for Suggestions {
    fn default() -> Self {
        Self::Enabled(vec![])
    }
}

#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
pub struct CodeSuggestion {
    /// Each substitute can have multiple variants due to multiple
    /// applicable suggestions
    ///
    /// `foo.bar` might be replaced with `a.b` or `x.y` by replacing
    /// `foo` and `bar` on their own:
    ///
    /// ```ignore (illustrative)
    /// vec![
    ///     Substitution { parts: vec![(0..3, "a"), (4..7, "b")] },
    ///     Substitution { parts: vec![(0..3, "x"), (4..7, "y")] },
    /// ]
    /// ```
    ///
    /// or by replacing the entire span:
    ///
    /// ```ignore (illustrative)
    /// vec![
    ///     Substitution { parts: vec![(0..7, "a.b")] },
    ///     Substitution { parts: vec![(0..7, "x.y")] },
    /// ]
    /// ```
    pub substitutions: Vec<Substitution>,
    pub msg: DiagMessage,
    /// Visual representation of this suggestion.
    pub style: SuggestionStyle,
    /// Whether or not the suggestion is approximate
    ///
    /// Sometimes we may show suggestions with placeholders,
    /// which are useful for users but not useful for
    /// tools like rustfix
    pub applicability: Applicability,
}

#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
/// See the docs on `CodeSuggestion::substitutions`
pub struct Substitution {
    pub parts: Vec<SubstitutionPart>,
}

#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
pub struct SubstitutionPart {
    pub span: Span,
    pub snippet: String,
}

#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
pub struct TrimmedSubstitutionPart {
    pub original_span: Span,
    pub span: Span,
    pub snippet: String,
}

impl TrimmedSubstitutionPart {
    pub fn is_addition(&self, sm: &SourceMap) -> bool {
        !self.snippet.is_empty() && !self.replaces_meaningful_content(sm)
    }

    pub fn is_deletion(&self, sm: &SourceMap) -> bool {
        self.snippet.trim().is_empty() && self.replaces_meaningful_content(sm)
    }

    pub fn is_replacement(&self, sm: &SourceMap) -> bool {
        !self.snippet.is_empty() && self.replaces_meaningful_content(sm)
    }

    /// Whether this is a replacement that overwrites source with a snippet
    /// in a way that isn't a superset of the original string. For example,
    /// replacing "abc" with "abcde" is not destructive, but replacing it
    /// it with "abx" is, since the "c" character is lost.
    pub fn is_destructive_replacement(&self, sm: &SourceMap) -> bool {
        self.is_replacement(sm)
            && !sm
                .span_to_snippet(self.span)
                .is_ok_and(|snippet| as_substr(snippet.trim(), self.snippet.trim()).is_some())
    }

    fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool {
        sm.span_to_snippet(self.span)
            .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty())
    }
}

/// Given an original string like `AACC`, and a suggestion like `AABBCC`, try to detect
/// the case where a substring of the suggestion is "sandwiched" in the original, like
/// `BB` is. Return the length of the prefix, the "trimmed" suggestion, and the length
/// of the suffix.
fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a str, usize)> {
    let common_prefix = original
        .chars()
        .zip(suggestion.chars())
        .take_while(|(c1, c2)| c1 == c2)
        .map(|(c, _)| c.len_utf8())
        .sum();
    let original = &original[common_prefix..];
    let suggestion = &suggestion[common_prefix..];
    if suggestion.ends_with(original) {
        let common_suffix = original.len();
        Some((common_prefix, &suggestion[..suggestion.len() - original.len()], common_suffix))
    } else {
        None
    }
}

/// Signifies that the compiler died with an explicit call to `.bug`
/// or `.span_bug` rather than a failed assertion, etc.
pub struct ExplicitBug;

/// Signifies that the compiler died due to a delayed bug rather than a failed
/// assertion, etc.
pub struct DelayedBugPanic;

/// A `DiagCtxt` deals with errors and other compiler output.
/// Certain errors (fatal, bug, unimpl) may cause immediate exit,
/// others log errors for later reporting.
pub struct DiagCtxt {
    inner: Lock<DiagCtxtInner>,
}

#[derive(Copy, Clone)]
pub struct DiagCtxtHandle<'a> {
    dcx: &'a DiagCtxt,
    /// Some contexts create `DiagCtxtHandle` with this field set, and thus all
    /// errors emitted with it will automatically taint when emitting errors.
    tainted_with_errors: Option<&'a Cell<Option<ErrorGuaranteed>>>,
}

impl<'a> std::ops::Deref for DiagCtxtHandle<'a> {
    type Target = &'a DiagCtxt;

    fn deref(&self) -> &Self::Target {
        &self.dcx
    }
}

/// This inner struct exists to keep it all behind a single lock;
/// this is done to prevent possible deadlocks in a multi-threaded compiler,
/// as well as inconsistent state observation.
struct DiagCtxtInner {
    flags: DiagCtxtFlags,

    /// The error guarantees from all emitted errors, each paired with the
    /// thread that emitted it. The length gives the error count.
    err_guars: Vec<(ErrorGuaranteed, ThreadId)>,
    /// The error guarantee from all emitted lint errors, each paired with the
    /// thread that emitted it. The length gives the lint error count.
    lint_err_guars: Vec<(ErrorGuaranteed, ThreadId)>,
    /// The delayed bugs and their error guarantees.
    delayed_bugs: Vec<(DelayedDiagInner, ErrorGuaranteed)>,

    /// The error count shown to the user at the end.
    deduplicated_err_count: usize,
    /// The warning count shown to the user at the end.
    deduplicated_warn_count: usize,

    emitter: Box<DynEmitter>,

    /// Must we produce a diagnostic to justify the use of the expensive
    /// `trimmed_def_paths` function? Backtrace is the location of the call.
    must_produce_diag: Option<Backtrace>,

    /// Has this diagnostic context printed any diagnostics? (I.e. has
    /// `self.emitter.emit_diagnostic()` been called?
    has_printed: bool,

    /// This flag indicates that an expected diagnostic was emitted and suppressed.
    /// This is used for the `must_produce_diag` check.
    suppressed_expected_diag: bool,

    /// This set contains the code of all emitted diagnostics to avoid
    /// emitting the same diagnostic with extended help (`--teach`) twice, which
    /// would be unnecessary repetition.
    taught_diagnostics: FxHashSet<ErrCode>,

    /// Used to suggest rustc --explain `<error code>`
    emitted_diagnostic_codes: FxIndexSet<ErrCode>,

    /// This set contains a hash of every diagnostic that has been emitted by
    /// this `DiagCtxt`. These hashes is used to avoid emitting the same error
    /// twice.
    emitted_diagnostics: FxHashSet<Hash128>,

    /// We only want to emit `recursion_depth_exceeding_limit` once per
    /// crate. Otherwise crates like `calimero-store` emit more than
    /// a thousand warnings.
    ///
    /// We only check this in `TRACK_DIAGNOSTIC` meaning that the diagnostics
    /// still get tracked by the query system, even if they don't get emitted
    /// to users.
    emitted_recursion_depth_exceeding_limit: bool,

    /// Stashed diagnostics emitted in one stage of the compiler that may be
    /// stolen and emitted/cancelled by other stages (e.g. to improve them and
    /// add more information). All stashed diagnostics must be emitted with
    /// `emit_stashed_diagnostics` by the time the `DiagCtxtInner` is dropped,
    /// otherwise an assertion failure will occur.
    stashed_diagnostics:
        FxIndexMap<StashKey, FxIndexMap<Span, (DiagInner, Option<ErrorGuaranteed>, ThreadId)>>,

    future_breakage_diagnostics: Vec<DiagInner>,

    /// expected diagnostic will have the level `Expect` which additionally
    /// carries the [`LintExpectationId`] of the expectation that can be
    /// marked as fulfilled. This is a collection of all [`LintExpectationId`]s
    /// that have been marked as fulfilled this way.
    ///
    /// Emitting expectations after having stolen this field can happen. In particular, an
    /// `#[expect(warnings)]` can easily make the `UNFULFILLED_LINT_EXPECTATIONS` lint expect
    /// itself. To avoid needless complexity in this corner case, we tolerate failing to track
    /// those expectations.
    ///
    /// [RFC-2383]: https://rust-lang.github.io/rfcs/2383-lint-reasons.html
    fulfilled_expectations: FxIndexSet<LintExpectationId>,

    /// The file where the ICE information is stored. This allows delayed_span_bug backtraces to be
    /// stored along side the main panic backtrace.
    ice_file: Option<PathBuf>,

    /// Controlled by `-Z hint-msrv`; this allows avoiding emitting lints which would raise MSRV.
    msrv: Option<RustcVersion>,
}

/// A key denoting where from a diagnostic was stashed.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum StashKey {
    ItemNoType,
    UnderscoreForArrayLengths,
    EarlySyntaxWarning,
    CallIntoMethod,
    /// When an invalid lifetime e.g. `'2` should be reinterpreted
    /// as a char literal in the parser
    LifetimeIsChar,
    /// Maybe there was a typo where a comma was forgotten before
    /// FRU syntax
    MaybeFruTypo,
    CallAssocMethod,
    AssociatedTypeSuggestion,
    UndeterminedMacroResolution,
    /// Used by `Parser::maybe_recover_trailing_expr`
    ExprInPat,
    /// If in the parser we detect a field expr with turbofish generic params it's possible that
    /// it's a method call without parens. If later on in `hir_typeck` we find out that this is
    /// the case we suppress this message and we give a better suggestion.
    GenericInFieldExpr,
    ReturnTypeNotation,
}

fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
    (*f)(diag)
}

/// Diagnostics emitted by `DiagCtxtInner::emit_diagnostic` are passed through this function. Used
/// for tracking by incremental, to replay diagnostics as necessary.
pub static TRACK_DIAGNOSTIC: AtomicRef<
    fn(DiagInner, &mut dyn FnMut(DiagInner) -> Option<ErrorGuaranteed>) -> Option<ErrorGuaranteed>,
> = AtomicRef::new(&(default_track_diagnostic as _));

#[derive(Copy, Clone, Default)]
pub struct DiagCtxtFlags {
    /// If false, warning-level lints are suppressed.
    /// (rustc: see `--allow warnings` and `--cap-lints`)
    pub can_emit_warnings: bool,
    /// If Some, the Nth error-level diagnostic is upgraded to bug-level.
    /// (rustc: see `-Z treat-err-as-bug`)
    pub treat_err_as_bug: Option<NonZero<usize>>,
    /// Eagerly emit delayed bugs as errors, so that the compiler debugger may
    /// see all of the errors being emitted at once.
    pub eagerly_emit_delayed_bugs: bool,
    /// Show macro backtraces.
    /// (rustc: see `-Z macro-backtrace`)
    pub macro_backtrace: bool,
    /// If true, identical diagnostics are reported only once.
    pub deduplicate_diagnostics: bool,
    /// Track where errors are created. Enabled with `-Ztrack-diagnostics`.
    pub track_diagnostics: bool,
}

impl Drop for DiagCtxtInner {
    fn drop(&mut self) {
        // For tools using `interface::run_compiler` (e.g. rustc, rustdoc)
        // stashed diagnostics will have already been emitted. But for others
        // that don't use `interface::run_compiler` (e.g. rustfmt, some clippy
        // lints) this fallback is necessary.
        //
        // Important: it is sound to produce an `ErrorGuaranteed` when stashing
        // errors because they are guaranteed to be emitted here or earlier.
        self.emit_stashed_diagnostics();

        // Important: it is sound to produce an `ErrorGuaranteed` when emitting
        // delayed bugs because they are guaranteed to be emitted here if
        // necessary.
        self.flush_delayed();

        // Sanity check: did we use some of the expensive `trimmed_def_paths` functions
        // unexpectedly, that is, without producing diagnostics? If so, for debugging purposes, we
        // suggest where this happened and how to avoid it.
        if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() {
            if let Some(backtrace) = &self.must_produce_diag {
                let suggestion = match backtrace.status() {
                    BacktraceStatus::Disabled => String::from(
                        "Backtraces are currently disabled: set `RUST_BACKTRACE=1` and re-run \
                        to see where it happened.",
                    ),
                    BacktraceStatus::Captured => format!(
                        "This happened in the following `must_produce_diag` call's backtrace:\n\
                        {backtrace}",
                    ),
                    _ => String::from("(impossible to capture backtrace where this happened)"),
                };
                panic!(
                    "`trimmed_def_paths` called, diagnostics were expected but none were emitted. \
                    Use `with_no_trimmed_paths` for debugging. {suggestion}"
                );
            }
        }
    }
}

impl DiagCtxt {
    pub fn disable_warnings(mut self) -> Self {
        self.inner.get_mut().flags.can_emit_warnings = false;
        self
    }

    pub fn with_flags(mut self, flags: DiagCtxtFlags) -> Self {
        self.inner.get_mut().flags = flags;
        self
    }

    pub fn with_ice_file(mut self, ice_file: PathBuf) -> Self {
        self.inner.get_mut().ice_file = Some(ice_file);
        self
    }

    pub fn with_msrv(mut self, msrv: RustcVersion) -> Self {
        self.inner.get_mut().msrv = Some(msrv);
        self
    }

    pub fn new(emitter: Box<DynEmitter>) -> Self {
        Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
    }

    pub fn make_silent(&self) {
        let mut inner = self.inner.borrow_mut();
        inner.emitter = Box::new(emitter::SilentEmitter {});
    }

    pub fn set_emitter(&self, emitter: Box<dyn Emitter + DynSend>) {
        self.inner.borrow_mut().emitter = emitter;
    }

    // This is here to not allow mutation of flags;
    // as of this writing it's used in Session::consider_optimizing and
    // in tests in rustc_interface.
    pub fn can_emit_warnings(&self) -> bool {
        self.inner.borrow_mut().flags.can_emit_warnings
    }

    /// Resets the diagnostic error count as well as the cached emitted diagnostics.
    ///
    /// NOTE: *do not* call this function from rustc. It is only meant to be called from external
    /// tools that want to reuse a `Parser` cleaning the previously emitted diagnostics as well as
    /// the overall count of emitted error diagnostics.
    pub fn reset_err_count(&self) {
        // Use destructuring so that if a field gets added to `DiagCtxtInner`, it's impossible to
        // fail to update this method as well.
        let mut inner = self.inner.borrow_mut();
        let DiagCtxtInner {
            flags: _,
            err_guars,
            lint_err_guars,
            delayed_bugs,
            deduplicated_err_count,
            deduplicated_warn_count,
            emitter: _,
            must_produce_diag,
            has_printed,
            suppressed_expected_diag,
            taught_diagnostics,
            emitted_diagnostic_codes,
            emitted_diagnostics,
            emitted_recursion_depth_exceeding_limit,
            stashed_diagnostics,
            future_breakage_diagnostics,
            fulfilled_expectations,
            ice_file: _,
            msrv: _,
        } = inner.deref_mut();

        // For the `Vec`s and `HashMap`s, we overwrite with an empty container to free the
        // underlying memory (which `clear` would not do).
        *err_guars = Default::default();
        *lint_err_guars = Default::default();
        *delayed_bugs = Default::default();
        *deduplicated_err_count = 0;
        *deduplicated_warn_count = 0;
        *must_produce_diag = None;
        *has_printed = false;
        *suppressed_expected_diag = false;
        *taught_diagnostics = Default::default();
        *emitted_diagnostic_codes = Default::default();
        *emitted_diagnostics = Default::default();
        *emitted_recursion_depth_exceeding_limit = false;
        *stashed_diagnostics = Default::default();
        *future_breakage_diagnostics = Default::default();
        *fulfilled_expectations = Default::default();
    }

    pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> {
        DiagCtxtHandle { dcx: self, tainted_with_errors: None }
    }

    /// Link this to a taintable context so that emitting errors will automatically set
    /// the `Option<ErrorGuaranteed>` instead of having to do that manually at every error
    /// emission site.
    pub fn taintable_handle<'a>(
        &'a self,
        tainted_with_errors: &'a Cell<Option<ErrorGuaranteed>>,
    ) -> DiagCtxtHandle<'a> {
        DiagCtxtHandle { dcx: self, tainted_with_errors: Some(tainted_with_errors) }
    }
}

impl<'a> DiagCtxtHandle<'a> {
    /// Stashes a diagnostic for possible later improvement in a different,
    /// later stage of the compiler. Possible actions depend on the diagnostic
    /// level:
    /// - Level::Bug, Level:Fatal: not allowed, will trigger a panic.
    /// - Level::Error: immediately counted as an error that has occurred, because it
    ///   is guaranteed to be emitted eventually. Can be later accessed with the
    ///   provided `span` and `key` through
    ///   [`DiagCtxtHandle::try_steal_modify_and_emit_err`] or
    ///   [`DiagCtxtHandle::try_steal_replace_and_emit_err`]. These do not allow
    ///   cancellation or downgrading of the error. Returns
    ///   `Some(ErrorGuaranteed)`.
    /// - Level::DelayedBug: this does happen occasionally with errors that are
    ///   downgraded to delayed bugs. It is not stashed, but immediately
    ///   emitted as a delayed bug. This is because stashing it would cause it
    ///   to be counted by `err_count` which we don't want. It doesn't matter
    ///   that we cannot steal and improve it later, because it's not a
    ///   user-facing error. Returns `Some(ErrorGuaranteed)` as is normal for
    ///   delayed bugs.
    /// - Level::Warning and lower (i.e. !is_error()): can be accessed with the
    ///   provided `span` and `key` through [`DiagCtxtHandle::steal_non_err()`]. This
    ///   allows cancelling and downgrading of the diagnostic. Returns `None`.
    pub fn stash_diagnostic(
        &self,
        span: Span,
        key: StashKey,
        diag: DiagInner,
    ) -> Option<ErrorGuaranteed> {
        let guar = match diag.level {
            Bug | Fatal => {
                self.span_bug(
                    span,
                    format!("invalid level in `stash_diagnostic`: {:?}", diag.level),
                );
            }
            // We delay a bug here so that `-Ztreat-err-as-bug -Zeagerly-emit-delayed-bugs`
            // can be used to create a backtrace at the stashing site instead of whenever the
            // diagnostic context is dropped and thus delayed bugs are emitted.
            Error => Some(self.span_delayed_bug(span, format!("stashing {key:?}"))),
            DelayedBug => {
                return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors);
            }
            ForceWarning | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
            | Expect => None,
        };

        // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
        // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
        // See the PR for a discussion.
        self.inner
            .borrow_mut()
            .stashed_diagnostics
            .entry(key)
            .or_default()
            .insert(span.with_parent(None), (diag, guar, std::thread::current().id()));

        guar
    }

    /// Steal a previously stashed non-error diagnostic with the given `Span`
    /// and [`StashKey`] as the key. Panics if the found diagnostic is an
    /// error.
    pub fn steal_non_err(self, span: Span, key: StashKey) -> Option<Diag<'a, ()>> {
        // FIXME(#120456) - is `swap_remove` correct?
        let (diag, guar, _) = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
            |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
        )?;
        assert!(!diag.is_error());
        assert!(guar.is_none());
        Some(Diag::new_diagnostic(self, diag))
    }

    /// Steals a previously stashed error with the given `Span` and
    /// [`StashKey`] as the key, modifies it, and emits it. Returns `None` if
    /// no matching diagnostic is found. Panics if the found diagnostic's level
    /// isn't `Level::Error`.
    pub fn try_steal_modify_and_emit_err<F>(
        self,
        span: Span,
        key: StashKey,
        mut modify_err: F,
    ) -> Option<ErrorGuaranteed>
    where
        F: FnMut(&mut Diag<'_>),
    {
        // FIXME(#120456) - is `swap_remove` correct?
        let err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
            |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
        );
        err.map(|(err, guar, _)| {
            // The use of `::<ErrorGuaranteed>` is safe because level is `Level::Error`.
            assert_eq!(err.level, Error);
            assert!(guar.is_some());
            let mut err = Diag::<ErrorGuaranteed>::new_diagnostic(self, err);
            modify_err(&mut err);
            assert_eq!(err.level, Error);
            err.emit()
        })
    }

    /// Steals a previously stashed error with the given `Span` and
    /// [`StashKey`] as the key, cancels it if found, and emits `new_err`.
    /// Panics if the found diagnostic's level isn't `Level::Error`.
    pub fn try_steal_replace_and_emit_err(
        self,
        span: Span,
        key: StashKey,
        new_err: Diag<'_>,
    ) -> ErrorGuaranteed {
        // FIXME(#120456) - is `swap_remove` correct?
        let old_err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
            |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
        );
        match old_err {
            Some((old_err, guar, _)) => {
                assert_eq!(old_err.level, Error);
                assert!(guar.is_some());
                // Because `old_err` has already been counted, it can only be
                // safely cancelled because the `new_err` supplants it.
                Diag::<ErrorGuaranteed>::new_diagnostic(self, old_err).cancel();
            }
            None => {}
        };
        new_err.emit()
    }

    pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool {
        let inner = self.inner.borrow();
        if let Some(stashed_diagnostics) = inner.stashed_diagnostics.get(&key)
            && !stashed_diagnostics.is_empty()
        {
            stashed_diagnostics.contains_key(&span.with_parent(None))
        } else {
            false
        }
    }

    /// Emit all stashed diagnostics.
    pub fn emit_stashed_diagnostics(&self) -> Option<ErrorGuaranteed> {
        self.inner.borrow_mut().emit_stashed_diagnostics()
    }

    /// This excludes delayed bugs.
    #[inline]
    pub fn err_count(&self) -> usize {
        let inner = self.inner.borrow();
        inner.err_guars.len()
            + inner.lint_err_guars.len()
            + inner
                .stashed_diagnostics
                .values()
                .map(|a| a.values().filter(|(_, guar, _)| guar.is_some()).count())
                .sum::<usize>()
    }

    /// The number of errors that have been emitted on the *current thread*.
    ///
    /// Like [`DiagCtxtHandle::err_count`], but only counts errors whose recorded
    /// emitting thread is the calling thread.
    pub fn err_count_on_current_thread(&self) -> usize {
        let inner = self.inner.borrow();
        let current = std::thread::current().id();
        inner.err_guars.iter().filter(|(_, thread)| *thread == current).count()
            + inner.lint_err_guars.iter().filter(|(_, thread)| *thread == current).count()
            + inner
                .stashed_diagnostics
                .values()
                .map(|a| {
                    a.values()
                        .filter(|(_, guar, thread)| guar.is_some() && *thread == current)
                        .count()
                })
                .sum::<usize>()
    }

    /// This excludes lint errors and delayed bugs. Unless absolutely
    /// necessary, prefer `has_errors` to this method.
    pub fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
        self.inner.borrow().has_errors_excluding_lint_errors()
    }

    /// This excludes delayed bugs.
    pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
        self.inner.borrow().has_errors()
    }

    /// This excludes nothing. Unless absolutely necessary, prefer `has_errors`
    /// to this method.
    pub fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
        self.inner.borrow().has_errors_or_delayed_bugs()
    }

    pub fn print_error_count(&self) {
        let mut inner = self.inner.borrow_mut();

        // Any stashed diagnostics should have been handled by
        // `emit_stashed_diagnostics` by now.
        assert!(inner.stashed_diagnostics.is_empty());

        if inner.treat_err_as_bug() {
            return;
        }

        let warnings = match inner.deduplicated_warn_count {
            0 => Cow::from(""),
            1 => Cow::from("1 warning emitted"),
            count => Cow::from(format!("{count} warnings emitted")),
        };
        let errors = match inner.deduplicated_err_count {
            0 => Cow::from(""),
            1 => Cow::from("aborting due to 1 previous error"),
            count => Cow::from(format!("aborting due to {count} previous errors")),
        };

        match (errors.len(), warnings.len()) {
            (0, 0) => return,
            (0, _) => {
                // Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a
                // configuration like `--cap-lints allow --force-warn bare_trait_objects`.
                inner.emit_diagnostic(
                    DiagInner::new(ForceWarning, DiagMessage::Str(warnings)),
                    None,
                );
            }
            (_, 0) => {
                inner.emit_diagnostic(DiagInner::new(Error, errors), self.tainted_with_errors);
            }
            (_, _) => {
                inner.emit_diagnostic(
                    DiagInner::new(Error, format!("{errors}; {warnings}")),
                    self.tainted_with_errors,
                );
            }
        }

        let can_show_explain = inner.emitter.should_show_explain();
        let are_there_diagnostics = !inner.emitted_diagnostic_codes.is_empty();
        if can_show_explain && are_there_diagnostics {
            let mut error_codes = inner
                .emitted_diagnostic_codes
                .iter()
                .filter_map(|&code| {
                    if crate::codes::try_find_description(code).is_ok() {
                        Some(code.to_string())
                    } else {
                        None
                    }
                })
                .collect::<Vec<_>>();
            if !error_codes.is_empty() {
                error_codes.sort();
                if error_codes.len() > 1 {
                    let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
                    let msg1 = format!(
                        "Some errors have detailed explanations: {}{}",
                        error_codes[..limit].join(", "),
                        if error_codes.len() > 9 { "..." } else { "." }
                    );
                    let msg2 = format!(
                        "For more information about an error, try `rustc --explain {}`.",
                        &error_codes[0]
                    );
                    inner.emit_diagnostic(DiagInner::new(FailureNote, msg1), None);
                    inner.emit_diagnostic(DiagInner::new(FailureNote, msg2), None);
                } else {
                    let msg = format!(
                        "For more information about this error, try `rustc --explain {}`.",
                        &error_codes[0]
                    );
                    inner.emit_diagnostic(DiagInner::new(FailureNote, msg), None);
                }
            }
        }
    }

    /// This excludes delayed bugs. Used for early aborts after errors occurred
    /// -- e.g. because continuing in the face of errors is likely to lead to
    /// bad results, such as spurious/uninteresting additional errors -- when
    /// returning an error `Result` is difficult.
    pub fn abort_if_errors(&self) {
        if let Some(guar) = self.has_errors() {
            guar.raise_fatal();
        }
    }

    /// `true` if we haven't taught a diagnostic with this code already.
    /// The caller must then teach the user about such a diagnostic.
    ///
    /// Used to suppress emitting the same error multiple times with extended explanation when
    /// calling `-Zteach`.
    pub fn must_teach(&self, code: ErrCode) -> bool {
        self.inner.borrow_mut().taught_diagnostics.insert(code)
    }

    pub fn emit_diagnostic(&self, diagnostic: DiagInner) -> Option<ErrorGuaranteed> {
        self.inner.borrow_mut().emit_diagnostic(diagnostic, self.tainted_with_errors)
    }

    pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
        self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type);
    }

    pub fn emit_timing_section_start(&self, record: TimingRecord) {
        self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::Start);
    }

    pub fn emit_timing_section_end(&self, record: TimingRecord) {
        self.inner.borrow_mut().emitter.emit_timing_section(record, TimingEvent::End);
    }

    pub fn emit_future_breakage_report(&self) {
        let inner = &mut *self.inner.borrow_mut();
        let diags = mem::take(&mut inner.future_breakage_diagnostics);
        if !diags.is_empty() {
            inner.emitter.emit_future_breakage_report(diags);
        }
    }

    pub fn emit_unused_externs(
        &self,
        lint_level: rustc_lint_defs::Level,
        loud: bool,
        unused_externs: &[&str],
    ) {
        let mut inner = self.inner.borrow_mut();

        // This "error" is an odd duck.
        // - It's only produce with JSON output.
        // - It's not emitted the usual way, via `emit_diagnostic`.
        // - The `$message_type` field is "unused_externs" rather than the usual
        //   "diagnostic".
        //
        // We count it as a lint error because it has a lint level. The value
        // of `loud` (which comes from "unused-externs" or
        // "unused-externs-silent"), also affects whether it's treated like a
        // hard error or not.
        if loud && lint_level.is_error() {
            // This `unchecked_error_guaranteed` is valid. It is where the
            // `ErrorGuaranteed` for unused_extern errors originates.
            #[allow(deprecated)]
            let guar = ErrorGuaranteed::unchecked_error_guaranteed();
            inner.lint_err_guars.push((guar, std::thread::current().id()));
            inner.panic_if_treat_err_as_bug();
        }

        inner.emitter.emit_unused_externs(lint_level, unused_externs)
    }

    /// This methods steals all [`LintExpectationId`]s that are stored inside
    /// [`DiagCtxtInner`] and indicate that the linked expectation has been fulfilled.
    #[must_use]
    pub fn steal_fulfilled_expectation_ids(&self) -> FxIndexSet<LintExpectationId> {
        mem::take(&mut self.inner.borrow_mut().fulfilled_expectations)
    }

    /// Trigger an ICE if there are any delayed bugs and no hard errors.
    ///
    /// This will panic if there are any stashed diagnostics. You can call
    /// `emit_stashed_diagnostics` to emit those before calling `flush_delayed`.
    pub fn flush_delayed(&self) {
        self.inner.borrow_mut().flush_delayed();
    }

    /// Used when trimmed_def_paths is called and we must produce a diagnostic
    /// to justify its cost.
    #[track_caller]
    pub fn set_must_produce_diag(&self) {
        assert!(
            self.inner.borrow().must_produce_diag.is_none(),
            "should only need to collect a backtrace once"
        );
        self.inner.borrow_mut().must_produce_diag = Some(Backtrace::capture());
    }
}

// This `impl` block contains only the public diagnostic creation/emission API.
//
// Functions beginning with `struct_`/`create_` create a diagnostic. Other
// functions create and emit a diagnostic all in one go.
impl<'a> DiagCtxtHandle<'a> {
    #[track_caller]
    pub fn struct_bug(self, msg: impl Into<Cow<'static, str>>) -> Diag<'a, BugAbort> {
        Diag::new(self, Bug, msg.into())
    }

    #[track_caller]
    pub fn bug(self, msg: impl Into<Cow<'static, str>>) -> ! {
        self.struct_bug(msg).emit()
    }

    #[track_caller]
    pub fn struct_span_bug(
        self,
        span: impl Into<MultiSpan>,
        msg: impl Into<Cow<'static, str>>,
    ) -> Diag<'a, BugAbort> {
        self.struct_bug(msg).with_span(span)
    }

    #[track_caller]
    pub fn span_bug(self, span: impl Into<MultiSpan>, msg: impl Into<Cow<'static, str>>) -> ! {
        self.struct_span_bug(span, msg.into()).emit()
    }

    #[track_caller]
    pub fn create_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> Diag<'a, BugAbort> {
        bug.into_diag(self, Bug)
    }

    #[track_caller]
    pub fn emit_bug(self, bug: impl Diagnostic<'a, BugAbort>) -> ! {
        self.create_bug(bug).emit()
    }

    #[track_caller]
    pub fn struct_fatal(self, msg: impl Into<DiagMessage>) -> Diag<'a, FatalAbort> {
        Diag::new(self, Fatal, msg)
    }

    #[track_caller]
    pub fn fatal(self, msg: impl Into<DiagMessage>) -> ! {
        self.struct_fatal(msg).emit()
    }

    #[track_caller]
    pub fn struct_span_fatal(
        self,
        span: impl Into<MultiSpan>,
        msg: impl Into<DiagMessage>,
    ) -> Diag<'a, FatalAbort> {
        self.struct_fatal(msg).with_span(span)
    }

    #[track_caller]
    pub fn span_fatal(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) -> ! {
        self.struct_span_fatal(span, msg).emit()
    }

    #[track_caller]
    pub fn create_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> Diag<'a, FatalAbort> {
        fatal.into_diag(self, Fatal)
    }

    #[track_caller]
    pub fn emit_fatal(self, fatal: impl Diagnostic<'a, FatalAbort>) -> ! {
        self.create_fatal(fatal).emit()
    }

    #[track_caller]
    pub fn create_almost_fatal(
        self,
        fatal: impl Diagnostic<'a, FatalError>,
    ) -> Diag<'a, FatalError> {
        fatal.into_diag(self, Fatal)
    }

    #[track_caller]
    pub fn emit_almost_fatal(self, fatal: impl Diagnostic<'a, FatalError>) -> FatalError {
        self.create_almost_fatal(fatal).emit()
    }

    // FIXME: This method should be removed (every error should have an associated error code).
    #[track_caller]
    pub fn struct_err(self, msg: impl Into<DiagMessage>) -> Diag<'a> {
        Diag::new(self, Error, msg)
    }

    #[track_caller]
    pub fn err(self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
        self.struct_err(msg).emit()
    }

    #[track_caller]
    pub fn struct_span_err(
        self,
        span: impl Into<MultiSpan>,
        msg: impl Into<DiagMessage>,
    ) -> Diag<'a> {
        self.struct_err(msg).with_span(span)
    }

    #[track_caller]
    pub fn span_err(
        self,
        span: impl Into<MultiSpan>,
        msg: impl Into<DiagMessage>,
    ) -> ErrorGuaranteed {
        self.struct_span_err(span, msg).emit()
    }

    #[track_caller]
    pub fn create_err(self, err: impl Diagnostic<'a>) -> Diag<'a> {
        err.into_diag(self, Error)
    }

    #[track_caller]
    pub fn emit_err(self, err: impl Diagnostic<'a>) -> ErrorGuaranteed {
        self.create_err(err).emit()
    }

    /// Ensures that an error is printed. See [`Level::DelayedBug`].
    #[track_caller]
    pub fn delayed_bug(self, msg: impl Into<Cow<'static, str>>) -> ErrorGuaranteed {
        Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).emit()
    }

    /// Ensures that an error is printed. See [`Level::DelayedBug`].
    ///
    /// Note: this function used to be called `delay_span_bug`. It was renamed
    /// to match similar functions like `span_err`, `span_warn`, etc.
    #[track_caller]
    pub fn span_delayed_bug(
        self,
        sp: impl Into<MultiSpan>,
        msg: impl Into<Cow<'static, str>>,
    ) -> ErrorGuaranteed {
        Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).with_span(sp).emit()
    }

    #[track_caller]
    pub fn struct_warn(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
        Diag::new(self, Warning, msg)
    }

    #[track_caller]
    pub fn warn(self, msg: impl Into<DiagMessage>) {
        self.struct_warn(msg).emit()
    }

    #[track_caller]
    pub fn struct_span_warn(
        self,
        span: impl Into<MultiSpan>,
        msg: impl Into<DiagMessage>,
    ) -> Diag<'a, ()> {
        self.struct_warn(msg).with_span(span)
    }

    #[track_caller]
    pub fn span_warn(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
        self.struct_span_warn(span, msg).emit()
    }

    #[track_caller]
    pub fn create_warn(self, warning: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
        warning.into_diag(self, Warning)
    }

    #[track_caller]
    pub fn emit_warn(self, warning: impl Diagnostic<'a, ()>) {
        self.create_warn(warning).emit()
    }

    #[track_caller]
    pub fn struct_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
        Diag::new(self, Note, msg)
    }

    #[track_caller]
    pub fn note(&self, msg: impl Into<DiagMessage>) {
        self.struct_note(msg).emit()
    }

    #[track_caller]
    pub fn struct_span_note(
        self,
        span: impl Into<MultiSpan>,
        msg: impl Into<DiagMessage>,
    ) -> Diag<'a, ()> {
        self.struct_note(msg).with_span(span)
    }

    #[track_caller]
    pub fn span_note(self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
        self.struct_span_note(span, msg).emit()
    }

    #[track_caller]
    pub fn create_note(self, note: impl Diagnostic<'a, ()>) -> Diag<'a, ()> {
        note.into_diag(self, Note)
    }

    #[track_caller]
    pub fn emit_note(self, note: impl Diagnostic<'a, ()>) {
        self.create_note(note).emit()
    }

    #[track_caller]
    pub fn struct_help(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
        Diag::new(self, Help, msg)
    }

    #[track_caller]
    pub fn struct_failure_note(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
        Diag::new(self, FailureNote, msg)
    }

    #[track_caller]
    pub fn struct_allow(self, msg: impl Into<DiagMessage>) -> Diag<'a, ()> {
        Diag::new(self, Allow, msg)
    }

    #[track_caller]
    pub fn struct_expect(self, msg: impl Into<DiagMessage>, id: LintExpectationId) -> Diag<'a, ()> {
        Diag::new(self, Expect, msg).with_lint_id(id)
    }
}

// Note: we prefer implementing operations on `DiagCtxt`, rather than
// `DiagCtxtInner`, whenever possible. This minimizes functions where
// `DiagCtxt::foo()` just borrows `inner` and forwards a call to
// `DiagCtxtInner::foo`.
impl DiagCtxtInner {
    fn new(emitter: Box<DynEmitter>) -> Self {
        Self {
            flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
            err_guars: Vec::new(),
            lint_err_guars: Vec::new(),
            delayed_bugs: Vec::new(),
            deduplicated_err_count: 0,
            deduplicated_warn_count: 0,
            emitter,
            must_produce_diag: None,
            has_printed: false,
            suppressed_expected_diag: false,
            taught_diagnostics: Default::default(),
            emitted_diagnostic_codes: Default::default(),
            emitted_diagnostics: Default::default(),
            emitted_recursion_depth_exceeding_limit: false,
            stashed_diagnostics: Default::default(),
            future_breakage_diagnostics: Vec::new(),
            fulfilled_expectations: Default::default(),
            ice_file: None,
            msrv: None,
        }
    }

    /// Emit all stashed diagnostics.
    fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
        let mut guar = None;
        let has_errors = !self.err_guars.is_empty();
        for (_, stashed_diagnostics) in mem::take(&mut self.stashed_diagnostics).into_iter() {
            for (_, (diag, _guar, _thread)) in stashed_diagnostics {
                if !diag.is_error() {
                    // Unless they're forced, don't flush stashed warnings when
                    // there are errors, to avoid causing warning overload. The
                    // stash would've been stolen already if it were important.
                    if !diag.is_force_warn() && has_errors {
                        continue;
                    }
                }
                guar = guar.or(self.emit_diagnostic(diag, None));
            }
        }
        guar
    }

    // Return value is only `Some` if the level is `Error` or `DelayedBug`.
    fn emit_diagnostic(
        &mut self,
        mut diagnostic: DiagInner,
        taint: Option<&Cell<Option<ErrorGuaranteed>>>,
    ) -> Option<ErrorGuaranteed> {
        if diagnostic.has_future_breakage() {
            // Future breakages aren't emitted if they're `Level::Allow` or
            // `Level::Expect`, but they still need to be constructed and
            // stashed below, so they'll trigger the must_produce_diag check.
            assert_matches!(diagnostic.level, Error | ForceWarning | Warning | Allow | Expect);
            self.future_breakage_diagnostics.push(diagnostic.clone());
        }

        // We call TRACK_DIAGNOSTIC with an empty closure for the cases that
        // return early *and* have some kind of side-effect, except where
        // noted.
        match diagnostic.level {
            Bug => {}
            Fatal | Error => {
                if self.treat_next_err_as_bug() {
                    // `Fatal` and `Error` can be promoted to `Bug`.
                    diagnostic.level = Bug;
                }
            }
            DelayedBug => {
                // Note that because we check these conditions first,
                // `-Zeagerly-emit-delayed-bugs` and `-Ztreat-err-as-bug`
                // continue to work even after we've issued an error and
                // stopped recording new delayed bugs.
                if self.flags.eagerly_emit_delayed_bugs {
                    // `DelayedBug` can be promoted to `Error` or `Bug`.
                    if self.treat_next_err_as_bug() {
                        diagnostic.level = Bug;
                    } else {
                        diagnostic.level = Error;
                    }
                } else {
                    // If we have already emitted at least one error, we don't need
                    // to record the delayed bug, because it'll never be used.
                    return if let Some(guar) = self.has_errors() {
                        Some(guar)
                    } else {
                        // No `TRACK_DIAGNOSTIC` call is needed, because the
                        // incremental session is deleted if there is a delayed
                        // bug. This also saves us from cloning the diagnostic.
                        let backtrace = std::backtrace::Backtrace::capture();
                        // This `unchecked_error_guaranteed` is valid. It is where the
                        // `ErrorGuaranteed` for delayed bugs originates. See
                        // `DiagCtxtInner::drop`.
                        #[allow(deprecated)]
                        let guar = ErrorGuaranteed::unchecked_error_guaranteed();
                        self.delayed_bugs
                            .push((DelayedDiagInner::with_backtrace(diagnostic, backtrace), guar));
                        Some(guar)
                    };
                }
            }
            ForceWarning if diagnostic.lint_id.is_none() => {} // `ForceWarning(Some(...))` is below, with `Expect`
            Warning => {
                if !self.flags.can_emit_warnings {
                    // We are not emitting warnings.
                    if diagnostic.has_future_breakage() {
                        // The side-effect is at the top of this method.
                        TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
                    }
                    return None;
                }
            }
            Note | Help | FailureNote => {}
            OnceNote | OnceHelp => panic!("bad level: {:?}", diagnostic.level),
            Allow => {
                // Nothing emitted for allowed lints.
                if diagnostic.has_future_breakage() {
                    // The side-effect is at the top of this method.
                    TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
                    self.suppressed_expected_diag = true;
                }
                return None;
            }
            Expect | ForceWarning => {
                self.fulfilled_expectations.insert(diagnostic.lint_id.unwrap());
                if let Expect = diagnostic.level {
                    // Nothing emitted here for expected lints.
                    TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
                    self.suppressed_expected_diag = true;
                    return None;
                }
            }
        }

        if let (Some(msrv), Some(diag_msrv)) = (self.msrv, diagnostic.rust_version())
            && diag_msrv > msrv
        {
            return None;
        }

        TRACK_DIAGNOSTIC(diagnostic, &mut |mut diagnostic| {
            if let Some(code) = diagnostic.code {
                self.emitted_diagnostic_codes.insert(code);
            }

            let already_emitted = {
                let mut hasher = StableHasher::new();
                diagnostic.hash(&mut hasher);
                let diagnostic_hash = hasher.finish();
                !self.emitted_diagnostics.insert(diagnostic_hash)
            };

            let is_error = diagnostic.is_error();
            let is_lint = diagnostic.is_lint.is_some();
            // We only emit the first occurrence of `recursion_depth_exceeding_limit`.
            let silence_recursion_depth_exceeded_limit =
                diagnostic.is_lint.as_ref().is_some_and(|lint| {
                    lint.name.eq_ignore_ascii_case(
                        rustc_lint_defs::builtin::RECURSION_DEPTH_EXCEEDING_LIMIT.name,
                    ) && mem::replace(&mut self.emitted_recursion_depth_exceeding_limit, true)
                });

            // Only emit the diagnostic if we've been asked to deduplicate or
            // haven't already emitted an equivalent diagnostic.
            if !silence_recursion_depth_exceeded_limit
                && !(self.flags.deduplicate_diagnostics && already_emitted)
            {
                debug!(?diagnostic);
                debug!(?self.emitted_diagnostics);

                let not_yet_emitted = |sub: &mut Subdiag| {
                    debug!(?sub);
                    if sub.level != OnceNote && sub.level != OnceHelp {
                        return true;
                    }
                    let mut hasher = StableHasher::new();
                    sub.hash(&mut hasher);
                    let diagnostic_hash = hasher.finish();
                    debug!(?diagnostic_hash);
                    self.emitted_diagnostics.insert(diagnostic_hash)
                };
                diagnostic.children.retain_mut(not_yet_emitted);
                if already_emitted {
                    let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`";
                    diagnostic.sub(Note, msg, MultiSpan::new());
                }

                if is_error {
                    self.deduplicated_err_count += 1;
                } else if matches!(diagnostic.level, ForceWarning | Warning) {
                    self.deduplicated_warn_count += 1;
                }
                self.has_printed = true;

                self.emitter.emit_diagnostic(diagnostic);
            }

            if is_error {
                // If we have any delayed bugs recorded, we can discard them
                // because they won't be used. (This should only occur if there
                // have been no errors previously emitted, because we don't add
                // new delayed bugs once the first error is emitted.)
                if !self.delayed_bugs.is_empty() {
                    assert_eq!(self.lint_err_guars.len() + self.err_guars.len(), 0);
                    self.delayed_bugs.clear();
                    self.delayed_bugs.shrink_to_fit();
                }

                // This `unchecked_error_guaranteed` is valid. It is where the
                // `ErrorGuaranteed` for errors and lint errors originates.
                #[allow(deprecated)]
                let guar = ErrorGuaranteed::unchecked_error_guaranteed();
                let thread = std::thread::current().id();
                if is_lint {
                    self.lint_err_guars.push((guar, thread));
                } else {
                    if let Some(taint) = taint {
                        taint.set(Some(guar));
                    }
                    self.err_guars.push((guar, thread));
                }
                self.panic_if_treat_err_as_bug();
                Some(guar)
            } else {
                None
            }
        })
    }

    fn treat_err_as_bug(&self) -> bool {
        self.flags
            .treat_err_as_bug
            .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() >= c.get())
    }

    // Use this one before incrementing `err_count`.
    fn treat_next_err_as_bug(&self) -> bool {
        self.flags
            .treat_err_as_bug
            .is_some_and(|c| self.err_guars.len() + self.lint_err_guars.len() + 1 >= c.get())
    }

    fn has_errors_excluding_lint_errors(&self) -> Option<ErrorGuaranteed> {
        self.err_guars.get(0).map(|(guar, _)| *guar).or_else(|| {
            if let Some((_diag, guar, _)) = self
                .stashed_diagnostics
                .values()
                .flat_map(|stashed_diagnostics| stashed_diagnostics.values())
                .find(|(diag, guar, _)| guar.is_some() && diag.is_lint.is_none())
            {
                *guar
            } else {
                None
            }
        })
    }

    fn has_errors(&self) -> Option<ErrorGuaranteed> {
        self.err_guars
            .get(0)
            .map(|(guar, _)| *guar)
            .or_else(|| self.lint_err_guars.get(0).map(|(guar, _)| *guar))
            .or_else(|| {
                self.stashed_diagnostics.values().find_map(|stashed_diagnostics| {
                    stashed_diagnostics.values().find_map(|(_, guar, _)| *guar)
                })
            })
    }

    fn has_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
        self.has_errors().or_else(|| self.delayed_bugs.get(0).map(|(_, guar)| guar).copied())
    }

    fn flush_delayed(&mut self) {
        // Stashed diagnostics must be emitted before delayed bugs are flushed.
        // Otherwise, we might ICE prematurely when errors would have
        // eventually happened.
        assert!(self.stashed_diagnostics.is_empty());

        if !self.err_guars.is_empty() {
            // If an error happened already. We shouldn't expose delayed bugs.
            return;
        }

        if self.delayed_bugs.is_empty() {
            // Nothing to do.
            return;
        }

        let bugs: Vec<_> = mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect();

        let backtrace = std::env::var_os("RUST_BACKTRACE").as_deref() != Some(OsStr::new("0"));
        let decorate = backtrace || self.ice_file.is_none();
        let mut out = self
            .ice_file
            .as_ref()
            .and_then(|file| std::fs::File::options().create(true).append(true).open(file).ok());

        // Put the overall explanation before the `DelayedBug`s, to frame them
        // better (e.g. separate warnings from them). Also, use notes, which
        // don't count as errors, to avoid possibly triggering
        // `-Ztreat-err-as-bug`, which we don't want.
        let note1 = "no errors encountered even though delayed bugs were created";
        let note2 = "those delayed bugs will now be shown as internal compiler errors";
        self.emit_diagnostic(DiagInner::new(Note, note1), None);
        self.emit_diagnostic(DiagInner::new(Note, note2), None);

        for bug in bugs {
            if let Some(out) = &mut out {
                _ = write!(
                    out,
                    "delayed bug: {}\n{}\n",
                    bug.inner
                        .messages
                        .iter()
                        .filter_map(|(msg, _)| msg.as_str())
                        .collect::<String>(),
                    &bug.note
                );
            }

            let mut bug = if decorate { bug.decorate() } else { bug.inner };

            // "Undelay" the delayed bugs into plain bugs.
            if bug.level != DelayedBug {
                // NOTE(eddyb) not panicking here because we're already producing
                // an ICE, and the more information the merrier.
                //
                // We are at the `DiagInner`/`DiagCtxtInner` level rather than
                // the usual `Diag`/`DiagCtxt` level, so we must augment `bug`
                // in a lower-level fashion.
                let msg = msg!(
                    "`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"
                ).arg("level", bug.level).format();
                bug.sub(Note, msg, bug.span.primary_span().unwrap().into());
            }
            bug.level = Bug;

            self.emit_diagnostic(bug, None);
        }

        // Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.
        panic::panic_any(DelayedBugPanic);
    }

    fn panic_if_treat_err_as_bug(&self) {
        if self.treat_err_as_bug() {
            let n = self.flags.treat_err_as_bug.map(|c| c.get()).unwrap();
            assert_eq!(n, self.err_guars.len() + self.lint_err_guars.len());
            if n == 1 {
                panic!("aborting due to `-Z treat-err-as-bug=1`");
            } else {
                panic!("aborting after {n} errors due to `-Z treat-err-as-bug={n}`");
            }
        }
    }
}

struct DelayedDiagInner {
    inner: DiagInner,
    note: Backtrace,
}

impl DelayedDiagInner {
    fn with_backtrace(diagnostic: DiagInner, backtrace: Backtrace) -> Self {
        DelayedDiagInner { inner: diagnostic, note: backtrace }
    }

    fn decorate(self) -> DiagInner {
        // We are at the `DiagInner`/`DiagCtxtInner` level rather than the
        // usual `Diag`/`DiagCtxt` level, so we must construct `diag` in a
        // lower-level fashion.
        let mut diag = self.inner;
        let msg = match self.note.status() {
            BacktraceStatus::Captured => msg!(
                "delayed at {$emitted_at}
                {$note}"
            ),
            // Avoid the needless newline when no backtrace has been captured,
            // the display impl should just be a single line.
            _ => msg!("delayed at {$emitted_at} - {$note}"),
        }
        .arg("emitted_at", diag.emitted_at.clone())
        .arg("note", self.note)
        .format();
        diag.sub(Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into());
        diag
    }
}

/// | Level        | is_error | EmissionGuarantee            | Top-level | Sub | Used in lints?
/// | -----        | -------- | -----------------            | --------- | --- | --------------
/// | Bug          | yes      | BugAbort                     | yes       | -   | -
/// | Fatal        | yes      | FatalAbort/FatalError[^star] | yes       | -   | -
/// | Error        | yes      | ErrorGuaranteed              | yes       | -   | yes
/// | DelayedBug   | yes      | ErrorGuaranteed              | yes       | -   | -
/// | ForceWarning | -        | ()                           | yes       | -   | lint-only
/// | Warning      | -        | ()                           | yes       | yes | yes
/// | Note         | -        | ()                           | rare      | yes | -
/// | OnceNote     | -        | ()                           | -         | yes | lint-only
/// | Help         | -        | ()                           | rare      | yes | -
/// | OnceHelp     | -        | ()                           | -         | yes | lint-only
/// | FailureNote  | -        | ()                           | rare      | -   | -
/// | Allow        | -        | ()                           | yes       | -   | lint-only
/// | Expect       | -        | ()                           | yes       | -   | lint-only
///
/// [^star]: `FatalAbort` normally, `FatalError` in the non-aborting "almost fatal" case that is
///     occasionally used.
///
#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)]
pub enum Level {
    /// For bugs in the compiler. Manifests as an ICE (internal compiler error) panic.
    Bug,

    /// An error that causes an immediate abort. Used for things like configuration errors,
    /// internal overflows, some file operation errors.
    Fatal,

    /// An error in the code being compiled, which prevents compilation from finishing. This is the
    /// most common case.
    Error,

    /// This is a strange one: lets you register an error without emitting it. If compilation ends
    /// without any other errors occurring, this will be emitted as a bug. Otherwise, it will be
    /// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths
    /// that should only be reached when compiling erroneous code.
    DelayedBug,

    /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
    /// from finishing.
    ///
    /// Requires a [`LintExpectationId`] for expected lint diagnostics. In all other cases this
    /// should be `None`.
    ForceWarning,

    /// A warning about the code being compiled. Does not prevent compilation from finishing.
    /// Will be skipped if `can_emit_warnings` is false.
    Warning,

    /// A message giving additional context.
    Note,

    /// A note that is only emitted once.
    OnceNote,

    /// A message suggesting how to fix something.
    Help,

    /// A help that is only emitted once.
    OnceHelp,

    /// Similar to `Note`, but used in cases where compilation has failed. When printed for human
    /// consumption, it doesn't have any kind of `note:` label.
    FailureNote,

    /// Only used for lints.
    Allow,

    /// Only used for lints. Requires a [`LintExpectationId`] for silencing the lints.
    Expect,
}

impl fmt::Display for Level {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.to_str().fmt(f)
    }
}

impl Level {
    fn color(self) -> anstyle::Style {
        match self {
            Bug | Fatal | Error | DelayedBug => AnsiColor::BrightRed.on_default(),
            ForceWarning | Warning => {
                if cfg!(windows) {
                    AnsiColor::BrightYellow.on_default()
                } else {
                    AnsiColor::Yellow.on_default()
                }
            }
            Note | OnceNote => AnsiColor::BrightGreen.on_default(),
            Help | OnceHelp => AnsiColor::BrightCyan.on_default(),
            FailureNote => anstyle::Style::new(),
            Allow | Expect => unreachable!(),
        }
    }

    pub fn to_str(self) -> &'static str {
        match self {
            Bug | DelayedBug => "error: internal compiler error",
            Fatal | Error => "error",
            ForceWarning | Warning => "warning",
            Note | OnceNote => "note",
            Help | OnceHelp => "help",
            FailureNote => "failure-note",
            Allow | Expect => unreachable!(),
        }
    }

    pub fn is_failure_note(&self) -> bool {
        matches!(*self, FailureNote)
    }
}

impl IntoDiagArg for Level {
    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
        DiagArgValue::Str(Cow::from(self.to_string()))
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
pub enum Style {
    MainHeaderMsg,
    HeaderMsg,
    LineAndColumn,
    LineNumber,
    Quotation,
    UnderlinePrimary,
    UnderlineSecondary,
    LabelPrimary,
    LabelSecondary,
    NoStyle,
    Level(Level),
    Highlight,
    Addition,
    Removal,
}

// FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite.
pub fn elided_lifetime_in_path_suggestion(
    source_map: &SourceMap,
    n: usize,
    path_span: Span,
    incl_angl_brckt: bool,
    insertion_span: Span,
) -> ElidedLifetimeInPathSubdiag {
    let expected = ExpectedLifetimeParameter { span: path_span, count: n };
    // Do not try to suggest anything if generated by a proc-macro.
    let indicate = source_map.is_span_accessible(insertion_span).then(|| {
        let anon_lts = vec!["'_"; n].join(", ");
        let suggestion =
            if incl_angl_brckt { format!("<{anon_lts}>") } else { format!("{anon_lts}, ") };

        IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion }
    });

    ElidedLifetimeInPathSubdiag { expected, indicate }
}

/// Grammatical tool for displaying messages to end users in a nice form.
///
/// Returns "an" if the given string starts with a vowel, and "a" otherwise.
pub fn a_or_an(s: &str) -> &'static str {
    let mut chars = s.chars();
    let Some(mut first_alpha_char) = chars.next() else {
        return "a";
    };
    if first_alpha_char == '`' {
        let Some(next) = chars.next() else {
            return "a";
        };
        first_alpha_char = next;
    }
    if ["a", "e", "i", "o", "u", "&"].contains(&&first_alpha_char.to_lowercase().to_string()[..]) {
        "an"
    } else {
        "a"
    }
}

#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum TerminalUrl {
    No,
    Yes,
    Auto,
}
