diff options
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 54 |
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 | }; |
18 | use hir_expand::{ | 18 | use 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)] |
502 | pub enum VariantDef { | 524 | pub enum VariantDef { |
503 | Struct(Struct), | 525 | Struct(Struct), |
526 | Union(Union), | ||
504 | EnumVariant(EnumVariant), | 527 | EnumVariant(EnumVariant), |
505 | } | 528 | } |
506 | impl_froms!(VariantDef: Struct, EnumVariant); | 529 | impl_froms!(VariantDef: Struct, Union, EnumVariant); |
507 | 530 | ||
508 | impl VariantDef { | 531 | impl 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> { |