//! Implementation of lint checking.
//!
//! The lint checking is mostly consolidated into one pass which runs
//! after all other analyses. Throughout compilation, lint warnings
//! can be added via the `add_lint` method on the Session structure. This
//! requires a span and an ID of the node that the lint is being added to. The
//! lint isn't actually emitted at that time because it is unknown what the
//! actual lint level at that location is.
//!
//! To actually emit lint warnings/errors, a separate pass is used.
//! A context keeps track of the current state of all lint levels.
//! Upon entering a node of the ast which can modify the lint settings, the
//! previous lint state is pushed onto a stack and the ast is then recursed
//! upon. As the ast is traversed, this keeps track of the current lint level
//! for all lint attributes.

use std::cell::Cell;
use std::{iter, slice};

use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync;
use rustc_data_structures::unord::UnordMap;
use rustc_errors::{Diag, LintDiagnostic, MultiSpan};
use rustc_feature::Features;
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_middle::bug;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt};
use rustc_session::lint::{
    BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
};
use rustc_session::{LintStoreMarker, Session};
use rustc_span::Span;
use rustc_span::edit_distance::find_best_match_for_names;
use rustc_span::symbol::{Ident, Symbol, sym};
use rustc_target::abi;
use tracing::debug;

use self::TargetLint::*;
use crate::levels::LintLevelsBuilder;
use crate::passes::{EarlyLintPassObject, LateLintPassObject};

mod diagnostics;

type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::DynSend + sync::DynSync;
type LateLintPassFactory =
    dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::DynSend + sync::DynSync;

/// Information about the registered lints.
///
/// This is basically the subset of `Context` that we can
/// build early in the compile pipeline.
pub struct LintStore {
    /// Registered lints.
    lints: Vec<&'static Lint>,

    /// Constructor functions for each variety of lint pass.
    ///
    /// These should only be called once, but since we want to avoid locks or
    /// interior mutability, we don't enforce this (and lints should, in theory,
    /// be compatible with being constructed more than once, though not
    /// necessarily in a sane manner. This is safe though.)
    pub pre_expansion_passes: Vec<Box<EarlyLintPassFactory>>,
    pub early_passes: Vec<Box<EarlyLintPassFactory>>,
    pub late_passes: Vec<Box<LateLintPassFactory>>,
    /// This is unique in that we construct them per-module, so not once.
    pub late_module_passes: Vec<Box<LateLintPassFactory>>,

    /// Lints indexed by name.
    by_name: UnordMap<String, TargetLint>,

    /// Map of registered lint groups to what lints they expand to.
    lint_groups: FxIndexMap<&'static str, LintGroup>,
}

impl LintStoreMarker for LintStore {}

/// The target of the `by_name` map, which accounts for renaming/deprecation.
#[derive(Debug)]
enum TargetLint {
    /// A direct lint target
    Id(LintId),

    /// Temporary renaming, used for easing migration pain; see #16545
    Renamed(String, LintId),

    /// Lint with this name existed previously, but has been removed/deprecated.
    /// The string argument is the reason for removal.
    Removed(String),

    /// A lint name that should give no warnings and have no effect.
    ///
    /// This is used by rustc to avoid warning about old rustdoc lints before rustdoc registers
    /// them as tool lints.
    Ignored,
}

pub enum FindLintError {
    NotFound,
    Removed,
}

struct LintAlias {
    name: &'static str,
    /// Whether deprecation warnings should be suppressed for this alias.
    silent: bool,
}

struct LintGroup {
    lint_ids: Vec<LintId>,
    is_externally_loaded: bool,
    depr: Option<LintAlias>,
}

