Skip to content

Commit 36a27ec

Browse files
committed
Auto merge of rust-lang#79519 - cjgillot:noattr, r=wesleywiser
Store HIR attributes in a side table Same idea as rust-lang#72015 but for attributes. The objective is to reduce incr-comp invalidations due to modified attributes. Notably, those due to modified doc comments. Implementation: - collect attributes during AST->HIR lowering, in `LocalDefId -> ItemLocalId -> &[Attributes]` nested tables; - access the attributes through a `hir_owner_attrs` query; - local refactorings to use this access; - remove `attrs` from HIR data structures one-by-one. Change in behaviour: - the HIR visitor traverses all attributes at once instead of parent-by-parent; - attribute arrays are sometimes duplicated: for statements and variant constructors; - as a consequence, attributes are marked as used after unused-attribute lint emission to avoid duplicate lints. ~~Current bug: the lint level is not correctly applied in `std::backtrace_rs`, triggering an unused attribute warning on `#![no_std]`. I welcome suggestions.~~
2 parents cb8bc0b + 6c66826 commit 36a27ec

26 files changed

+103
-81
lines changed

clippy_lints/src/attrs.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,15 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
276276
}
277277

278278
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
279+
let attrs = cx.tcx.hir().attrs(item.hir_id());
279280
if is_relevant_item(cx, item) {
280-
check_attrs(cx, item.span, item.ident.name, &item.attrs)
281+
check_attrs(cx, item.span, item.ident.name, attrs)
281282
}
282283
match item.kind {
283284
ItemKind::ExternCrate(..) | ItemKind::Use(..) => {
284-
let skip_unused_imports = item.attrs.iter().any(|attr| attr.has_name(sym::macro_use));
285+
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
285286

286-
for attr in item.attrs {
287+
for attr in attrs {
287288
if in_external_macro(cx.sess(), attr.span) {
288289
return;
289290
}
@@ -353,13 +354,13 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
353354

354355
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
355356
if is_relevant_impl(cx, item) {
356-
check_attrs(cx, item.span, item.ident.name, &item.attrs)
357+
check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()))
357358
}
358359
}
359360

360361
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
361362
if is_relevant_trait(cx, item) {
362-
check_attrs(cx, item.span, item.ident.name, &item.attrs)
363+
check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()))
363364
}
364365
}
365366
}

