Skip to content

Commit 7161a70

Browse files
committed
Auto merge of rust-lang#95562 - lcnr:attr-no-encode, r=davidtwco
don't encode only locally used attrs Part of rust-lang/compiler-team#505. We now filter builtin attributes before encoding them in the crate metadata in case they should only be used in the local crate. To prevent accidental misuse `get_attrs` now requires the caller to state which attribute they are interested in. For places where that isn't trivially possible, I've added a method `fn get_attrs_unchecked` which I intend to remove in a followup PR. After this pull request landed, we can then slowly move all attributes to only be used in the local crate while being certain that we don't accidentally try to access them from extern crates. cc rust-lang#94963 (comment)
2 parents 3182532 + 107ee40 commit 7161a70

11 files changed

+27
-45
lines changed

clippy_lints/src/derivable_impls.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_help;
2-
use clippy_utils::{is_automatically_derived, is_default_equivalent, peel_blocks};
2+
use clippy_utils::{is_default_equivalent, peel_blocks};
33
use rustc_hir::{
44
def::{DefKind, Res},
55
Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
@@ -71,8 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
7171
self_ty,
7272
..
7373
}) = item.kind;
74-
if let attrs = cx.tcx.hir().attrs(item.hir_id());
75-
if !is_automatically_derived(attrs);
74+
if !cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
7675
if !item.span.from_expansion();
7776
if let Some(def_id) = trait_ref.trait_def_id();
7877
if cx.tcx.is_diagnostic_item(sym::Default, def_id);
@@ -81,6 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
8180
if let ImplItemKind::Fn(_, b) = &impl_item.kind;
8281
if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b);
8382
if let Some(adt_def) = cx.tcx.type_of(item.def_id).ty_adt_def();
83+
if let attrs = cx.tcx.hir().attrs(item.hir_id());
8484
if !attrs.iter().any(|attr| attr.doc_str().is_some());
8585
if let child_attrs = cx.tcx.hir().attrs(impl_item_hir);
8686
if !child_attrs.iter().any(|attr| attr.doc_str().is_some());