#[derive(Debug)]
pub enum CheckLintNameResult<'a> {
    Ok(&'a [LintId]),
    /// Lint doesn't exist. Potentially contains a suggestion for a correct lint name.
    NoLint(Option<(Symbol, bool)>),
    /// The lint refers to a tool that has not been registered.
    NoTool,
    /// The lint has been renamed to a new name.
    Renamed(String),
    /// The lint has been removed due to the given reason.
    Removed(String),

    /// The lint is from a tool. The `LintId` will be returned as if it were a
    /// rustc lint. The `Option<String>` indicates if the lint has been
    /// renamed.
    Tool(&'a [LintId], Option<String>),

    /// The lint is from a tool. Either the lint does not exist in the tool or
    /// the code was not compiled with the tool and therefore the lint was
    /// never added to the `LintStore`.
    MissingTool,
}

impl LintStore {
    pub fn new() -> LintStore {
        LintStore {
            lints: vec![],
            pre_expansion_passes: vec![],
            early_passes: vec![],
            late_passes: vec![],
            late_module_passes: vec![],
            by_name: Default::default(),
            lint_groups: Default::default(),
        }
    }

    pub fn get_lints<'t>(&'t self) -> &'t [&'static Lint] {
        &self.lints
    }

    pub fn get_lint_groups<'t>(
        &'t self,
    ) -> impl Iterator<Item = (&'static str, Vec<LintId>, bool)> + 't {
        self.lint_groups
            .iter()
            .filter(|(_, LintGroup { depr, .. })| {
                // Don't display deprecated lint groups.
                depr.is_none()
            })
            .map(|(k, LintGroup { lint_ids, is_externally_loaded, .. })| {
                (*k, lint_ids.clone(), *is_externally_loaded)
            })
    }

    pub fn register_early_pass(
        &mut self,
        pass: impl Fn() -> EarlyLintPassObject + 'static + sync::DynSend + sync::DynSync,
    ) {
        self.early_passes.push(Box::new(pass));
    }

    /// This lint pass is softly deprecated. It misses expanded code and has caused a few
    /// errors in the past. Currently, it is only used in Clippy. New implementations
    /// should avoid using this interface, as it might be removed in the future.
    ///
    /// * See [rust#69838](https://github.com/rust-lang/rust/pull/69838)
    /// * See [rust-clippy#5518](https://github.com/rust-lang/rust-clippy/pull/5518)
    pub fn register_pre_expansion_pass(
        &mut self,
        pass: impl Fn() -> EarlyLintPassObject + 'static + sync::DynSend + sync::DynSync,
    ) {
        self.pre_expansion_passes.push(Box::new(pass));
    }

    pub fn register_late_pass(
        &mut self,
        pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
        + 'static
        + sync::DynSend
        + sync::DynSync,
    ) {
        self.late_passes.push(Box::new(pass));
    }

    pub fn register_late_mod_pass(
        &mut self,
        pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx>
        + 'static
        + sync::DynSend
        + sync::DynSync,
    ) {
        self.late_module_passes.push(Box::new(pass));
    }

    /// Helper method for register_early/late_pass
    pub fn register_lints(&mut self, lints: &[&'static Lint]) {
        for lint in lints {
            self.lints.push(lint);

            let id = LintId::of(lint);
            if self.by_name.insert(lint.name_lower(), Id(id)).is_some() {
                bug!("duplicate specification of lint {}", lint.name_lower())
            }

            if let Some(FutureIncompatibleInfo { reason, .. }) = lint.future_incompatible {
                if let Some(edition) = reason.edition() {
                    self.lint_groups
                        .entry(edition.lint_name())
                        .or_insert(LintGroup {
                            lint_ids: vec![],
                            is_externally_loaded: lint.is_externally_loaded,
                            depr: None,
                        })
                        .lint_ids
                        .push(id);
                } else {
                    // Lints belonging to the `future_incompatible` lint group are lints where a
                    // future version of rustc will cause existing code to stop compiling.
                    // Lints tied to an edition don't count because they are opt-in.
                    self.lint_groups
                        .entry("future_incompatible")
                        .or_insert(LintGroup {
                            lint_ids: vec![],
                            is_externally_loaded: lint.is_externally_loaded,
                            depr: None,
                        })
                        .lint_ids
                        .push(id);
                }
            }
        }
    }

    pub fn register_group_alias(&mut self, lint_name: &'static str, alias: &'static str) {
        self.lint_groups.insert(alias, LintGroup {
            lint_ids: vec![],
            is_externally_loaded: false,
            depr: Some(LintAlias { name: lint_name, silent: true }),
        });
    }

    pub fn register_group(
        &mut self,
        is_externally_loaded: bool,
        name: &'static str,
        deprecated_name: Option<&'static str>,
        to: Vec<LintId>,
    ) {
        let new = self
            .lint_groups
            .insert(name, LintGroup { lint_ids: to, is_externally_loaded, depr: None })
            .is_none();
        if let Some(deprecated) = deprecated_name {
            self.lint_groups.insert(deprecated, LintGroup {
                lint_ids: vec![],
                is_externally_loaded,
                depr: Some(LintAlias { name, silent: false }),
            });
        }

        if !new {
            bug!("duplicate specification of lint group {}", name);
        }
    }

    /// This lint should give no warning and have no effect.
    ///
    /// This is used by rustc to avoid warning about old rustdoc lints before rustdoc registers them as tool lints.
    #[track_caller]
    pub fn register_ignored(&mut self, name: &str) {
        if self.by_name.insert(name.to_string(), Ignored).is_some() {
            bug!("duplicate specification of lint {}", name);
        }
    }

    /// This lint has been renamed; warn about using the new name and apply the lint.
    #[track_caller]
    pub fn register_renamed(&mut self, old_name: &str, new_name: &str) {
        let Some(&Id(target)) = self.by_name.get(new_name) else {
            bug!("invalid lint renaming of {} to {}", old_name, new_name);
        };
        self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target));
    }

    pub fn register_removed(&mut self, name: &str, reason: &str) {
        self.by_name.insert(name.into(), Removed(reason.into()));
    }

    pub fn find_lints(&self, mut lint_name: &str) -> Result<Vec<LintId>, FindLintError> {
        match self.by_name.get(lint_name) {
            Some(&Id(lint_id)) => Ok(vec![lint_id]),
            Some(&Renamed(_, lint_id)) => Ok(vec![lint_id]),
            Some(&Removed(_)) => Err(FindLintError::Removed),
            Some(&Ignored) => Ok(vec![]),
            None => loop {
                return match self.lint_groups.get(lint_name) {
                    Some(LintGroup { lint_ids, depr, .. }) => {
                        if let Some(LintAlias { name, .. }) = depr {
                            lint_name = name;
                            continue;
                        }
                        Ok(lint_ids.clone())
                    }
                    None => Err(FindLintError::Removed),
                };
            },
        }
    }

    /// True if this symbol represents a lint group name.
    pub fn is_lint_group(&self, lint_name: Symbol) -> bool {
        debug!(
            "is_lint_group(lint_name={:?}, lint_groups={:?})",
            lint_name,
            self.lint_groups.keys().collect::<Vec<_>>()
        );
        let lint_name_str = lint_name.as_str();
        self.lint_groups.contains_key(lint_name_str) || {
            let warnings_name_str = crate::WARNINGS.name_lower();
            lint_name_str == warnings_name_str
        }
    }

    /// Checks the name of a lint for its existence, and whether it was
    /// renamed or removed. Generates a `Diag` containing a
    /// warning for renamed and removed lints. This is over both lint
    /// names from attributes and those passed on the command line. Since
    /// it emits non-fatal warnings and there are *two* lint passes that
    /// inspect attributes, this is only run from the late pass to avoid
    /// printing duplicate warnings.
    pub fn check_lint_name(
        &self,
        lint_name: &str,
        tool_name: Option<Symbol>,
        registered_tools: &RegisteredTools,
    ) -> CheckLintNameResult<'_> {
        if let Some(tool_name) = tool_name {
            // FIXME: rustc and rustdoc are considered tools for lints, but not for attributes.
            if tool_name != sym::rustc
                && tool_name != sym::rustdoc
                && !registered_tools.contains(&Ident::with_dummy_span(tool_name))
            {
                return CheckLintNameResult::NoTool;
            }
        }

        let complete_name = if let Some(tool_name) = tool_name {
            format!("{tool_name}::{lint_name}")
        } else {
            lint_name.to_string()
        };
        // If the lint was scoped with `tool::` check if the tool lint exists
        if let Some(tool_name) = tool_name {
            match self.by_name.get(&complete_name) {
                None => match self.lint_groups.get(&*complete_name) {
                    // If the lint isn't registered, there are two possibilities:
                    None => {
                        // 1. The tool is currently running, so this lint really doesn't exist.
                        // FIXME: should this handle tools that never register a lint, like rustfmt?
                        debug!("lints={:?}", self.by_name);
                        let tool_prefix = format!("{tool_name}::");

                        return if self.by_name.keys().any(|lint| lint.starts_with(&tool_prefix)) {
                            self.no_lint_suggestion(&complete_name, tool_name.as_str())
                        } else {
                            // 2. The tool isn't currently running, so no lints will be registered.
                            // To avoid giving a false positive, ignore all unknown lints.
                            CheckLintNameResult::MissingTool
                        };
                    }
                    Some(LintGroup { lint_ids, .. }) => {
                        return CheckLintNameResult::Tool(lint_ids, None);
                    }
                },
                Some(Id(id)) => return CheckLintNameResult::Tool(slice::from_ref(id), None),
                // If the lint was registered as removed or renamed by the lint tool, we don't need
                // to treat tool_lints and rustc lints different and can use the code below.
                _ => {}
            }
        }
        match self.by_name.get(&complete_name) {
            Some(Renamed(new_name, _)) => CheckLintNameResult::Renamed(new_name.to_string()),
            Some(Removed(reason)) => CheckLintNameResult::Removed(reason.to_string()),
            None => match self.lint_groups.get(&*complete_name) {
                // If neither the lint, nor the lint group exists check if there is a `clippy::`
                // variant of this lint
                None => self.check_tool_name_for_backwards_compat(&complete_name, "clippy"),
                Some(LintGroup { lint_ids, depr, .. }) => {
                    // Check if the lint group name is deprecated
                    if let Some(LintAlias { name, silent }) = depr {
                        let LintGroup { lint_ids, .. } = self.lint_groups.get(name).unwrap();
                        return if *silent {
                            CheckLintNameResult::Ok(lint_ids)
                        } else {
                            CheckLintNameResult::Tool(lint_ids, Some((*name).to_string()))
                        };
                    }
                    CheckLintNameResult::Ok(lint_ids)
                }
            },
            Some(Id(id)) => CheckLintNameResult::Ok(slice::from_ref(id)),
            Some(&Ignored) => CheckLintNameResult::Ok(&[]),
        }
    }

    fn no_lint_suggestion(&self, lint_name: &str, tool_name: &str) -> CheckLintNameResult<'_> {
        let name_lower = lint_name.to_lowercase();

        if lint_name.chars().any(char::is_uppercase) && self.find_lints(&name_lower).is_ok() {
            // First check if the lint name is (partly) in upper case instead of lower case...
            return CheckLintNameResult::NoLint(Some((Symbol::intern(&name_lower), false)));
        }

        // ...if not, search for lints with a similar name
        // Note: find_best_match_for_name depends on the sort order of its input vector.
        // To ensure deterministic output, sort elements of the lint_groups hash map.
        // Also, never suggest deprecated lint groups.
        // We will soon sort, so the initial order does not matter.
        #[allow(rustc::potential_query_instability)]
        let mut groups: Vec<_> = self
            .lint_groups
            .iter()
            .filter_map(|(k, LintGroup { depr, .. })| depr.is_none().then_some(k))
            .collect();
        groups.sort();
        let groups = groups.iter().map(|k| Symbol::intern(k));
        let lints = self.lints.iter().map(|l| Symbol::intern(&l.name_lower()));
        let names: Vec<Symbol> = groups.chain(lints).collect();
        let mut lookups = vec![Symbol::intern(&name_lower)];
        if let Some(stripped) = name_lower.split("::").last() {
            lookups.push(Symbol::intern(stripped));
        }
        let res = find_best_match_for_names(&names, &lookups, None);
        let is_rustc = res.map_or_else(
            || false,
            |s| name_lower.contains("::") && !s.as_str().starts_with(tool_name),
        );
        let suggestion = res.map(|s| (s, is_rustc));
        CheckLintNameResult::NoLint(suggestion)
    }

    fn check_tool_name_for_backwards_compat(
        &self,
        lint_name: &str,
        tool_name: &str,
    ) -> CheckLintNameResult<'_> {
        let complete_name = format!("{tool_name}::{lint_name}");
        match self.by_name.get(&complete_name) {
            None => match self.lint_groups.get(&*complete_name) {
                // Now we are sure, that this lint exists nowhere
                None => self.no_lint_suggestion(lint_name, tool_name),
                Some(LintGroup { lint_ids, depr, .. }) => {
                    // Reaching this would be weird, but let's cover this case anyway
                    if let Some(LintAlias { name, silent }) = depr {
                        let LintGroup { lint_ids, .. } = self.lint_groups.get(name).unwrap();
                        if *silent {
                            CheckLintNameResult::Tool(lint_ids, Some(complete_name))
                        } else {
                            CheckLintNameResult::Tool(lint_ids, Some((*name).to_string()))
                        }
                    } else {
                        CheckLintNameResult::Tool(lint_ids, Some(complete_name))
                    }
                }
            },
            Some(Id(id)) => CheckLintNameResult::Tool(slice::from_ref(id), Some(complete_name)),
            Some(other) => {
                debug!("got renamed lint {:?}", other);
                CheckLintNameResult::NoLint(None)
            }
        }
    }
}

