Skip to content

Commit def1c09

Browse files
authored
Simplify missing_inline_in_public_items (#17292)
changelog: none
2 parents fd956e6 + 6e6921c commit def1c09

3 files changed

Lines changed: 35 additions & 130 deletions

File tree

clippy_lints/src/missing_inline.rs

Lines changed: 28 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use clippy_utils::diagnostics::{span_lint, span_lint_hir};
2-
use rustc_hir::def_id::DefId;
3-
use rustc_hir::{self as hir, Attribute, find_attr};
4-
use rustc_lint::{LateContext, LateLintPass, LintContext};
5-
use rustc_middle::ty::AssocContainer;
1+
use clippy_utils::diagnostics::span_lint;
2+
use rustc_hir::{ImplItem, ImplItemKind, Item, ItemKind, OwnerId, TraitFn, TraitItem, TraitItemKind, find_attr};
3+
use rustc_lint::{LateContext, LateLintPass};
64
use rustc_session::config::CrateType;
75
use rustc_session::declare_lint_pass;
86
use rustc_span::Span;
@@ -66,134 +64,41 @@ declare_clippy_lint! {
6664

6765
declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]);
6866

69-
fn check_missing_inline_attrs(
70-
cx: &LateContext<'_>,
71-
attrs: &[Attribute],
72-
sp: Span,
73-
desc: &'static str,
74-
hir_id: Option<hir::HirId>,
75-
) {
76-
if !find_attr!(attrs, Inline(..)) {
77-
let msg = format!("missing `#[inline]` for {desc}");
78-
if let Some(hir_id) = hir_id {
79-
span_lint_hir(cx, MISSING_INLINE_IN_PUBLIC_ITEMS, hir_id, sp, msg);
80-
} else {
81-
span_lint(cx, MISSING_INLINE_IN_PUBLIC_ITEMS, sp, msg);
82-
}
67+
fn check(cx: &LateContext<'_>, item: OwnerId, sp: Span) {
68+
if cx.effective_visibilities.is_exported(item.def_id)
69+
&& !find_attr!(cx.tcx.hir_attrs(item.into()), Inline(..))
70+
// Rust `inline` doesn't mean anything with external linkage.
71+
&& !cx.tcx.codegen_fn_attrs(item.def_id).contains_extern_indicator()
72+
&& !cx.tcx.crate_types().iter().any(|&t| matches!(t, CrateType::ProcMacro))
73+
&& !sp.in_external_macro(cx.tcx.sess.source_map())
74+
{
75+
span_lint(
76+
cx,
77+
MISSING_INLINE_IN_PUBLIC_ITEMS,
78+
sp,
79+
"missing `#[inline]` on a publicly callable function",
80+
);
8381
}
8482
}
8583

8684
impl<'tcx> LateLintPass<'tcx> for MissingInline {
87-
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
88-
if it.span.in_external_macro(cx.sess().source_map()) {
89-
return;
90-
}
91-
92-
if cx
93-
.tcx
94-
.crate_types()
95-
.iter()
96-
.any(|t: &CrateType| matches!(t, CrateType::ProcMacro))
97-
{
98-
return;
99-
}
100-
101-
if !cx.effective_visibilities.is_exported(it.owner_id.def_id) {
102-
return;
103-
}
104-
match it.kind {
105-
hir::ItemKind::Fn { .. } => {
106-
if fn_is_externally_exported(cx, it.owner_id.to_def_id()) {
107-
return;
108-
}
109-
110-
let desc = "a function";
111-
let attrs = cx.tcx.hir_attrs(it.hir_id());
112-
check_missing_inline_attrs(cx, attrs, it.span, desc, None);
113-
},
114-
hir::ItemKind::Trait { items: trait_items, .. } => {
115-
// note: we need to check if the trait is exported so we can't use
116-
// `LateLintPass::check_trait_item` here.
117-
for &tit in trait_items {
118-
let tit_ = cx.tcx.hir_trait_item(tit);
119-
match tit_.kind {
120-
hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {},
121-
hir::TraitItemKind::Fn(..) => {
122-
if cx.tcx.defaultness(tit.owner_id).has_value() {
123-
// trait method with default body needs inline in case
124-
// an impl is not provided
125-
let desc = "a default trait method";
126-
let item = cx.tcx.hir_trait_item(tit);
127-
let attrs = cx.tcx.hir_attrs(item.hir_id());
128-
check_missing_inline_attrs(cx, attrs, item.span, desc, Some(tit.hir_id()));
129-
}
130-
},
131-
}
132-
}
133-
},
134-
hir::ItemKind::Const(..)
135-
| hir::ItemKind::Enum(..)
136-
| hir::ItemKind::Macro(..)
137-
| hir::ItemKind::Mod(..)
138-
| hir::ItemKind::Static(..)
139-
| hir::ItemKind::Struct(..)
140-
| hir::ItemKind::TraitAlias(..)
141-
| hir::ItemKind::GlobalAsm { .. }
142-
| hir::ItemKind::TyAlias(..)
143-
| hir::ItemKind::Union(..)
144-
| hir::ItemKind::ExternCrate(..)
145-
| hir::ItemKind::ForeignMod { .. }
146-
| hir::ItemKind::Impl { .. }
147-
| hir::ItemKind::Use(..) => {},
85+
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) {
86+
if let ItemKind::Fn { .. } = it.kind {
87+
check(cx, it.owner_id, it.span);
14888
}
14989
}
15090

151-
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
152-
if impl_item.span.in_external_macro(cx.sess().source_map())
153-
|| cx
154-
.tcx
155-
.crate_types()
156-
.iter()
157-
.any(|t: &CrateType| matches!(t, CrateType::ProcMacro))
91+
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
92+
if let TraitItemKind::Fn(_, f) = item.kind
93+
&& let TraitFn::Provided(_) = f
15894
{
159-
return;
95+
check(cx, item.owner_id, item.span);
16096
}
97+
}
16198

162-
// If the item being implemented is not exported, then we don't need #[inline]
163-
if !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) {
164-
return;
165-
}
166-
167-
let desc = match impl_item.kind {
168-
hir::ImplItemKind::Fn(..) => "a method",
169-
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(_) => return,
170-
};
171-
172-
let assoc_item = cx.tcx.associated_item(impl_item.owner_id);
173-
let container_id = assoc_item.container_id(cx.tcx);
174-
let trait_def_id = match assoc_item.container {
175-
AssocContainer::Trait => Some(container_id),
176-
AssocContainer::TraitImpl(_) => Some(cx.tcx.impl_trait_id(container_id)),
177-
AssocContainer::InherentImpl => None,
178-
};
179-
180-
if let Some(trait_def_id) = trait_def_id
181-
&& trait_def_id.is_local()
182-
&& !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id)
183-
{
184-
// If a trait is being implemented for an item, and the
185-
// trait is not exported, we don't need #[inline]
186-
return;
99+
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
100+
if let ImplItemKind::Fn(..) = item.kind {
101+
check(cx, item.owner_id, item.span);
187102
}
188-
189-
let attrs = cx.tcx.hir_attrs(impl_item.hir_id());
190-
check_missing_inline_attrs(cx, attrs, impl_item.span, desc, None);
191103
}
192104
}
193-
194-
/// Checks if this function is externally exported, where #[inline] wouldn't have the desired effect
195-
/// and a rustc warning would be triggered, see #15301
196-
fn fn_is_externally_exported(cx: &LateContext<'_>, def_id: DefId) -> bool {
197-
let attrs = cx.tcx.codegen_fn_attrs(def_id);
198-
attrs.contains_extern_indicator()
199-
}