clippy_lints/src/cognitive_complexity.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ impl CognitiveComplexity {
7676

7777
if rust_cc > self.limit.limit() {
7878
let fn_span = match kind {
79-
FnKind::ItemFn(ident, _, _, _, _) | FnKind::Method(ident, _, _, _) => ident.span,
80-
FnKind::Closure(_) => {
79+
FnKind::ItemFn(ident, _, _, _) | FnKind::Method(ident, _, _) => ident.span,
80+
FnKind::Closure => {
8181
let header_span = body_span.with_hi(decl.output.span().lo());
8282
let pos = snippet_opt(cx, header_span).and_then(|snip| {
8383
let low_offset = snip.find('|')?;

clippy_lints/src/derive.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
170170
}) = item.kind
171171
{
172172
let ty = cx.tcx.type_of(item.def_id);
173-
let is_automatically_derived = is_automatically_derived(&*item.attrs);
173+
let attrs = cx.tcx.hir().attrs(item.hir_id());
174+
let is_automatically_derived = is_automatically_derived(attrs);
174175

175176
check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
176177
check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived);

clippy_lints/src/doc.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,14 @@ impl_lint_pass!(DocMarkdown =>
208208
);
209209

210210
impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
211-
fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) {
212-
check_attrs(cx, &self.valid_idents, &krate.item.attrs);
211+
fn check_crate(&mut self, cx: &LateContext<'tcx>, _: &'tcx hir::Crate<'_>) {
212+
let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID);
213+
check_attrs(cx, &self.valid_idents, attrs);
213214
}
214215

215216
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
216-
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
217+
let attrs = cx.tcx.hir().attrs(item.hir_id());
218+
let headers = check_attrs(cx, &self.valid_idents, attrs);
217219
match item.kind {
218220
hir::ItemKind::Fn(ref sig, _, body_id) => {
219221
if !(is_entrypoint_fn(cx, item.def_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
@@ -249,7 +251,8 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
249251
}
250252

251253
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
252-
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
254+
let attrs = cx.tcx.hir().attrs(item.hir_id());
255+
let headers = check_attrs(cx, &self.valid_idents, attrs);
253256
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
254257
if !in_external_macro(cx.tcx.sess, item.span) {
255258
lint_for_missing_headers(cx, item.hir_id(), item.span, sig, headers, None, None);
@@ -258,7 +261,8 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
258261
}
259262

260263
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
261-
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
264+
let attrs = cx.tcx.hir().attrs(item.hir_id());
265+
let headers = check_attrs(cx, &self.valid_idents, attrs);
262266
if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) {
263267
return;
264268
}

clippy_lints/src/exhaustive_items.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ impl LateLintPass<'_> for ExhaustiveItems {
7373
if_chain! {
7474
if let ItemKind::Enum(..) | ItemKind::Struct(..) = item.kind;
7575
if cx.access_levels.is_exported(item.hir_id());
76-
if !item.attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
76+
let attrs = cx.tcx.hir().attrs(item.hir_id());
77+
if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
7778
then {
7879
let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind {
7980
if v.fields().iter().any(|f| !f.vis.node.is_pub()) {

clippy_lints/src/functions.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,9 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
251251
hir_id: hir::HirId,
252252
) {
253253
let unsafety = match kind {
254-
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _, _) => unsafety,
255-
intravisit::FnKind::Method(_, sig, _, _) => sig.header.unsafety,
256-
intravisit::FnKind::Closure(_) => return,
254+
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _) => unsafety,
255+
intravisit::FnKind::Method(_, sig, _) => sig.header.unsafety,
256+
intravisit::FnKind::Closure => return,
257257
};
258258

259259
// don't warn for implementations, it's not their fault
@@ -267,9 +267,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
267267
..
268268
},
269269
_,
270-
_,
271270
)
272-
| intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _, _) => {
271+
| intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _) => {
273272
self.check_arg_number(cx, decl, span.with_hi(decl.output.span().hi()))
274273
},
275274
_ => {},
@@ -281,7 +280,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
281280
}
282281

283282
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
284-
let attr = must_use_attr(&item.attrs);
283+
let attrs = cx.tcx.hir().attrs(item.hir_id());
284+
let attr = must_use_attr(attrs);
285285
if let hir::ItemKind::Fn(ref sig, ref _generics, ref body_id) = item.kind {
286286
let is_public = cx.access_levels.is_exported(item.hir_id());
287287
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
@@ -292,7 +292,7 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
292292
check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr);
293293
return;
294294
}
295-
if is_public && !is_proc_macro(cx.sess(), &item.attrs) && attr_by_name(&item.attrs, "no_mangle").is_none() {
295+
if is_public && !is_proc_macro(cx.sess(), attrs) && attr_by_name(attrs, "no_mangle").is_none() {
296296
check_must_use_candidate(
297297
cx,
298298
&sig.decl,
@@ -313,11 +313,12 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
313313
if is_public && trait_ref_of_method(cx, item.hir_id()).is_none() {
314314
check_result_unit_err(cx, &sig.decl, item.span, fn_header_span);
315315
}
316-
let attr = must_use_attr(&item.attrs);
316+
let attrs = cx.tcx.hir().attrs(item.hir_id());
317+
let attr = must_use_attr(attrs);
317318
if let Some(attr) = attr {
318319
check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr);
319320
} else if is_public
320-
&& !is_proc_macro(cx.sess(), &item.attrs)
321+
&& !is_proc_macro(cx.sess(), attrs)
321322
&& trait_ref_of_method(cx, item.hir_id()).is_none()
322323
{
323324
check_must_use_candidate(
@@ -345,15 +346,16 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
345346
check_result_unit_err(cx, &sig.decl, item.span, fn_header_span);
346347
}
347348

348-
let attr = must_use_attr(&item.attrs);
349+
let attrs = cx.tcx.hir().attrs(item.hir_id());
350+
let attr = must_use_attr(attrs);
349351
if let Some(attr) = attr {
350352
check_needless_must_use(cx, &sig.decl, item.hir_id(), item.span, fn_header_span, attr);
351353
}
352354
if let hir::TraitFn::Provided(eid) = *eid {
353355
let body = cx.tcx.hir().body(eid);
354356
Self::check_raw_ptr(cx, sig.header.unsafety, &sig.decl, body, item.hir_id());
355357

356-
if attr.is_none() && is_public && !is_proc_macro(cx.sess(), &item.attrs) {
358+
if attr.is_none() && is_public && !is_proc_macro(cx.sess(), attrs) {
357359
check_must_use_candidate(
358360
cx,
359361
&sig.decl,

clippy_lints/src/future_not_send.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
5858
_: Span,
5959
hir_id: HirId,
6060
) {
61-
if let FnKind::Closure(_) = kind {
61+
if let FnKind::Closure = kind {
6262
return;
6363
}
6464
let ret_ty = utils::return_ty(cx, hir_id);

clippy_lints/src/inline_fn_without_body.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ declare_lint_pass!(InlineFnWithoutBody => [INLINE_FN_WITHOUT_BODY]);
3434
impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody {
3535
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
3636
if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind {
37-
check_attrs(cx, item.ident.name, &item.attrs);
37+
let attrs = cx.tcx.hir().attrs(item.hir_id());
38+
check_attrs(cx, item.ident.name, attrs);
3839
}
3940
}
4041
}

clippy_lints/src/loops.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
578578
// also check for empty `loop {}` statements, skipping those in #[panic_handler]
579579
if block.stmts.is_empty() && block.expr.is_none() && !is_in_panic_handler(cx, expr) {
580580
let msg = "empty `loop {}` wastes CPU cycles";
581-
let help = if is_no_std_crate(cx.tcx.hir().krate()) {
581+
let help = if is_no_std_crate(cx) {
582582
"you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body"
583583
} else {
584584
"you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body"

clippy_lints/src/macro_use.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
107107
if_chain! {
108108
if cx.sess().opts.edition >= Edition::Edition2018;
109109
if let hir::ItemKind::Use(path, _kind) = &item.kind;
110-
if let Some(mac_attr) = item
111-
.attrs
110+
let attrs = cx.tcx.hir().attrs(item.hir_id());
111+
if let Some(mac_attr) = attrs
112112
.iter()
113113
.find(|attr| attr.ident().map(|s| s.to_string()) == Some("macro_use".to_string()));
114114
if let Res::Def(DefKind::Mod, id) = path.res;

clippy_lints/src/main_recursion.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ pub struct MainRecursion {
3232
impl_lint_pass!(MainRecursion => [MAIN_RECURSION]);
3333

3434
impl LateLintPass<'_> for MainRecursion {
35-
fn check_crate(&mut self, _: &LateContext<'_>, krate: &Crate<'_>) {
36-
self.has_no_std_attr = is_no_std_crate(krate);
35+
fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
36+
self.has_no_std_attr = is_no_std_crate(cx);
3737
}
3838

3939
fn check_expr_post(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {

clippy_lints/src/matches.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1207,11 +1207,11 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr
12071207
if b0 != b1;
12081208
let if_guard = &b0_arms[0].guard;
12091209
if if_guard.is_none() || b0_arms.len() == 1;
1210-
if b0_arms[0].attrs.is_empty();
1210+
if cx.tcx.hir().attrs(b0_arms[0].hir_id).is_empty();
12111211
if b0_arms[1..].iter()
12121212
.all(|arm| {
12131213
find_bool_lit(&arm.body.kind, desugared).map_or(false, |b| b == b0) &&
1214-
arm.guard.is_none() && arm.attrs.is_empty()
1214+
arm.guard.is_none() && cx.tcx.hir().attrs(arm.hir_id).is_empty()
12151215
});
12161216
then {
12171217
// The suggestion may be incorrect, because some arms can have `cfg` attributes

clippy_lints/src/misc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
278278
span: Span,
279279
_: HirId,
280280
) {
281-
if let FnKind::Closure(_) = k {
281+
if let FnKind::Closure = k {
282282
// Does not apply to closures
283283
return;
284284
}

clippy_lints/src/missing_const_for_fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
133133
return;
134134
}
135135
},
136-
FnKind::Closure(..) => return,
136+
FnKind::Closure => return,
137137
}
138138

139139
let mir = cx.tcx.optimized_mir(def_id);

clippy_lints/src/missing_doc.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
127127
}
128128

129129
fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) {
130-
self.check_missing_docs_attrs(cx, &krate.item.attrs, krate.item.span, "the", "crate");
130+
let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID);
131+
self.check_missing_docs_attrs(cx, attrs, krate.item.span, "the", "crate");
131132
}
132133

133134
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
@@ -160,13 +161,15 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
160161

161162
let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
162163

163-
self.check_missing_docs_attrs(cx, &it.attrs, it.span, article, desc);
164+
let attrs = cx.tcx.hir().attrs(it.hir_id());
165+
self.check_missing_docs_attrs(cx, attrs, it.span, article, desc);
164166
}
165167

166168
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) {
167169
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
168170

169-
self.check_missing_docs_attrs(cx, &trait_item.attrs, trait_item.span, article, desc);
171+
let attrs = cx.tcx.hir().attrs(trait_item.hir_id());
172+
self.check_missing_docs_attrs(cx, attrs, trait_item.span, article, desc);
170173
}
171174

172175
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
@@ -181,16 +184,19 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
181184
}
182185

183186
let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
184-
self.check_missing_docs_attrs(cx, &impl_item.attrs, impl_item.span, article, desc);
187+
let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
188+
self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
185189
}
186190

187191
fn check_struct_field(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::StructField<'_>) {
188192
if !sf.is_positional() {
189-
self.check_missing_docs_attrs(cx, &sf.attrs, sf.span, "a", "struct field");
193+
let attrs = cx.tcx.hir().attrs(sf.hir_id);
194+
self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field");
190195
}
191196
}
192197

193198
fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) {
194-
self.check_missing_docs_attrs(cx, &v.attrs, v.span, "a", "variant");
199+
let attrs = cx.tcx.hir().attrs(v.id);
200+
self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
195201
}
196202
}

clippy_lints/src/missing_inline.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
9393
match it.kind {
9494
hir::ItemKind::Fn(..) => {
9595
let desc = "a function";
96-
check_missing_inline_attrs(cx, &it.attrs, it.span, desc);
96+
let attrs = cx.tcx.hir().attrs(it.hir_id());
97+
check_missing_inline_attrs(cx, attrs, it.span, desc);
9798
},
9899
hir::ItemKind::Trait(ref _is_auto, ref _unsafe, ref _generics, ref _bounds, trait_items) => {
99100
// note: we need to check if the trait is exported so we can't use
@@ -108,7 +109,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
108109
// an impl is not provided
109110
let desc = "a default trait method";
110111
let item = cx.tcx.hir().trait_item(tit.id);
111-
check_missing_inline_attrs(cx, &item.attrs, item.span, desc);
112+
let attrs = cx.tcx.hir().attrs(item.hir_id());
113+
check_missing_inline_attrs(cx, attrs, item.span, desc);
112114
}
113115
},
114116
}
@@ -160,6 +162,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
160162
}
161163
}
162164

163-
check_missing_inline_attrs(cx, &impl_item.attrs, impl_item.span, desc);
165+
let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
166+
check_missing_inline_attrs(cx, attrs, impl_item.span, desc);
164167
}
165168
}

clippy_lints/src/needless_borrow.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrow {
115115
}
116116
}
117117

118-
fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) {
119-
if is_automatically_derived(item.attrs) {
118+
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
119+
let attrs = cx.tcx.hir().attrs(item.hir_id());
120+
if is_automatically_derived(attrs) {
120121
debug_assert!(self.derived_item.is_none());
121122
self.derived_item = Some(item.def_id);
122123
}

clippy_lints/src/needless_pass_by_value.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,14 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
8080
}
8181

8282
match kind {
83-
FnKind::ItemFn(.., header, _, attrs) => {
83+
FnKind::ItemFn(.., header, _) => {
84+
let attrs = cx.tcx.hir().attrs(hir_id);
8485
if header.abi != Abi::Rust || requires_exact_signature(attrs) {
8586
return;
8687
}
8788
},
8889
FnKind::Method(..) => (),
89-
FnKind::Closure(..) => return,
90+
FnKind::Closure => return,
9091
}
9192

9293
// Exclude non-inherent impls

clippy_lints/src/panic_in_result_fn.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicInResultFn {
4343
span: Span,
4444
hir_id: hir::HirId,
4545
) {
46-
if !matches!(fn_kind, FnKind::Closure(_))
47-
&& is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type)
48-
{
46+
if !matches!(fn_kind, FnKind::Closure) && is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type) {
4947
lint_impl_body(cx, span, body);
5048
}
5149
}

clippy_lints/src/partialeq_ne_impl.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
3535
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
3636
if_chain! {
3737
if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), items: impl_items, .. }) = item.kind;
38-
if !is_automatically_derived(&*item.attrs);
38+
let attrs = cx.tcx.hir().attrs(item.hir_id());
39+
if !is_automatically_derived(attrs);
3940
if let Some(eq_trait) = cx.tcx.lang_items().eq_trait();
4041
if trait_ref.path.res.def_id() == eq_trait;
4142
then {

0 commit comments

Comments
 (0)