/// Context for lint checking outside of type inference.
pub struct LateContext<'tcx> {
    /// Type context we're checking in.
    pub tcx: TyCtxt<'tcx>,

    /// Current body, or `None` if outside a body.
    pub enclosing_body: Option<hir::BodyId>,

    /// Type-checking results for the current body. Access using the `typeck_results`
    /// and `maybe_typeck_results` methods, which handle querying the typeck results on demand.
    // FIXME(eddyb) move all the code accessing internal fields like this,
    // to this module, to avoid exposing it to lint logic.
    pub(super) cached_typeck_results: Cell<Option<&'tcx ty::TypeckResults<'tcx>>>,

    /// Parameter environment for the item we are in.
    pub param_env: ty::ParamEnv<'tcx>,

    /// Items accessible from the crate being checked.
    pub effective_visibilities: &'tcx EffectiveVisibilities,

    pub last_node_with_lint_attrs: hir::HirId,

    /// Generic type parameters in scope for the item we are in.
    pub generics: Option<&'tcx hir::Generics<'tcx>>,

    /// We are only looking at one module
    pub only_module: bool,
}

/// Context for lint checking of the AST, after expansion, before lowering to HIR.
pub struct EarlyContext<'a> {
    pub builder: LintLevelsBuilder<'a, crate::levels::TopDown>,
    pub buffered: LintBuffer,
}

