| //! checks for `#[inline]` on trait methods without bodies |
| |
| use clippy_utils::diagnostics::span_lint_and_then; |
| use clippy_utils::sugg::DiagnosticExt; |
| use rustc_ast::ast::Attribute; |
| use rustc_errors::Applicability; |
| use rustc_hir::{TraitFn, TraitItem, TraitItemKind}; |
| use rustc_lint::{LateContext, LateLintPass}; |
| use rustc_session::{declare_lint_pass, declare_tool_lint}; |
| use rustc_span::{sym, Symbol}; |
| |
| declare_clippy_lint! { |
| /// ### What it does |
| /// Checks for `#[inline]` on trait methods without bodies |
| /// |
| /// ### Why is this bad? |
| /// Only implementations of trait methods may be inlined. |
| /// The inline attribute is ignored for trait methods without bodies. |
| /// |
| /// ### Example |
| /// ```no_run |
| /// trait Animal { |
| /// #[inline] |
| /// fn name(&self) -> &'static str; |
| /// } |
| /// ``` |
| #[clippy::version = "pre 1.29.0"] |
| pub INLINE_FN_WITHOUT_BODY, |
| correctness, |
| "use of `#[inline]` on trait methods without bodies" |
| } |
| |
| declare_lint_pass!(InlineFnWithoutBody => [INLINE_FN_WITHOUT_BODY]); |
| |
| impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody { |
| fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { |
| if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind { |
| let attrs = cx.tcx.hir().attrs(item.hir_id()); |
| check_attrs(cx, item.ident.name, attrs); |
| } |
| } |
| } |
| |
| fn check_attrs(cx: &LateContext<'_>, name: Symbol, attrs: &[Attribute]) { |
| for attr in attrs { |
| if !attr.has_name(sym::inline) { |
| continue; |
| } |
| |
| span_lint_and_then( |
| cx, |
| INLINE_FN_WITHOUT_BODY, |
| attr.span, |
| &format!("use of `#[inline]` on trait method `{name}` which has no body"), |
| |diag| { |
| diag.suggest_remove_item(cx, attr.span, "remove", Applicability::MachineApplicable); |
| }, |
| ); |
| } |
| } |