Auto merge of #95562 - lcnr:attr-no-encode, r=davidtwco
don't encode only locally used attrs Part of https://github.com/rust-lang/compiler-team/issues/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 https://github.com/rust-lang/rust/pull/94963#issuecomment-1082924289
This commit is contained in:
commit
481db40311
55 changed files with 455 additions and 467 deletions
|
@ -1072,6 +1072,9 @@ rustc_queries! {
|
|||
desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) }
|
||||
}
|
||||
|
||||
/// Returns the attributes on the item at `def_id`.
|
||||
///
|
||||
/// Do not use this directly, use `tcx.get_attrs` instead.
|
||||
query item_attrs(def_id: DefId) -> &'tcx [ast::Attribute] {
|
||||
desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) }
|
||||
separate_provide_extern
|
||||
|
|
|
@ -230,8 +230,7 @@ impl AdtDefData {
|
|||
flags |= AdtFlags::HAS_CTOR;
|
||||
}
|
||||
|
||||
let attrs = tcx.get_attrs(did);
|
||||
if tcx.sess.contains_name(&attrs, sym::fundamental) {
|
||||
if tcx.has_attr(did, sym::fundamental) {
|
||||
flags |= AdtFlags::IS_FUNDAMENTAL;
|
||||
}
|
||||
if Some(did) == tcx.lang_items().phantom_data() {
|
||||
|
|
|
@ -1148,9 +1148,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
/// `rustc_layout_scalar_valid_range` attribute.
|
||||
// FIXME(eddyb) this is an awkward spot for this method, maybe move it?
|
||||
pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
|
||||
let attrs = self.get_attrs(def_id);
|
||||
let get = |name| {
|
||||
let Some(attr) = attrs.iter().find(|a| a.has_name(name)) else {
|
||||
let Some(attr) = self.get_attr(def_id, name) else {
|
||||
return Bound::Unbounded;
|
||||
};
|
||||
debug!("layout_scalar_valid_range: attr={:?}", attr);
|
||||
|
|
|
@ -568,11 +568,8 @@ impl<T> Trait<T> for X {
|
|||
}
|
||||
}
|
||||
TargetFeatureCast(def_id) => {
|
||||
let attrs = self.get_attrs(*def_id);
|
||||
let target_spans = attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.has_name(sym::target_feature))
|
||||
.map(|attr| attr.span);
|
||||
let target_spans =
|
||||
self.get_attrs(*def_id, sym::target_feature).map(|attr| attr.span);
|
||||
diag.note(
|
||||
"functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
|
||||
);
|
||||
|
|
|
@ -8,6 +8,7 @@ use rustc_hir::def_id::{CrateNum, DefId};
|
|||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_middle::ty::normalize_erasing_regions::NormalizationError;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
|
@ -185,8 +186,8 @@ impl<'tcx> InstanceDef<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn attrs(&self, tcx: TyCtxt<'tcx>) -> ty::Attributes<'tcx> {
|
||||
tcx.get_attrs(self.def_id())
|
||||
pub fn get_attrs(&self, tcx: TyCtxt<'tcx>, attr: Symbol) -> ty::Attributes<'tcx> {
|
||||
tcx.get_attrs(self.def_id(), attr)
|
||||
}
|
||||
|
||||
/// Returns `true` if the LLVM version of this instance is unconditionally
|
||||
|
|
|
@ -14,12 +14,6 @@ pub use self::AssocItemContainer::*;
|
|||
pub use self::BorrowKind::*;
|
||||
pub use self::IntVarValue::*;
|
||||
pub use self::Variance::*;
|
||||
pub use adt::*;
|
||||
pub use assoc::*;
|
||||
pub use generics::*;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
pub use vtable::*;
|
||||
|
||||
use crate::metadata::ModChild;
|
||||
use crate::middle::privacy::AccessLevels;
|
||||
use crate::mir::{Body, GeneratorLayout};
|
||||
|
@ -28,8 +22,12 @@ use crate::ty;
|
|||
use crate::ty::fast_reject::SimplifiedType;
|
||||
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
|
||||
use crate::ty::util::Discr;
|
||||
pub use adt::*;
|
||||
pub use assoc::*;
|
||||
pub use generics::*;
|
||||
use rustc_ast as ast;
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_data_structures::intern::{Interned, WithStableHash};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
|
@ -44,6 +42,7 @@ use rustc_session::cstore::CrateStoreDyn;
|
|||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::Align;
|
||||
pub use vtable::*;
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
@ -1818,8 +1817,8 @@ impl ReprOptions {
|
|||
field_shuffle_seed ^= user_seed;
|
||||
}
|
||||
|
||||
for attr in tcx.get_attrs(did).iter() {
|
||||
for r in attr::find_repr_attrs(&tcx.sess, attr) {
|
||||
for attr in tcx.get_attrs(did, sym::repr) {
|
||||
for r in attr::parse_repr_attr(&tcx.sess, attr) {
|
||||
flags.insert(match r {
|
||||
attr::ReprC => ReprFlags::IS_C,
|
||||
attr::ReprPacked(pack) => {
|
||||
|
@ -1941,8 +1940,7 @@ impl<'tcx> FieldDef {
|
|||
}
|
||||
}
|
||||
|
||||
pub type Attributes<'tcx> = &'tcx [ast::Attribute];
|
||||
|
||||
pub type Attributes<'tcx> = impl Iterator<Item = &'tcx ast::Attribute>;
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum ImplOverlapKind {
|
||||
/// These impls are always allowed to overlap.
|
||||
|
@ -2186,8 +2184,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets the attributes of a definition.
|
||||
pub fn get_attrs(self, did: DefId) -> Attributes<'tcx> {
|
||||
// FIXME(@lcnr): Remove this function.
|
||||
pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [ast::Attribute] {
|
||||
if let Some(did) = did.as_local() {
|
||||
self.hir().attrs(self.hir().local_def_id_to_hir_id(did))
|
||||
} else {
|
||||
|
@ -2195,9 +2193,29 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets all attributes with the given name.
|
||||
pub fn get_attrs(self, did: DefId, attr: Symbol) -> ty::Attributes<'tcx> {
|
||||
let filter_fn = move |a: &&ast::Attribute| a.has_name(attr);
|
||||
if let Some(did) = did.as_local() {
|
||||
self.hir().attrs(self.hir().local_def_id_to_hir_id(did)).iter().filter(filter_fn)
|
||||
} else if cfg!(debug_assertions) && rustc_feature::is_builtin_only_local(attr) {
|
||||
bug!("tried to access the `only_local` attribute `{}` from an extern crate", attr);
|
||||
} else {
|
||||
self.item_attrs(did).iter().filter(filter_fn)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_attr(self, did: DefId, attr: Symbol) -> Option<&'tcx ast::Attribute> {
|
||||
self.get_attrs(did, attr).next()
|
||||
}
|
||||
|
||||
/// Determines whether an item is annotated with an attribute.
|
||||
pub fn has_attr(self, did: DefId, attr: Symbol) -> bool {
|
||||
self.sess.contains_name(&self.get_attrs(did), attr)
|
||||
if cfg!(debug_assertions) && !did.is_local() && rustc_feature::is_builtin_only_local(attr) {
|
||||
bug!("tried to access the `only_local` attribute `{}` from an extern crate", attr);
|
||||
} else {
|
||||
self.get_attrs(did, attr).next().is_some()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this is an `auto trait`.
|
||||
|
|
|
@ -1163,9 +1163,8 @@ pub fn normalize_opaque_types<'tcx>(
|
|||
|
||||
/// Determines whether an item is annotated with `doc(hidden)`.
|
||||
pub fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||
tcx.get_attrs(def_id)
|
||||
.iter()
|
||||
.filter_map(|attr| if attr.has_name(sym::doc) { attr.meta_item_list() } else { None })
|
||||
tcx.get_attrs(def_id, sym::doc)
|
||||
.filter_map(|attr| attr.meta_item_list())
|
||||
.any(|items| items.iter().any(|item| item.has_name(sym::hidden)))
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue