Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/data/adt.rs')
| -rw-r--r-- | crates/hir-def/src/data/adt.rs | 215 |
1 files changed, 105 insertions, 110 deletions
diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs index c8429d8b68..9db66d6e91 100644 --- a/crates/hir-def/src/data/adt.rs +++ b/crates/hir-def/src/data/adt.rs @@ -27,7 +27,6 @@ use crate::{ #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructData { pub name: Name, - pub variant_data: Arc<VariantData>, pub repr: Option<ReprOptions>, pub visibility: RawVisibility, pub flags: StructFlags, @@ -69,7 +68,6 @@ pub struct EnumVariants { #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumVariantData { pub name: Name, - pub variant_data: Arc<VariantData>, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -79,6 +77,94 @@ pub enum VariantData { Unit, } +impl VariantData { + #[inline] + pub(crate) fn variant_data_query(db: &dyn DefDatabase, id: VariantId) -> Arc<VariantData> { + db.variant_data_with_diagnostics(id).0 + } + + pub(crate) fn variant_data_with_diagnostics_query( + db: &dyn DefDatabase, + id: VariantId, + ) -> (Arc<VariantData>, DefDiagnostics) { + let (shape, types_map, (fields, diagnostics)) = match id { + VariantId::EnumVariantId(id) => { + let loc = id.lookup(db); + let item_tree = loc.id.item_tree(db); + let parent = loc.parent.lookup(db); + let krate = parent.container.krate; + let variant = &item_tree[loc.id.value]; + ( + variant.shape, + variant.types_map.clone(), + lower_fields( + db, + krate, + parent.container.local_id, + loc.id.tree_id(), + &item_tree, + krate.cfg_options(db), + FieldParent::EnumVariant(loc.id.value), + &variant.fields, + Some(item_tree[parent.id.value].visibility), + ), + ) + } + VariantId::StructId(id) => { + let loc = id.lookup(db); + let item_tree = loc.id.item_tree(db); + let krate = loc.container.krate; + let strukt = &item_tree[loc.id.value]; + ( + strukt.shape, + strukt.types_map.clone(), + lower_fields( + db, + krate, + loc.container.local_id, + loc.id.tree_id(), + &item_tree, + krate.cfg_options(db), + FieldParent::Struct(loc.id.value), + &strukt.fields, + None, + ), + ) + } + VariantId::UnionId(id) => { + let loc = id.lookup(db); + let item_tree = loc.id.item_tree(db); + let krate = loc.container.krate; + let union = &item_tree[loc.id.value]; + ( + FieldsShape::Record, + union.types_map.clone(), + lower_fields( + db, + krate, + loc.container.local_id, + loc.id.tree_id(), + &item_tree, + krate.cfg_options(db), + FieldParent::Union(loc.id.value), + &union.fields, + None, + ), + ) + } + }; + + ( + Arc::new(match shape { + FieldsShape::Record => VariantData::Record { fields, types_map }, + FieldsShape::Tuple => VariantData::Tuple { fields, types_map }, + FieldsShape::Unit => VariantData::Unit, + }), + DefDiagnostics::new(diagnostics), + ) + } +} + /// A single field of an enum variant or struct #[derive(Debug, Clone, PartialEq, Eq)] pub struct FieldData { @@ -99,13 +185,6 @@ fn repr_from_value( impl StructData { #[inline] pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { - db.struct_data_with_diagnostics(id).0 - } - - pub(crate) fn struct_data_with_diagnostics_query( - db: &dyn DefDatabase, - id: StructId, - ) -> (Arc<StructData>, DefDiagnostics) { let loc = id.lookup(db); let krate = loc.container.krate; let item_tree = loc.id.item_tree(db); @@ -130,44 +209,16 @@ impl StructData { } let strukt = &item_tree[loc.id.value]; - let (fields, diagnostics) = lower_fields( - db, - krate, - loc.container.local_id, - loc.id.tree_id(), - &item_tree, - krate.cfg_options(db), - FieldParent::Struct(loc.id.value), - &strukt.fields, - None, - ); - let types_map = strukt.types_map.clone(); - - ( - Arc::new(StructData { - name: strukt.name.clone(), - variant_data: Arc::new(match strukt.shape { - FieldsShape::Record => VariantData::Record { fields, types_map }, - FieldsShape::Tuple => VariantData::Tuple { fields, types_map }, - FieldsShape::Unit => VariantData::Unit, - }), - repr, - visibility: item_tree[strukt.visibility].clone(), - flags, - }), - DefDiagnostics::new(diagnostics), - ) + Arc::new(StructData { + name: strukt.name.clone(), + repr, + visibility: item_tree[strukt.visibility].clone(), + flags, + }) } #[inline] pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { - db.union_data_with_diagnostics(id).0 - } - - pub(crate) fn union_data_with_diagnostics_query( - db: &dyn DefDatabase, - id: UnionId, - ) -> (Arc<StructData>, DefDiagnostics) { let loc = id.lookup(db); let krate = loc.container.krate; let item_tree = loc.id.item_tree(db); @@ -182,28 +233,13 @@ impl StructData { } let union = &item_tree[loc.id.value]; - let (fields, diagnostics) = lower_fields( - db, - krate, - loc.container.local_id, - loc.id.tree_id(), - &item_tree, - krate.cfg_options(db), - FieldParent::Union(loc.id.value), - &union.fields, - None, - ); - let types_map = union.types_map.clone(); - ( - Arc::new(StructData { - name: union.name.clone(), - variant_data: Arc::new(VariantData::Record { fields, types_map }), - repr, - visibility: item_tree[union.visibility].clone(), - flags, - }), - DefDiagnostics::new(diagnostics), - ) + + Arc::new(StructData { + name: union.name.clone(), + repr, + visibility: item_tree[union.visibility].clone(), + flags, + }) } } @@ -227,16 +263,16 @@ impl EnumVariants { // [Adopted from rustc](https://github.com/rust-lang/rust/blob/bd53aa3bf7a24a70d763182303bd75e5fc51a9af/compiler/rustc_middle/src/ty/adt.rs#L446-L448) pub fn is_payload_free(&self, db: &dyn DefDatabase) -> bool { - self.variants.iter().all(|(v, _)| { + self.variants.iter().all(|&(v, _)| { // The condition check order is slightly modified from rustc // to improve performance by early returning with relatively fast checks - let variant = &db.enum_variant_data(*v).variant_data; + let variant = &db.variant_data(v.into()); if !variant.fields().is_empty() { return false; } // The outer if condition is whether this variant has const ctor or not if !matches!(variant.kind(), StructKind::Unit) { - let body = db.body((*v).into()); + let body = db.body(v.into()); // A variant with explicit discriminant if body.exprs[body.body_expr] != Expr::Missing { return false; @@ -282,43 +318,11 @@ impl EnumVariantData { db: &dyn DefDatabase, e: EnumVariantId, ) -> Arc<EnumVariantData> { - db.enum_variant_data_with_diagnostics(e).0 - } - - pub(crate) fn enum_variant_data_with_diagnostics_query( - db: &dyn DefDatabase, - e: EnumVariantId, - ) -> (Arc<EnumVariantData>, DefDiagnostics) { let loc = e.lookup(db); - let container = loc.parent.lookup(db).container; - let krate = container.krate; let item_tree = loc.id.item_tree(db); let variant = &item_tree[loc.id.value]; - let (fields, diagnostics) = lower_fields( - db, - krate, - container.local_id, - loc.id.tree_id(), - &item_tree, - krate.cfg_options(db), - FieldParent::Variant(loc.id.value), - &variant.fields, - Some(item_tree[loc.parent.lookup(db).id.value].visibility), - ); - let types_map = variant.types_map.clone(); - - ( - Arc::new(EnumVariantData { - name: variant.name.clone(), - variant_data: Arc::new(match variant.shape { - FieldsShape::Record => VariantData::Record { fields, types_map }, - FieldsShape::Tuple => VariantData::Tuple { fields, types_map }, - FieldsShape::Unit => VariantData::Unit, - }), - }), - DefDiagnostics::new(diagnostics), - ) + Arc::new(EnumVariantData { name: variant.name.clone() }) } } @@ -352,15 +356,6 @@ impl VariantData { VariantData::Unit => StructKind::Unit, } } - - #[allow(clippy::self_named_constructors)] - pub(crate) fn variant_data(db: &dyn DefDatabase, id: VariantId) -> Arc<VariantData> { - match id { - VariantId::StructId(it) => db.struct_data(it).variant_data.clone(), - VariantId::EnumVariantId(it) => db.enum_variant_data(it).variant_data.clone(), - VariantId::UnionId(it) => db.union_data(it).variant_data.clone(), - } - } } #[derive(Debug, Copy, Clone, PartialEq, Eq)] |