impl EarlyContext<'_> {
    /// Emit a lint at the appropriate level, with an associated span and an existing
    /// diagnostic.
    ///
    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
    #[rustc_lint_diagnostics]
    pub fn span_lint_with_diagnostics(
        &self,
        lint: &'static Lint,
        span: MultiSpan,
        diagnostic: BuiltinLintDiag,
    ) {
        self.opt_span_lint_with_diagnostics(lint, Some(span), diagnostic);
    }

    /// Emit a lint at the appropriate level, with an optional associated span and an existing
    /// diagnostic.
    ///
    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
    #[rustc_lint_diagnostics]
    pub fn opt_span_lint_with_diagnostics(
        &self,
        lint: &'static Lint,
        span: Option<MultiSpan>,
        diagnostic: BuiltinLintDiag,
    ) {
        self.opt_span_lint(lint, span, |diag| {
            diagnostics::decorate_lint(self.sess(), diagnostic, diag);
        });
    }
}

pub trait LintContext {
    fn sess(&self) -> &Session;

    // FIXME: These methods should not take an Into<MultiSpan> -- instead, callers should need to
    // set the span in their `decorate` function (preferably using set_span).
    /// Emit a lint at the appropriate level, with an optional associated span.
    ///
    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
    #[rustc_lint_diagnostics]
    fn opt_span_lint<S: Into<MultiSpan>>(
        &self,
        lint: &'static Lint,
        span: Option<S>,
        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
    );