tests/ui/missing_inline.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: missing `#[inline]` for a function
1+
error: missing `#[inline]` on a publicly callable function
22
--> tests/ui/missing_inline.rs:20:1
33
|
44
LL | pub fn pub_foo() {}
@@ -7,31 +7,31 @@ LL | pub fn pub_foo() {}
77
= note: `-D clippy::missing-inline-in-public-items` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::missing_inline_in_public_items)]`
99

10-
error: missing `#[inline]` for a default trait method
10+
error: missing `#[inline]` on a publicly callable function
1111
--> tests/ui/missing_inline.rs:39:5
1212
|
1313
LL | fn PubBar_b() {}
1414
| ^^^^^^^^^^^^^^^^
1515

16-
error: missing `#[inline]` for a method
16+
error: missing `#[inline]` on a publicly callable function
1717
--> tests/ui/missing_inline.rs:56:5
1818
|
1919
LL | fn PubBar_a() {}
2020
| ^^^^^^^^^^^^^^^^
2121

22-
error: missing `#[inline]` for a method
22+
error: missing `#[inline]` on a publicly callable function
2323
--> tests/ui/missing_inline.rs:60:5
2424
|
2525
LL | fn PubBar_b() {}
2626
| ^^^^^^^^^^^^^^^^
2727

28-
error: missing `#[inline]` for a method
28+
error: missing `#[inline]` on a publicly callable function
2929
--> tests/ui/missing_inline.rs:64:5
3030
|
3131
LL | fn PubBar_c() {}
3232
| ^^^^^^^^^^^^^^^^
3333

34-
error: missing `#[inline]` for a method
34+
error: missing `#[inline]` on a publicly callable function
3535
--> tests/ui/missing_inline.rs:76:5
3636
|
3737
LL | pub fn PubFooImpl() {}

tests/ui/missing_inline_executable.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: missing `#[inline]` for a function
1+
error: missing `#[inline]` on a publicly callable function
22
--> tests/ui/missing_inline_executable.rs:3:1
33
|
44
LL | pub fn foo() {}

0 commit comments

Comments
 (0)