aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r--crates/ra_hir/src/code_model.rs54
1 files changed, 43 insertions, 11 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index a7bba85e1..bb1596bed 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -11,9 +11,9 @@ use hir_def::{
11 per_ns::PerNs, 11 per_ns::PerNs,
12 resolver::{HasResolver, TypeNs}, 12 resolver::{HasResolver, TypeNs},
13 type_ref::{Mutability, TypeRef}, 13 type_ref::{Mutability, TypeRef},
14 AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, 14 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId,
15 ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, 15 HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId,
16 StaticId, StructId, TraitId, TypeAliasId, UnionId, 16 Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
17}; 17};
18use hir_expand::{ 18use hir_expand::{
19 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
@@ -383,6 +383,28 @@ impl Union {
383 pub fn ty(self, db: &impl HirDatabase) -> Ty { 383 pub fn ty(self, db: &impl HirDatabase) -> Ty {
384 db.type_for_def(self.into(), Namespace::Types) 384 db.type_for_def(self.into(), Namespace::Types)
385 } 385 }
386
387 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
388 db.union_data(self.id)
389 .variant_data
390 .fields()
391 .iter()
392 .map(|(id, _)| StructField { parent: self.into(), id })
393 .collect()
394 }
395
396 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
397 db.union_data(self.id)
398 .variant_data
399 .fields()
400 .iter()
401 .find(|(_id, data)| data.name == *name)
402 .map(|(id, _)| StructField { parent: self.into(), id })
403 }
404
405 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
406 db.union_data(self.id).variant_data.clone()
407 }
386} 408}
387 409
388#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 410#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -501,14 +523,16 @@ impl Adt {
501#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 523#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
502pub enum VariantDef { 524pub enum VariantDef {
503 Struct(Struct), 525 Struct(Struct),
526 Union(Union),
504 EnumVariant(EnumVariant), 527 EnumVariant(EnumVariant),
505} 528}
506impl_froms!(VariantDef: Struct, EnumVariant); 529impl_froms!(VariantDef: Struct, Union, EnumVariant);
507 530
508impl VariantDef { 531impl VariantDef {
509 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { 532 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
510 match self { 533 match self {
511 VariantDef::Struct(it) => it.fields(db), 534 VariantDef::Struct(it) => it.fields(db),
535 VariantDef::Union(it) => it.fields(db),
512 VariantDef::EnumVariant(it) => it.fields(db), 536 VariantDef::EnumVariant(it) => it.fields(db),
513 } 537 }
514 } 538 }
@@ -516,6 +540,7 @@ impl VariantDef {
516 pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 540 pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
517 match self { 541 match self {
518 VariantDef::Struct(it) => it.field(db, name), 542 VariantDef::Struct(it) => it.field(db, name),
543 VariantDef::Union(it) => it.field(db, name),
519 VariantDef::EnumVariant(it) => it.field(db, name), 544 VariantDef::EnumVariant(it) => it.field(db, name),
520 } 545 }
521 } 546 }
@@ -523,6 +548,7 @@ impl VariantDef {
523 pub fn module(self, db: &impl HirDatabase) -> Module { 548 pub fn module(self, db: &impl HirDatabase) -> Module {
524 match self { 549 match self {
525 VariantDef::Struct(it) => it.module(db), 550 VariantDef::Struct(it) => it.module(db),
551 VariantDef::Union(it) => it.module(db),
526 VariantDef::EnumVariant(it) => it.module(db), 552 VariantDef::EnumVariant(it) => it.module(db),
527 } 553 }
528 } 554 }
@@ -530,6 +556,7 @@ impl VariantDef {
530 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 556 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
531 match self { 557 match self {
532 VariantDef::Struct(it) => it.variant_data(db), 558 VariantDef::Struct(it) => it.variant_data(db),
559 VariantDef::Union(it) => it.variant_data(db),
533 VariantDef::EnumVariant(it) => it.variant_data(db), 560 VariantDef::EnumVariant(it) => it.variant_data(db),
534 } 561 }
535 } 562 }
@@ -1056,19 +1083,24 @@ impl Type {
1056 } 1083 }
1057 1084
1058 pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { 1085 pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> {
1059 let mut res = Vec::new();
1060 if let Ty::Apply(a_ty) = &self.ty.value { 1086 if let Ty::Apply(a_ty) = &self.ty.value {
1061 match a_ty.ctor { 1087 match a_ty.ctor {
1062 ty::TypeCtor::Adt(Adt::Struct(s)) => { 1088 ty::TypeCtor::Adt(AdtId::StructId(s)) => {
1063 for field in s.fields(db) { 1089 let var_def = s.into();
1064 let ty = field.ty(db).subst(&a_ty.parameters); 1090 return db
1065 res.push((field, self.derived(ty))); 1091 .field_types(var_def)
1066 } 1092 .iter()
1093 .map(|(local_id, ty)| {
1094 let def = StructField { parent: var_def.into(), id: local_id };
1095 let ty = ty.clone().subst(&a_ty.parameters);
1096 (def, self.derived(ty))
1097 })
1098 .collect();
1067 } 1099 }
1068 _ => {} 1100 _ => {}
1069 } 1101 }
1070 }; 1102 };
1071 res 1103 Vec::new()
1072 } 1104 }
1073 1105
1074 pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec<Type> { 1106 pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec<Type> {