Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/data.rs')
-rw-r--r--crates/hir-def/src/data.rs166
1 files changed, 125 insertions, 41 deletions
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index b251564016..e1fe13f9af 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -12,7 +12,7 @@ use crate::{
ConstId, ExternCrateId, FunctionId, HasModule, ImplId, ItemContainerId, ItemLoc, Lookup,
Macro2Id, MacroRulesId, ProcMacroId, StaticId, TraitAliasId, TraitId, TypeAliasId,
db::DefDatabase,
- item_tree::{self, FnFlags, ModItem},
+ item_tree::{self, FnFlags, ModItem, StaticFlags},
nameres::proc_macro::{ProcMacroKind, parse_macro_name_and_helper_attrs},
path::ImportAlias,
type_ref::{TraitRef, TypeBound, TypeRefId, TypesMap},
@@ -27,9 +27,8 @@ pub struct FunctionData {
pub visibility: RawVisibility,
pub abi: Option<Symbol>,
pub legacy_const_generics_indices: Option<Box<Box<[u32]>>>,
- pub rustc_allow_incoherent_impl: bool,
pub types_map: Arc<TypesMap>,
- flags: FnFlags,
+ pub flags: FnFlags,
}
impl FunctionData {
@@ -72,7 +71,9 @@ impl FunctionData {
}
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
- let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists();
+ if attrs.by_key(&sym::rustc_allow_incoherent_impl).exists() {
+ flags |= FnFlags::RUSTC_ALLOW_INCOHERENT_IMPL;
+ }
if flags.contains(FnFlags::HAS_UNSAFE_KW)
&& attrs.by_key(&sym::rustc_deprecated_safe_2024).exists()
{
@@ -101,51 +102,65 @@ impl FunctionData {
legacy_const_generics_indices: attrs.rustc_legacy_const_generics(),
types_map: func.types_map.clone(),
flags,
- rustc_allow_incoherent_impl,
})
}
+ #[inline]
pub fn has_body(&self) -> bool {
self.flags.contains(FnFlags::HAS_BODY)
}
/// True if the first param is `self`. This is relevant to decide whether this
/// can be called as a method.
+ #[inline]
pub fn has_self_param(&self) -> bool {
self.flags.contains(FnFlags::HAS_SELF_PARAM)
}
+ #[inline]
pub fn is_default(&self) -> bool {
self.flags.contains(FnFlags::HAS_DEFAULT_KW)
}
+ #[inline]
pub fn is_const(&self) -> bool {
self.flags.contains(FnFlags::HAS_CONST_KW)
}
+ #[inline]
pub fn is_async(&self) -> bool {
self.flags.contains(FnFlags::HAS_ASYNC_KW)
}
+ #[inline]
pub fn is_unsafe(&self) -> bool {
self.flags.contains(FnFlags::HAS_UNSAFE_KW)
}
+ #[inline]
pub fn is_deprecated_safe_2024(&self) -> bool {
self.flags.contains(FnFlags::DEPRECATED_SAFE_2024)
}
+ #[inline]
pub fn is_safe(&self) -> bool {
self.flags.contains(FnFlags::HAS_SAFE_KW)
}
+ #[inline]
pub fn is_varargs(&self) -> bool {
self.flags.contains(FnFlags::IS_VARARGS)
}
+ #[inline]
pub fn has_target_feature(&self) -> bool {
self.flags.contains(FnFlags::HAS_TARGET_FEATURE)
}
+
+ #[inline]
+ pub fn rustc_allow_incoherent_impl(&self) -> bool {
+ self.flags.contains(FnFlags::RUSTC_ALLOW_INCOHERENT_IMPL)
+ }
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -153,15 +168,37 @@ pub struct TypeAliasData {
pub name: Name,
pub type_ref: Option<TypeRefId>,
pub visibility: RawVisibility,
- pub is_extern: bool,
- pub rustc_has_incoherent_inherent_impls: bool,
- pub rustc_allow_incoherent_impl: bool,
+ pub flags: TypeAliasFlags,
/// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl).
pub bounds: Box<[TypeBound]>,
pub types_map: Arc<TypesMap>,
}
+bitflags::bitflags! {
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub struct TypeAliasFlags: u8 {
+ const IS_EXTERN = 1 << 0;
+ const RUSTC_HAS_INCOHERENT_INHERENT_IMPLS = 1 << 1;
+ const RUSTC_ALLOW_INCOHERENT_IMPL = 1 << 2;
+ }
+}
+
impl TypeAliasData {
+ #[inline]
+ pub fn is_extern(&self) -> bool {
+ self.flags.contains(TypeAliasFlags::IS_EXTERN)
+ }
+
+ #[inline]
+ pub fn rustc_has_incoherent_inherent_impls(&self) -> bool {
+ self.flags.contains(TypeAliasFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS)
+ }
+
+ #[inline]
+ pub fn rustc_allow_incoherent_impl(&self) -> bool {
+ self.flags.contains(TypeAliasFlags::RUSTC_ALLOW_INCOHERENT_IMPL)
+ }
+
pub(crate) fn type_alias_data_query(
db: &dyn DefDatabase,
typ: TypeAliasId,
@@ -180,17 +217,24 @@ impl TypeAliasData {
loc.container.module(db).krate(),
ModItem::from(loc.id.value).into(),
);
- let rustc_has_incoherent_inherent_impls =
- attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists();
- let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists();
+
+ let mut flags = TypeAliasFlags::empty();
+
+ if matches!(loc.container, ItemContainerId::ExternBlockId(_)) {
+ flags |= TypeAliasFlags::IS_EXTERN;
+ }
+ if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() {
+ flags |= TypeAliasFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS;
+ }
+ if attrs.by_key(&sym::rustc_allow_incoherent_impl).exists() {
+ flags |= TypeAliasFlags::RUSTC_ALLOW_INCOHERENT_IMPL;
+ }
Arc::new(TypeAliasData {
name: typ.name.clone(),
type_ref: typ.type_ref,
visibility,
- is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)),
- rustc_has_incoherent_inherent_impls,
- rustc_allow_incoherent_impl,
+ flags,
bounds: typ.bounds.clone(),
types_map: typ.types_map.clone(),
})
@@ -199,7 +243,7 @@ impl TypeAliasData {
bitflags::bitflags! {
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
- pub struct TraitFlags: u8 {
+ pub struct TraitFlags: u16 {
const IS_AUTO = 1 << 0;
const IS_UNSAFE = 1 << 1;
const IS_FUNDAMENTAL = 1 << 2;
@@ -332,9 +376,9 @@ impl Macro2Data {
let loc = makro.lookup(db);
let item_tree = loc.id.item_tree(db);
let makro = &item_tree[loc.id.value];
+ let attrs = item_tree.attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into());
- let helpers = item_tree
- .attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into())
+ let helpers = attrs
.by_key(&sym::rustc_builtin_macro)
.tt_values()
.next()
@@ -362,11 +406,9 @@ impl MacroRulesData {
let loc = makro.lookup(db);
let item_tree = loc.id.item_tree(db);
let makro = &item_tree[loc.id.value];
+ let attrs = item_tree.attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into());
- let macro_export = item_tree
- .attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into())
- .by_key(&sym::macro_export)
- .exists();
+ let macro_export = attrs.by_key(&sym::macro_export).exists();
Arc::new(MacroRulesData { name: makro.name.clone(), macro_export })
}
@@ -387,11 +429,9 @@ impl ProcMacroData {
let loc = makro.lookup(db);
let item_tree = loc.id.item_tree(db);
let makro = &item_tree[loc.id.value];
+ let attrs = item_tree.attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into());
- let (name, helpers) = if let Some(def) = item_tree
- .attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into())
- .parse_proc_macro_decl(&makro.name)
- {
+ let (name, helpers) = if let Some(def) = attrs.parse_proc_macro_decl(&makro.name) {
(
def.name,
match def.kind {
@@ -404,6 +444,7 @@ impl ProcMacroData {
stdx::never!("proc macro declaration is not a proc macro");
(makro.name.clone(), None)
};
+
Arc::new(ProcMacroData { name, helpers })
}
}
@@ -450,9 +491,16 @@ pub struct ConstData {
pub name: Option<Name>,
pub type_ref: TypeRefId,
pub visibility: RawVisibility,
- pub rustc_allow_incoherent_impl: bool,
- pub has_body: bool,
pub types_map: Arc<TypesMap>,
+ pub flags: ConstFlags,
+}
+
+bitflags::bitflags! {
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+ pub struct ConstFlags: u8 {
+ const RUSTC_ALLOW_INCOHERENT_IMPL = 1 << 0;
+ const HAS_BODY = 1 << 1;
+ }
}
impl ConstData {
@@ -465,21 +513,38 @@ impl ConstData {
} else {
item_tree[konst.visibility].clone()
};
+ let attrs = item_tree.attrs(
+ db,
+ loc.container.module(db).krate(),
+ ModItem::from(loc.id.value).into(),
+ );
- let rustc_allow_incoherent_impl = item_tree
- .attrs(db, loc.container.module(db).krate(), ModItem::from(loc.id.value).into())
- .by_key(&sym::rustc_allow_incoherent_impl)
- .exists();
+ let mut flags = ConstFlags::empty();
+ if attrs.by_key(&sym::rustc_allow_incoherent_impl).exists() {
+ flags |= ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL;
+ }
+ if konst.has_body {
+ flags |= ConstFlags::HAS_BODY;
+ }
Arc::new(ConstData {
name: konst.name.clone(),
type_ref: konst.type_ref,
visibility,
- rustc_allow_incoherent_impl,
- has_body: konst.has_body,
+ flags,
types_map: konst.types_map.clone(),
})
}
+
+ #[inline]
+ pub fn rustc_allow_incoherent_impl(&self) -> bool {
+ self.flags.contains(ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL)
+ }
+
+ #[inline]
+ pub fn has_body(&self) -> bool {
+ self.flags.contains(ConstFlags::HAS_BODY)
+ }
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -487,11 +552,8 @@ pub struct StaticData {
pub name: Name,
pub type_ref: TypeRefId,
pub visibility: RawVisibility,
- pub mutable: bool,
- pub is_extern: bool,
- pub has_safe_kw: bool,
- pub has_unsafe_kw: bool,
pub types_map: Arc<TypesMap>,
+ pub flags: StaticFlags,
}
impl StaticData {
@@ -500,17 +562,39 @@ impl StaticData {
let item_tree = loc.id.item_tree(db);
let statik = &item_tree[loc.id.value];
+ let mut flags = statik.flags;
+ if matches!(loc.container, ItemContainerId::ExternBlockId(_)) {
+ flags |= StaticFlags::IS_EXTERN;
+ }
+
Arc::new(StaticData {
name: statik.name.clone(),
type_ref: statik.type_ref,
visibility: item_tree[statik.visibility].clone(),
- mutable: statik.mutable,
- is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)),
- has_safe_kw: statik.has_safe_kw,
- has_unsafe_kw: statik.has_unsafe_kw,
+ flags,
types_map: statik.types_map.clone(),
})
}
+
+ #[inline]
+ pub fn is_extern(&self) -> bool {
+ self.flags.contains(StaticFlags::IS_EXTERN)
+ }
+
+ #[inline]
+ pub fn mutable(&self) -> bool {
+ self.flags.contains(StaticFlags::MUTABLE)
+ }
+
+ #[inline]
+ pub fn has_safe_kw(&self) -> bool {
+ self.flags.contains(StaticFlags::HAS_SAFE_KW)
+ }
+
+ #[inline]
+ pub fn has_unsafe_kw(&self) -> bool {
+ self.flags.contains(StaticFlags::HAS_UNSAFE_KW)
+ }
}
fn trait_vis(db: &dyn DefDatabase, trait_id: TraitId) -> RawVisibility {