    /// Emit a lint at `span` from a lint struct (some type that implements `LintDiagnostic`,
    /// typically generated by `#[derive(LintDiagnostic)]`).
    fn emit_span_lint<S: Into<MultiSpan>>(
        &self,
        lint: &'static Lint,
        span: S,
        decorator: impl for<'a> LintDiagnostic<'a, ()>,
    ) {
        self.opt_span_lint(lint, Some(span), |lint| {
            decorator.decorate_lint(lint);
        });
    }

    /// Emit a lint at the appropriate level, with an associated span.
    ///
    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
    #[rustc_lint_diagnostics]
    fn span_lint<S: Into<MultiSpan>>(
        &self,
        lint: &'static Lint,
        span: S,
        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
    ) {
        self.opt_span_lint(lint, Some(span), decorate);
    }

    /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically
    /// generated by `#[derive(LintDiagnostic)]`).
    fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> LintDiagnostic<'a, ()>) {
        self.opt_span_lint(lint, None as Option<Span>, |lint| {
            decorator.decorate_lint(lint);
        });
    }

    /// Emit a lint at the appropriate level, with no associated span.
    ///
    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
    #[rustc_lint_diagnostics]
    fn lint(&self, lint: &'static Lint, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)) {
        self.opt_span_lint(lint, None as Option<Span>, decorate);
    }

    /// This returns the lint level for the given lint at the current location.
    fn get_lint_level(&self, lint: &'static Lint) -> Level;

    /// This function can be used to manually fulfill an expectation. This can
    /// be used for lints which contain several spans, and should be suppressed,
    /// if either location was marked with an expectation.
    ///
    /// Note that this function should only be called for [`LintExpectationId`]s
    /// retrieved from the current lint pass. Buffered or manually created ids can
    /// cause ICEs.
    fn fulfill_expectation(&self, expectation: LintExpectationId) {
        // We need to make sure that submitted expectation ids are correctly fulfilled suppressed
        // and stored between compilation sessions. To not manually do these steps, we simply create
        // a dummy diagnostic and emit it as usual, which will be suppressed and stored like a
        // normal expected lint diagnostic.
        #[allow(rustc::diagnostic_outside_of_impl)]
        #[allow(rustc::untranslatable_diagnostic)]
        self.sess()
            .dcx()
            .struct_expect(
                "this is a dummy diagnostic, to submit and store an expectation",
                expectation,
            )
            .emit();
    }
}

