use clippy_utils::diagnostics::{span_lint, span_lint_hir};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, Attribute, find_attr};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::AssocContainer;
use rustc_session::config::CrateType;
use rustc_session::declare_lint_pass;
use rustc_span::Span;

declare_clippy_lint! {
    /// ### What it does
    /// It lints if an exported function, method, trait method with default impl,
    /// or trait method impl is not `#[inline]`.
    ///
    /// ### Why restrict this?
    /// When a function is not marked `#[inline]`, it is not
    /// [a “small” candidate for automatic inlining][small], and LTO is not in use, then it is not
    /// possible for the function to be inlined into the code of any crate other than the one in
    /// which it is defined.  Depending on the role of the function and the relationship of the crates,
    /// this could significantly reduce performance.
    ///
    /// Certain types of crates might intend for most of the methods in their public API to be able
    /// to be inlined across crates even when LTO is disabled.
    /// This lint allows those crates to require all exported methods to be `#[inline]` by default, and
    /// then opt out for specific methods where this might not make sense.
    ///
    /// ### Example
    /// ```no_run
    /// pub fn foo() {} // missing #[inline]
    /// fn ok() {} // ok
    /// #[inline] pub fn bar() {} // ok
    /// #[inline(always)] pub fn baz() {} // ok
    ///
    /// pub trait Bar {
    ///   fn bar(); // ok
    ///   fn def_bar() {} // missing #[inline]
    /// }
    ///
    /// struct Baz;
    /// impl Baz {
    ///     fn private() {} // ok
    /// }
    ///
    /// impl Bar for Baz {
    ///   fn bar() {} // ok - Baz is not exported
    /// }
    ///
    /// pub struct PubBaz;
    /// impl PubBaz {
    ///     fn private() {} // ok
    ///     pub fn not_private() {} // missing #[inline]
    /// }
    ///
    /// impl Bar for PubBaz {
    ///     fn bar() {} // missing #[inline]
    ///     fn def_bar() {} // missing #[inline]
    /// }
    /// ```
    ///
    /// [small]: https://github.com/rust-lang/rust/pull/116505
    #[clippy::version = "pre 1.29.0"]
    pub MISSING_INLINE_IN_PUBLIC_ITEMS,
    restriction,
    "detects missing `#[inline]` attribute for public callables (functions, trait methods, methods...)"
}

fn check_missing_inline_attrs(
    cx: &LateContext<'_>,
    attrs: &[Attribute],
    sp: Span,
    desc: &'static str,
    hir_id: Option<hir::HirId>,
) {
    if !find_attr!(attrs, AttributeKind::Inline(..)) {
        let msg = format!("missing `#[inline]` for {desc}");
        if let Some(hir_id) = hir_id {
            span_lint_hir(cx, MISSING_INLINE_IN_PUBLIC_ITEMS, hir_id, sp, msg);
        } else {
            span_lint(cx, MISSING_INLINE_IN_PUBLIC_ITEMS, sp, msg);
        }
    }
}

declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]);

impl<'tcx> LateLintPass<'tcx> for MissingInline {
    fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
        if it.span.in_external_macro(cx.sess().source_map()) {
            return;
        }

        if cx
            .tcx
            .crate_types()
            .iter()
            .any(|t: &CrateType| matches!(t, CrateType::ProcMacro))
        {
            return;
        }

        if !cx.effective_visibilities.is_exported(it.owner_id.def_id) {
            return;
        }
        match it.kind {
            hir::ItemKind::Fn { .. } => {
                if fn_is_externally_exported(cx, it.owner_id.to_def_id()) {
                    return;
                }

                let desc = "a function";
                let attrs = cx.tcx.hir_attrs(it.hir_id());
                check_missing_inline_attrs(cx, attrs, it.span, desc, None);
            },
            hir::ItemKind::Trait(.., trait_items) => {
                // note: we need to check if the trait is exported so we can't use
                // `LateLintPass::check_trait_item` here.
                for &tit in trait_items {
                    let tit_ = cx.tcx.hir_trait_item(tit);
                    match tit_.kind {
                        hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {},
                        hir::TraitItemKind::Fn(..) => {
                            if cx.tcx.defaultness(tit.owner_id).has_value() {
                                // trait method with default body needs inline in case
                                // an impl is not provided
                                let desc = "a default trait method";
                                let item = cx.tcx.hir_trait_item(tit);
                                let attrs = cx.tcx.hir_attrs(item.hir_id());
                                check_missing_inline_attrs(cx, attrs, item.span, desc, Some(tit.hir_id()));
                            }
                        },
                    }
                }
            },
            hir::ItemKind::Const(..)
            | hir::ItemKind::Enum(..)
            | hir::ItemKind::Macro(..)
            | hir::ItemKind::Mod(..)
            | hir::ItemKind::Static(..)
            | hir::ItemKind::Struct(..)
            | hir::ItemKind::TraitAlias(..)
            | hir::ItemKind::GlobalAsm { .. }
            | hir::ItemKind::TyAlias(..)
            | hir::ItemKind::Union(..)
            | hir::ItemKind::ExternCrate(..)
            | hir::ItemKind::ForeignMod { .. }
            | hir::ItemKind::Impl { .. }
            | hir::ItemKind::Use(..) => {},
        }
    }

    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
        if impl_item.span.in_external_macro(cx.sess().source_map())
            || cx
                .tcx
                .crate_types()
                .iter()
                .any(|t: &CrateType| matches!(t, CrateType::ProcMacro))
        {
            return;
        }

        // If the item being implemented is not exported, then we don't need #[inline]
        if !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) {
            return;
        }

        let desc = match impl_item.kind {
            hir::ImplItemKind::Fn(..) => "a method",
            hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(_) => return,
        };

        let assoc_item = cx.tcx.associated_item(impl_item.owner_id);
        let container_id = assoc_item.container_id(cx.tcx);
        let trait_def_id = match assoc_item.container {
            AssocContainer::Trait => Some(container_id),
            AssocContainer::TraitImpl(_) => Some(cx.tcx.impl_trait_id(container_id)),
            AssocContainer::InherentImpl => None,
        };

        if let Some(trait_def_id) = trait_def_id
            && trait_def_id.is_local()
            && !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id)
        {
            // If a trait is being implemented for an item, and the
            // trait is not exported, we don't need #[inline]
            return;
        }

        let attrs = cx.tcx.hir_attrs(impl_item.hir_id());
        check_missing_inline_attrs(cx, attrs, impl_item.span, desc, None);
    }
}

/// Checks if this function is externally exported, where #[inline] wouldn't have the desired effect
/// and a rustc warning would be triggered, see #15301
fn fn_is_externally_exported(cx: &LateContext<'_>, def_id: DefId) -> bool {
    let attrs = cx.tcx.codegen_fn_attrs(def_id);
    attrs.contains_extern_indicator()
}