clippy_lints/src/derive.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_then};
22
use clippy_utils::paths;
33
use clippy_utils::ty::{implements_trait, is_copy};
4-
use clippy_utils::{is_automatically_derived, is_lint_allowed, match_def_path};
4+
use clippy_utils::{is_lint_allowed, match_def_path};
55
use if_chain::if_chain;
66
use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor};
77
use rustc_hir::{
@@ -171,8 +171,8 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
171171
}) = item.kind
172172
{
173173
let ty = cx.tcx.type_of(item.def_id);
174-
let attrs = cx.tcx.hir().attrs(item.hir_id());
175-
let is_automatically_derived = is_automatically_derived(attrs);
174+
let is_automatically_derived =
175+
cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
176176

177177
check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
178178
check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived);
@@ -201,7 +201,7 @@ fn check_hash_peq<'tcx>(
201201
then {
202202
// Look for the PartialEq implementations for `ty`
203203
cx.tcx.for_each_relevant_impl(peq_trait_def_id, ty, |impl_id| {
204-
let peq_is_automatically_derived = is_automatically_derived(cx.tcx.get_attrs(impl_id));
204+
let peq_is_automatically_derived = cx.tcx.has_attr(impl_id, sym::automatically_derived);
205205

206206
if peq_is_automatically_derived == hash_is_automatically_derived {
207207
return;
@@ -255,7 +255,7 @@ fn check_ord_partial_ord<'tcx>(
255255
then {
256256
// Look for the PartialOrd implementations for `ty`
257257
cx.tcx.for_each_relevant_impl(partial_ord_trait_def_id, ty, |impl_id| {
258-
let partial_ord_is_automatically_derived = is_automatically_derived(cx.tcx.get_attrs(impl_id));
258+
let partial_ord_is_automatically_derived = cx.tcx.has_attr(impl_id, sym::automatically_derived);
259259

260260
if partial_ord_is_automatically_derived == ord_is_automatically_derived {
261261
return;

clippy_lints/src/functions/must_use.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ use clippy_utils::attrs::is_proc_macro;
1313
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
1414
use clippy_utils::source::snippet_opt;
1515
use clippy_utils::ty::is_must_use_ty;
16-
use clippy_utils::{match_def_path, must_use_attr, return_ty, trait_ref_of_method};
16+
use clippy_utils::{match_def_path, return_ty, trait_ref_of_method};
1717

1818
use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT};
1919

2020
pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
2121
let attrs = cx.tcx.hir().attrs(item.hir_id());
22-
let attr = must_use_attr(attrs);
22+
let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
2323
if let hir::ItemKind::Fn(ref sig, _generics, ref body_id) = item.kind {
2424
let is_public = cx.access_levels.is_exported(item.def_id);
2525
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
@@ -44,7 +44,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
4444
let is_public = cx.access_levels.is_exported(item.def_id);
4545
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
4646
let attrs = cx.tcx.hir().attrs(item.hir_id());
47-
let attr = must_use_attr(attrs);
47+
let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
4848
if let Some(attr) = attr {
4949
check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
5050
} else if is_public && !is_proc_macro(cx.sess(), attrs) && trait_ref_of_method(cx, item.def_id).is_none() {
@@ -67,7 +67,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
6767
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
6868

6969
let attrs = cx.tcx.hir().attrs(item.hir_id());
70-
let attr = must_use_attr(attrs);
70+
let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
7171
if let Some(attr) = attr {
7272
check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
7373
} else if let hir::TraitFn::Provided(eid) = *eid {

clippy_lints/src/manual_non_exhaustive.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use clippy_utils::attrs::is_doc_hidden;
21
use clippy_utils::diagnostics::span_lint_and_then;
32
use clippy_utils::source::snippet_opt;
43
use clippy_utils::{is_lint_allowed, meets_msrv, msrvs};
@@ -161,7 +160,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
161160
let id = cx.tcx.hir().local_def_id(v.id);
162161
(matches!(v.data, hir::VariantData::Unit(_))
163162
&& v.ident.as_str().starts_with('_')
164-
&& is_doc_hidden(cx.tcx.get_attrs(id.to_def_id())))
163+
&& cx.tcx.is_doc_hidden(id.to_def_id()))
165164
.then(|| (id, v.span))
166165
});
167166
if let Some((id, span)) = iter.next()

clippy_lints/src/matches/match_wild_enum.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,5 @@ impl<'a> CommonPrefixSearcher<'a> {
193193
}
194194

195195
fn is_hidden(cx: &LateContext<'_>, variant_def: &VariantDef) -> bool {
196-
let attrs = cx.tcx.get_attrs(variant_def.def_id);
197-
clippy_utils::attrs::is_doc_hidden(attrs) || clippy_utils::attrs::is_unstable(attrs)
196+
cx.tcx.is_doc_hidden(variant_def.def_id) || cx.tcx.has_attr(variant_def.def_id, sym::unstable)
198197
}

clippy_lints/src/new_without_default.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
8585
// can't be implemented for unsafe new
8686
return;
8787
}
88-
if clippy_utils::is_doc_hidden(cx.tcx.hir().attrs(id)) {
88+
if cx.tcx.is_doc_hidden(impl_item.def_id) {
8989
// shouldn't be implemented when it is hidden in docs
9090
return;
9191
}

clippy_lints/src/partialeq_ne_impl.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use clippy_utils::diagnostics::span_lint_hir;
2-
use clippy_utils::is_automatically_derived;
32
use if_chain::if_chain;
43
use rustc_hir::{Impl, Item, ItemKind};
54
use rustc_lint::{LateContext, LateLintPass};
@@ -37,8 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
3736
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
3837
if_chain! {
3938
if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), items: impl_items, .. }) = item.kind;
40-
let attrs = cx.tcx.hir().attrs(item.hir_id());
41-
if !is_automatically_derived(attrs);
39+
if !cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
4240
if let Some(eq_trait) = cx.tcx.lang_items().eq_trait();
4341
if trait_ref.path.res.def_id() == eq_trait;
4442
then {

clippy_lints/src/significant_drop_in_scrutinee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> {
290290

291291
fn has_sig_drop_attr(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
292292
if let Some(adt) = ty.ty_adt_def() {
293-
if get_attr(cx.sess(), cx.tcx.get_attrs(adt.did()), "has_significant_drop").count() > 0 {
293+
if get_attr(cx.sess(), cx.tcx.get_attrs_unchecked(adt.did()), "has_significant_drop").count() > 0 {
294294
return true;
295295
}
296296
}

clippy_utils/src/attrs.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use rustc_ast::{ast, attr};
1+
use rustc_ast::ast;
22
use rustc_errors::Applicability;
33
use rustc_session::Session;
4+
use rustc_ast::attr;
45
use rustc_span::sym;
56
use std::str::FromStr;
67

@@ -158,7 +159,3 @@ pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool {
158159
.any(|l| attr::list_contains_name(&l, sym::hidden))
159160
}
160161

161-
/// Return true if the attributes contain `#[unstable]`
162-
pub fn is_unstable(attrs: &[ast::Attribute]) -> bool {
163-
attrs.iter().any(|attr| attr.has_name(sym::unstable))
164-
}

clippy_utils/src/lib.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use std::lazy::SyncOnceCell;
6666
use std::sync::{Mutex, MutexGuard};
6767

6868
use if_chain::if_chain;
69-
use rustc_ast::ast::{self, Attribute, LitKind};
69+
use rustc_ast::ast::{self, LitKind};
7070
use rustc_data_structures::fx::FxHashMap;
7171
use rustc_data_structures::unhash::UnhashMap;
7272
use rustc_hir as hir;
@@ -1472,12 +1472,6 @@ pub fn recurse_or_patterns<'tcx, F: FnMut(&'tcx Pat<'tcx>)>(pat: &'tcx Pat<'tcx>
14721472
}
14731473
}
14741474

1475-
/// Checks for the `#[automatically_derived]` attribute all `#[derive]`d
1476-
/// implementations have.
1477-
pub fn is_automatically_derived(attrs: &[ast::Attribute]) -> bool {
1478-
has_attr(attrs, sym::automatically_derived)
1479-
}
1480-
14811475
pub fn is_self(slf: &Param<'_>) -> bool {
14821476
if let PatKind::Binding(.., name, _) = slf.pat.kind {
14831477
name.name == kw::SelfLower
@@ -1724,11 +1718,6 @@ pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'t
17241718
None
17251719
}
17261720

1727-
// Finds the `#[must_use]` attribute, if any
1728-
pub fn must_use_attr(attrs: &[Attribute]) -> Option<&Attribute> {
1729-
attrs.iter().find(|a| a.has_name(sym::must_use))
1730-
}
1731-
17321721
// check if expr is calling method or function with #[must_use] attribute
17331722
pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
17341723
let did = match expr.kind {
@@ -1745,7 +1734,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
17451734
_ => None,
17461735
};
17471736

1748-
did.map_or(false, |did| must_use_attr(cx.tcx.get_attrs(did)).is_some())
1737+
did.map_or(false, |did| cx.tcx.has_attr(did, sym::must_use))
17491738
}
17501739

17511740
/// Checks if an expression represents the identity function

clippy_utils/src/ty.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_trait_selection::infer::InferCtxtExt;
2222
use rustc_trait_selection::traits::query::normalize::AtExt;
2323
use std::iter;
2424

25-
use crate::{match_def_path, must_use_attr, path_res, paths};
25+
use crate::{match_def_path, path_res, paths};
2626

2727
// Checks if the given type implements copy.
2828
pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
@@ -178,18 +178,18 @@ pub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
178178
// Returns whether the type has #[must_use] attribute
179179
pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
180180
match ty.kind() {
181-
ty::Adt(adt, _) => must_use_attr(cx.tcx.get_attrs(adt.did())).is_some(),
182-
ty::Foreign(ref did) => must_use_attr(cx.tcx.get_attrs(*did)).is_some(),
181+
ty::Adt(adt, _) => cx.tcx.has_attr(adt.did(), sym::must_use),
182+
ty::Foreign(did) => cx.tcx.has_attr(*did, sym::must_use),
183183
ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => {
184184
// for the Array case we don't need to care for the len == 0 case
185185
// because we don't want to lint functions returning empty arrays
186186
is_must_use_ty(cx, *ty)
187187
},
188188
ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)),
189-
ty::Opaque(ref def_id, _) => {
189+
ty::Opaque(def_id, _) => {
190190
for (predicate, _) in cx.tcx.explicit_item_bounds(*def_id) {
191191
if let ty::PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder() {
192-
if must_use_attr(cx.tcx.get_attrs(trait_predicate.trait_ref.def_id)).is_some() {
192+
if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) {
193193
return true;
194194
}
195195
}
@@ -199,7 +199,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
199199
ty::Dynamic(binder, _) => {
200200
for predicate in binder.iter() {
201201
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
202-
if must_use_attr(cx.tcx.get_attrs(trait_ref.def_id)).is_some() {
202+
if cx.tcx.has_attr(trait_ref.def_id, sym::must_use) {
203203
return true;
204204
}
205205
}

0 commit comments

Comments
 (0)