impl<'a> EarlyContext<'a> {
    pub(crate) fn new(
        sess: &'a Session,
        features: &'a Features,
        lint_added_lints: bool,
        lint_store: &'a LintStore,
        registered_tools: &'a RegisteredTools,
        buffered: LintBuffer,
    ) -> EarlyContext<'a> {
        EarlyContext {
            builder: LintLevelsBuilder::new(
                sess,
                features,
                lint_added_lints,
                lint_store,
                registered_tools,
            ),
            buffered,
        }
    }
}

impl<'tcx> LintContext for LateContext<'tcx> {
    /// Gets the overall compiler `Session` object.
    fn sess(&self) -> &Session {
        self.tcx.sess
    }

    #[rustc_lint_diagnostics]
    fn opt_span_lint<S: Into<MultiSpan>>(
        &self,
        lint: &'static Lint,
        span: Option<S>,
        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
    ) {
        let hir_id = self.last_node_with_lint_attrs;

        match span {
            Some(s) => self.tcx.node_span_lint(lint, hir_id, s, decorate),
            None => self.tcx.node_lint(lint, hir_id, decorate),
        }
    }

    fn get_lint_level(&self, lint: &'static Lint) -> Level {
        self.tcx.lint_level_at_node(lint, self.last_node_with_lint_attrs).0
    }
}

impl LintContext for EarlyContext<'_> {
    /// Gets the overall compiler `Session` object.
    fn sess(&self) -> &Session {
        self.builder.sess()
    }

    #[rustc_lint_diagnostics]
    fn opt_span_lint<S: Into<MultiSpan>>(
        &self,
        lint: &'static Lint,
        span: Option<S>,
        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
    ) {
        self.builder.opt_span_lint(lint, span.map(|s| s.into()), decorate)
    }

    fn get_lint_level(&self, lint: &'static Lint) -> Level {
        self.builder.lint_level(lint).0
    }
}

impl<'tcx> LateContext<'tcx> {
    /// Gets the type-checking results for the current body,
    /// or `None` if outside a body.
    pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> {
        self.cached_typeck_results.get().or_else(|| {
            self.enclosing_body.map(|body| {
                let typeck_results = self.tcx.typeck_body(body);
                self.cached_typeck_results.set(Some(typeck_results));
                typeck_results
            })
        })
    }

    /// Gets the type-checking results for the current body.
    /// As this will ICE if called outside bodies, only call when working with
    /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
    #[track_caller]
    pub fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> {
        self.maybe_typeck_results().expect("`LateContext::typeck_results` called outside of body")
    }

