Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/signatures.rs')
-rw-r--r--crates/hir-def/src/signatures.rs219
1 files changed, 152 insertions, 67 deletions
diff --git a/crates/hir-def/src/signatures.rs b/crates/hir-def/src/signatures.rs
index ce76158151..7862049f99 100644
--- a/crates/hir-def/src/signatures.rs
+++ b/crates/hir-def/src/signatures.rs
@@ -24,7 +24,7 @@ use crate::{
attrs::AttrFlags,
db::DefDatabase,
expr_store::{
- ExpressionStore, ExpressionStoreSourceMap,
+ Body, ExpressionStore, ExpressionStoreBuilder, ExpressionStoreSourceMap,
lower::{
ExprCollector, lower_function, lower_generic_params, lower_trait, lower_type_alias,
},
@@ -44,7 +44,7 @@ fn as_name_opt(name: Option<ast::Name>) -> Name {
pub struct StructSignature {
pub name: Name,
pub generic_params: Arc<GenericParams>,
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub flags: StructFlags,
pub shape: FieldsShape,
}
@@ -71,8 +71,18 @@ bitflags! {
}
}
+#[salsa::tracked]
impl StructSignature {
- pub fn query(db: &dyn DefDatabase, id: StructId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
+ #[salsa::tracked(returns(deref))]
+ pub fn of(db: &dyn DefDatabase, id: StructId) -> Arc<Self> {
+ Self::with_source_map(db, id).0.clone()
+ }
+
+ #[salsa::tracked(returns(ref))]
+ pub fn with_source_map(
+ db: &dyn DefDatabase,
+ id: StructId,
+ ) -> (Arc<Self>, ExpressionStoreSourceMap) {
let loc = id.lookup(db);
let InFile { file_id, value: source } = loc.source(db);
let attrs = AttrFlags::query(db, id.into());
@@ -115,10 +125,12 @@ impl StructSignature {
shape,
name: as_name_opt(source.name()),
}),
- Arc::new(source_map),
+ source_map,
)
}
+}
+impl StructSignature {
#[inline]
pub fn repr(&self, db: &dyn DefDatabase, id: StructId) -> Option<ReprOptions> {
if self.flags.contains(StructFlags::HAS_REPR) {
@@ -142,12 +154,22 @@ fn adt_shape(adt_kind: ast::StructKind) -> FieldsShape {
pub struct UnionSignature {
pub name: Name,
pub generic_params: Arc<GenericParams>,
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub flags: StructFlags,
}
+#[salsa::tracked]
impl UnionSignature {
- pub fn query(db: &dyn DefDatabase, id: UnionId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
+ #[salsa::tracked(returns(deref))]
+ pub fn of(db: &dyn DefDatabase, id: UnionId) -> Arc<Self> {
+ Self::with_source_map(db, id).0.clone()
+ }
+
+ #[salsa::tracked(returns(ref))]
+ pub fn with_source_map(
+ db: &dyn DefDatabase,
+ id: UnionId,
+ ) -> (Arc<Self>, ExpressionStoreSourceMap) {
let loc = id.lookup(db);
let attrs = AttrFlags::query(db, id.into());
let mut flags = StructFlags::empty();
@@ -177,7 +199,7 @@ impl UnionSignature {
flags,
name: as_name_opt(source.name()),
}),
- Arc::new(source_map),
+ source_map,
)
}
}
@@ -196,12 +218,22 @@ bitflags! {
pub struct EnumSignature {
pub name: Name,
pub generic_params: Arc<GenericParams>,
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub flags: EnumFlags,
}
+#[salsa::tracked]
impl EnumSignature {
- pub fn query(db: &dyn DefDatabase, id: EnumId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
+ #[salsa::tracked(returns(deref))]
+ pub fn of(db: &dyn DefDatabase, id: EnumId) -> Arc<Self> {
+ Self::with_source_map(db, id).0.clone()
+ }
+
+ #[salsa::tracked(returns(ref))]
+ pub fn with_source_map(
+ db: &dyn DefDatabase,
+ id: EnumId,
+ ) -> (Arc<Self>, ExpressionStoreSourceMap) {
let loc = id.lookup(db);
let attrs = AttrFlags::query(db, id.into());
let mut flags = EnumFlags::empty();
@@ -229,10 +261,12 @@ impl EnumSignature {
flags,
name: as_name_opt(source.name()),
}),
- Arc::new(source_map),
+ source_map,
)
}
+}
+impl EnumSignature {
pub fn variant_body_type(db: &dyn DefDatabase, id: EnumId) -> IntegerType {
match AttrFlags::repr(db, id.into()) {
Some(ReprOptions { int: Some(builtin), .. }) => builtin,
@@ -257,13 +291,23 @@ bitflags::bitflags! {
pub struct ConstSignature {
pub name: Option<Name>,
// generic_params: Arc<GenericParams>,
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub type_ref: TypeRefId,
pub flags: ConstFlags,
}
+#[salsa::tracked]
impl ConstSignature {
- pub fn query(db: &dyn DefDatabase, id: ConstId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
+ #[salsa::tracked(returns(deref))]
+ pub fn of(db: &dyn DefDatabase, id: ConstId) -> Arc<Self> {
+ Self::with_source_map(db, id).0.clone()
+ }
+
+ #[salsa::tracked(returns(ref))]
+ pub fn with_source_map(
+ db: &dyn DefDatabase,
+ id: ConstId,
+ ) -> (Arc<Self>, ExpressionStoreSourceMap) {
let loc = id.lookup(db);
let module = loc.container.module(db);
@@ -282,15 +326,17 @@ impl ConstSignature {
(
Arc::new(ConstSignature {
- store: Arc::new(store),
+ store,
type_ref,
flags,
name: source.value.name().map(|it| it.as_name()),
}),
- Arc::new(source_map),
+ source_map,
)
}
+}
+impl ConstSignature {
pub fn has_body(&self) -> bool {
self.flags.contains(ConstFlags::HAS_BODY)
}
@@ -313,12 +359,23 @@ pub struct StaticSignature {
pub name: Name,
// generic_params: Arc<GenericParams>,
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub type_ref: TypeRefId,
pub flags: StaticFlags,
}
+
+#[salsa::tracked]
impl StaticSignature {
- pub fn query(db: &dyn DefDatabase, id: StaticId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
+ #[salsa::tracked(returns(deref))]
+ pub fn of(db: &dyn DefDatabase, id: StaticId) -> Arc<Self> {
+ Self::with_source_map(db, id).0.clone()
+ }
+
+ #[salsa::tracked(returns(ref))]
+ pub fn with_source_map(
+ db: &dyn DefDatabase,
+ id: StaticId,
+ ) -> (Arc<Self>, ExpressionStoreSourceMap) {
let loc = id.lookup(db);
let module = loc.container.module(db);
@@ -351,12 +408,12 @@ impl StaticSignature {
(
Arc::new(StaticSignature {
- store: Arc::new(store),
+ store,
type_ref,
flags,
name: as_name_opt(source.value.name()),
}),
- Arc::new(source_map),
+ source_map,
)
}
}
@@ -373,14 +430,24 @@ bitflags::bitflags! {
#[derive(Debug, PartialEq, Eq)]
pub struct ImplSignature {
pub generic_params: Arc<GenericParams>,
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub self_ty: TypeRefId,
pub target_trait: Option<TraitRef>,
pub flags: ImplFlags,
}
+#[salsa::tracked]
impl ImplSignature {
- pub fn query(db: &dyn DefDatabase, id: ImplId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
+ #[salsa::tracked(returns(deref))]
+ pub fn of(db: &dyn DefDatabase, id: ImplId) -> Arc<Self> {
+ Self::with_source_map(db, id).0.clone()
+ }
+
+ #[salsa::tracked(returns(ref))]
+ pub fn with_source_map(
+ db: &dyn DefDatabase,
+ id: ImplId,
+ ) -> (Arc<Self>, ExpressionStoreSourceMap) {
let loc = id.lookup(db);
let mut flags = ImplFlags::empty();
@@ -399,17 +466,13 @@ impl ImplSignature {
crate::expr_store::lower::lower_impl(db, loc.container, src, id);
(
- Arc::new(ImplSignature {
- store: Arc::new(store),
- generic_params,
- self_ty,
- target_trait,
- flags,
- }),
- Arc::new(source_map),
+ Arc::new(ImplSignature { store, generic_params, self_ty, target_trait, flags }),
+ source_map,
)
}
+}
+impl ImplSignature {
#[inline]
pub fn is_negative(&self) -> bool {
self.flags.contains(ImplFlags::NEGATIVE)
@@ -440,12 +503,22 @@ bitflags::bitflags! {
pub struct TraitSignature {
pub name: Name,
pub generic_params: Arc<GenericParams>,
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub flags: TraitFlags,
}
+#[salsa::tracked]
impl TraitSignature {
- pub fn query(db: &dyn DefDatabase, id: TraitId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
+ #[salsa::tracked(returns(deref))]
+ pub fn of(db: &dyn DefDatabase, id: TraitId) -> Arc<Self> {
+ Self::with_source_map(db, id).0.clone()
+ }
+
+ #[salsa::tracked(returns(ref))]
+ pub fn with_source_map(
+ db: &dyn DefDatabase,
+ id: TraitId,
+ ) -> (Arc<Self>, ExpressionStoreSourceMap) {
let loc = id.lookup(db);
let mut flags = TraitFlags::empty();
@@ -483,10 +556,7 @@ impl TraitSignature {
let name = as_name_opt(source.value.name());
let (store, source_map, generic_params) = lower_trait(db, loc.container, source, id);
- (
- Arc::new(TraitSignature { store: Arc::new(store), generic_params, flags, name }),
- Arc::new(source_map),
- )
+ (Arc::new(TraitSignature { store, generic_params, flags, name }), source_map)
}
}
@@ -517,18 +587,25 @@ bitflags! {
pub struct FunctionSignature {
pub name: Name,
pub generic_params: Arc<GenericParams>,
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub params: Box<[TypeRefId]>,
pub ret_type: Option<TypeRefId>,
pub abi: Option<Symbol>,
pub flags: FnFlags,
}
+#[salsa::tracked]
impl FunctionSignature {
- pub fn query(
+ #[salsa::tracked(returns(deref))]
+ pub fn of(db: &dyn DefDatabase, id: FunctionId) -> Arc<Self> {
+ Self::with_source_map(db, id).0.clone()
+ }
+
+ #[salsa::tracked(returns(ref))]
+ pub fn with_source_map(
db: &dyn DefDatabase,
id: FunctionId,
- ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
+ ) -> (Arc<Self>, ExpressionStoreSourceMap) {
let loc = id.lookup(db);
let module = loc.container.module(db);
@@ -589,17 +666,19 @@ impl FunctionSignature {
(
Arc::new(FunctionSignature {
generic_params,
- store: Arc::new(store),
+ store,
params,
ret_type,
abi,
flags,
name,
}),
- Arc::new(source_map),
+ source_map,
)
}
+}
+impl FunctionSignature {
pub fn has_body(&self) -> bool {
self.flags.contains(FnFlags::HAS_BODY)
}
@@ -656,7 +735,7 @@ impl FunctionSignature {
}
pub fn is_intrinsic(db: &dyn DefDatabase, id: FunctionId) -> bool {
- let data = db.function_signature(id);
+ let data = FunctionSignature::of(db, id);
data.flags.contains(FnFlags::RUSTC_INTRINSIC)
// Keep this around for a bit until extern "rustc-intrinsic" abis are no longer used
|| match &data.abi {
@@ -684,17 +763,24 @@ bitflags! {
pub struct TypeAliasSignature {
pub name: Name,
pub generic_params: Arc<GenericParams>,
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub bounds: Box<[TypeBound]>,
pub ty: Option<TypeRefId>,
pub flags: TypeAliasFlags,
}
+#[salsa::tracked]
impl TypeAliasSignature {
- pub fn query(
+ #[salsa::tracked(returns(deref))]
+ pub fn of(db: &dyn DefDatabase, id: TypeAliasId) -> Arc<Self> {
+ Self::with_source_map(db, id).0.clone()
+ }
+
+ #[salsa::tracked(returns(ref))]
+ pub fn with_source_map(
db: &dyn DefDatabase,
id: TypeAliasId,
- ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
+ ) -> (Arc<Self>, ExpressionStoreSourceMap) {
let loc = id.lookup(db);
let mut flags = TypeAliasFlags::empty();
@@ -714,28 +800,21 @@ impl TypeAliasSignature {
lower_type_alias(db, loc.container.module(db), source, id);
(
- Arc::new(TypeAliasSignature {
- store: Arc::new(store),
- generic_params,
- flags,
- bounds,
- name,
- ty,
- }),
- Arc::new(source_map),
+ Arc::new(TypeAliasSignature { store, generic_params, flags, bounds, name, ty }),
+ source_map,
)
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct FunctionBody {
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub parameters: Box<[PatId]>,
}
#[derive(Debug, PartialEq, Eq)]
pub struct SimpleBody {
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
}
pub type StaticBody = SimpleBody;
pub type ConstBody = SimpleBody;
@@ -743,7 +822,7 @@ pub type EnumVariantBody = SimpleBody;
#[derive(Debug, PartialEq, Eq)]
pub struct VariantFieldsBody {
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub fields: Box<[Option<ExprId>]>,
}
@@ -762,17 +841,17 @@ pub type LocalFieldId = Idx<FieldData>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VariantFields {
fields: Arena<FieldData>,
- pub store: Arc<ExpressionStore>,
+ pub store: ExpressionStore,
pub shape: FieldsShape,
}
#[salsa::tracked]
impl VariantFields {
- #[salsa::tracked(returns(clone))]
- pub(crate) fn query(
+ #[salsa::tracked(returns(ref))]
+ pub(crate) fn with_source_map(
db: &dyn DefDatabase,
id: VariantId,
- ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
+ ) -> (Arc<Self>, ExpressionStoreSourceMap) {
let (shape, result) = match id {
VariantId::EnumVariantId(id) => {
let loc = id.lookup(db);
@@ -809,20 +888,26 @@ impl VariantFields {
}
};
match result {
- Some((fields, store, source_map)) => (
- Arc::new(VariantFields { fields, store: Arc::new(store), shape }),
- Arc::new(source_map),
- ),
+ Some((fields, store, source_map)) => {
+ (Arc::new(VariantFields { fields, store, shape }), source_map)
+ }
None => {
- let (store, source_map) = ExpressionStore::empty_singleton();
- (Arc::new(VariantFields { fields: Arena::default(), store, shape }), source_map)
+ let source_map = ExpressionStoreSourceMap::default();
+ (
+ Arc::new(VariantFields {
+ fields: Arena::default(),
+ store: ExpressionStoreBuilder::default().finish().0,
+ shape,
+ }),
+ source_map,
+ )
}
}
}
#[salsa::tracked(returns(deref))]
pub(crate) fn firewall(db: &dyn DefDatabase, id: VariantId) -> Arc<Self> {
- Self::query(db, id).0
+ Self::with_source_map(db, id).0.clone()
}
}
@@ -1014,7 +1099,7 @@ impl EnumVariants {
}
// The outer if condition is whether this variant has const ctor or not
if !matches!(variant.shape, FieldsShape::Unit) {
- let body = db.body(v.into());
+ let body = Body::of(db, v.into());
// A variant with explicit discriminant
if !matches!(body[body.body_expr], crate::hir::Expr::Missing) {
return false;