    /// Returns the final resolution of a `QPath`, or `Res::Err` if unavailable.
    /// Unlike `.typeck_results().qpath_res(qpath, id)`, this can be used even outside
    /// bodies (e.g. for paths in `hir::Ty`), without any risk of ICE-ing.
    pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
        match *qpath {
            hir::QPath::Resolved(_, path) => path.res,
            hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
                .maybe_typeck_results()
                .filter(|typeck_results| typeck_results.hir_owner == id.owner)
                .or_else(|| {
                    self.tcx
                        .has_typeck_results(id.owner.def_id)
                        .then(|| self.tcx.typeck(id.owner.def_id))
                })
                .and_then(|typeck_results| typeck_results.type_dependent_def(id))
                .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
        }
    }

    /// Check if a `DefId`'s path matches the given absolute type path usage.
    ///
    /// Anonymous scopes such as `extern` imports are matched with `kw::Empty`;
    /// inherent `impl` blocks are matched with the name of the type.
    ///
    /// Instead of using this method, it is often preferable to instead use
    /// `rustc_diagnostic_item` or a `lang_item`. This is less prone to errors
    /// as paths get invalidated if the target definition moves.
    ///
    /// # Examples
    ///
    /// ```rust,ignore (no context or def id available)
    /// if cx.match_def_path(def_id, &[sym::core, sym::option, sym::Option]) {
    ///     // The given `def_id` is that of an `Option` type
    /// }
    /// ```
    ///
    /// Used by clippy, but should be replaced by diagnostic items eventually.
    pub fn match_def_path(&self, def_id: DefId, path: &[Symbol]) -> bool {
        let names = self.get_def_path(def_id);

        names.len() == path.len() && iter::zip(names, path).all(|(a, &b)| a == b)
    }

    /// Gets the absolute path of `def_id` as a vector of `Symbol`.
    ///
    /// # Examples
    ///
    /// ```rust,ignore (no context or def id available)
    /// let def_path = cx.get_def_path(def_id);
    /// if let &[sym::core, sym::option, sym::Option] = &def_path[..] {
    ///     // The given `def_id` is that of an `Option` type
    /// }
    /// ```
    pub fn get_def_path(&self, def_id: DefId) -> Vec<Symbol> {
        struct AbsolutePathPrinter<'tcx> {
            tcx: TyCtxt<'tcx>,
            path: Vec<Symbol>,
        }

        impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
            fn tcx(&self) -> TyCtxt<'tcx> {
                self.tcx
            }

            fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
                Ok(())
            }

            fn print_type(&mut self, _ty: Ty<'tcx>) -> Result<(), PrintError> {
                Ok(())
            }

            fn print_dyn_existential(
                &mut self,
                _predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
            ) -> Result<(), PrintError> {
                Ok(())
            }

            fn print_const(&mut self, _ct: ty::Const<'tcx>) -> Result<(), PrintError> {
                Ok(())
            }

            fn path_crate(&mut self, cnum: CrateNum) -> Result<(), PrintError> {
                self.path = vec![self.tcx.crate_name(cnum)];
                Ok(())
            }

            fn path_qualified(
                &mut self,
                self_ty: Ty<'tcx>,
                trait_ref: Option<ty::TraitRef<'tcx>>,
            ) -> Result<(), PrintError> {
                if trait_ref.is_none() {
                    if let ty::Adt(def, args) = self_ty.kind() {
                        return self.print_def_path(def.did(), args);
                    }
                }

                // This shouldn't ever be needed, but just in case:
                with_no_trimmed_paths!({
                    self.path = vec![match trait_ref {
                        Some(trait_ref) => Symbol::intern(&format!("{trait_ref:?}")),
                        None => Symbol::intern(&format!("<{self_ty}>")),
                    }];
                    Ok(())
                })
            }

            fn path_append_impl(
                &mut self,
                print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
                _disambiguated_data: &DisambiguatedDefPathData,
                self_ty: Ty<'tcx>,
                trait_ref: Option<ty::TraitRef<'tcx>>,
            ) -> Result<(), PrintError> {
                print_prefix(self)?;

                // This shouldn't ever be needed, but just in case:
                self.path.push(match trait_ref {
                    Some(trait_ref) => {
                        with_no_trimmed_paths!(Symbol::intern(&format!(
                            "<impl {} for {}>",
                            trait_ref.print_only_trait_path(),
                            self_ty
                        )))
                    }
                    None => {
                        with_no_trimmed_paths!(Symbol::intern(&format!("<impl {self_ty}>")))
                    }
                });

                Ok(())
            }

            fn path_append(
                &mut self,
                print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
                disambiguated_data: &DisambiguatedDefPathData,
            ) -> Result<(), PrintError> {
                print_prefix(self)?;

                // Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs.
                if let DefPathData::ForeignMod | DefPathData::Ctor = disambiguated_data.data {
                    return Ok(());
                }

                self.path.push(Symbol::intern(&disambiguated_data.data.to_string()));
                Ok(())
            }

            fn path_generic_args(
                &mut self,
                print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
                _args: &[GenericArg<'tcx>],
            ) -> Result<(), PrintError> {
                print_prefix(self)
            }
        }

        let mut printer = AbsolutePathPrinter { tcx: self.tcx, path: vec![] };
        printer.print_def_path(def_id, &[]).unwrap();
        printer.path
    }

    /// Returns the associated type `name` for `self_ty` as an implementation of `trait_id`.
    /// Do not invoke without first verifying that the type implements the trait.
    pub fn get_associated_type(
        &self,
        self_ty: Ty<'tcx>,
        trait_id: DefId,
        name: &str,
    ) -> Option<Ty<'tcx>> {
        let tcx = self.tcx;
        tcx.associated_items(trait_id)
            .find_by_name_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
            .and_then(|assoc| {
                let proj = Ty::new_projection(tcx, assoc.def_id, [self_ty]);
                tcx.try_normalize_erasing_regions(self.param_env, proj).ok()
            })
    }

    /// If the given expression is a local binding, find the initializer expression.
    /// If that initializer expression is another local binding, find its initializer again.
    ///
    /// This process repeats as long as possible (but usually no more than once).
    /// Type-check adjustments are not taken in account in this function.
    ///
    /// Examples:
    /// ```
    /// let abc = 1;
    /// let def = abc + 2;
    /// //        ^^^^^^^ output
    /// let def = def;
    /// dbg!(def);
    /// //   ^^^ input
    /// ```
    pub fn expr_or_init<'a>(&self, mut expr: &'a hir::Expr<'tcx>) -> &'a hir::Expr<'tcx> {
        expr = expr.peel_blocks();

        while let hir::ExprKind::Path(ref qpath) = expr.kind
            && let Some(parent_node) = match self.qpath_res(qpath, expr.hir_id) {
                Res::Local(hir_id) => Some(self.tcx.parent_hir_node(hir_id)),
                _ => None,
            }
            && let Some(init) = match parent_node {
                hir::Node::Expr(expr) => Some(expr),
                hir::Node::LetStmt(hir::LetStmt { init, .. }) => *init,
                _ => None,
            }
        {
            expr = init.peel_blocks();
        }
        expr
    }

    /// If the given expression is a local binding, find the initializer expression.
    /// If that initializer expression is another local or **outside** (`const`/`static`)
    /// binding, find its initializer again.
    ///
    /// This process repeats as long as possible (but usually no more than once).
    /// Type-check adjustments are not taken in account in this function.
    ///
    /// Examples:
    /// ```
    /// const ABC: i32 = 1;
    /// //               ^ output
    /// let def = ABC;
    /// dbg!(def);
    /// //   ^^^ input
    ///
    /// // or...
    /// let abc = 1;
    /// let def = abc + 2;
    /// //        ^^^^^^^ output
    /// dbg!(def);
    /// //   ^^^ input
    /// ```
    pub fn expr_or_init_with_outside_body<'a>(
        &self,
        mut expr: &'a hir::Expr<'tcx>,
    ) -> &'a hir::Expr<'tcx> {
        expr = expr.peel_blocks();

        while let hir::ExprKind::Path(ref qpath) = expr.kind
            && let Some(parent_node) = match self.qpath_res(qpath, expr.hir_id) {
                Res::Local(hir_id) => Some(self.tcx.parent_hir_node(hir_id)),
                Res::Def(_, def_id) => self.tcx.hir().get_if_local(def_id),
                _ => None,
            }
            && let Some(init) = match parent_node {
                hir::Node::Expr(expr) => Some(expr),
                hir::Node::LetStmt(hir::LetStmt { init, .. }) => *init,
                hir::Node::Item(item) => match item.kind {
                    hir::ItemKind::Const(.., body_id) | hir::ItemKind::Static(.., body_id) => {
                        Some(self.tcx.hir().body(body_id).value)
                    }
                    _ => None,
                },
                _ => None,
            }
        {
            expr = init.peel_blocks();
        }
        expr
    }
}

impl<'tcx> abi::HasDataLayout for LateContext<'tcx> {
    #[inline]
    fn data_layout(&self) -> &abi::TargetDataLayout {
        &self.tcx.data_layout
    }
}

impl<'tcx> ty::layout::HasTyCtxt<'tcx> for LateContext<'tcx> {
    #[inline]
    fn tcx(&self) -> TyCtxt<'tcx> {
        self.tcx
    }
}

impl<'tcx> ty::layout::HasParamEnv<'tcx> for LateContext<'tcx> {
    #[inline]
    fn param_env(&self) -> ty::ParamEnv<'tcx> {
        self.param_env
    }
}

impl<'tcx> LayoutOfHelpers<'tcx> for LateContext<'tcx> {
    type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;

    #[inline]
    fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> {
        err
    }
}
