diff options
author | Ekaterina Babshukova <[email protected]> | 2019-07-12 17:56:18 +0100 |
---|---|---|
committer | Ekaterina Babshukova <[email protected]> | 2019-07-12 18:31:49 +0100 |
commit | 2a1e11b36fe90460b139f2f6aee034f63e8252bf (patch) | |
tree | 8275d86d2d105a2bd2a5d601af9b6372a523107d /crates/ra_hir | |
parent | 8bb81d7418dbc4c295d31d261441b67dba4c0f76 (diff) |
complete fields in enum variants
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/adt.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 15 |
4 files changed, 28 insertions, 1 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index 5a3ea5f55..8afdac801 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -185,6 +185,13 @@ pub enum VariantDef { | |||
185 | impl_froms!(VariantDef: Struct, EnumVariant); | 185 | impl_froms!(VariantDef: Struct, EnumVariant); |
186 | 186 | ||
187 | impl VariantDef { | 187 | impl VariantDef { |
188 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | ||
189 | match self { | ||
190 | VariantDef::Struct(it) => it.fields(db), | ||
191 | VariantDef::EnumVariant(it) => it.fields(db), | ||
192 | } | ||
193 | } | ||
194 | |||
188 | pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | 195 | pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { |
189 | match self { | 196 | match self { |
190 | VariantDef::Struct(it) => it.field(db, name), | 197 | VariantDef::Struct(it) => it.field(db, name), |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 56831ba05..55d1298cf 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -55,7 +55,7 @@ use crate::{ | |||
55 | }; | 55 | }; |
56 | 56 | ||
57 | pub use self::{ | 57 | pub use self::{ |
58 | adt::AdtDef, | 58 | adt::{AdtDef, VariantDef}, |
59 | either::Either, | 59 | either::Either, |
60 | expr::ExprScopes, | 60 | expr::ExprScopes, |
61 | generics::{GenericParam, GenericParams, HasGenericParams}, | 61 | generics::{GenericParam, GenericParams, HasGenericParams}, |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 573add7da..071c1bb18 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -266,6 +266,11 @@ impl SourceAnalyzer { | |||
266 | self.infer.as_ref()?.field_resolution(expr_id) | 266 | self.infer.as_ref()?.field_resolution(expr_id) |
267 | } | 267 | } |
268 | 268 | ||
269 | pub fn resolve_variant(&self, struct_lit: &ast::StructLit) -> Option<crate::VariantDef> { | ||
270 | let expr_id = self.body_source_map.as_ref()?.node_expr(struct_lit.into())?; | ||
271 | self.infer.as_ref()?.variant_resolution(expr_id) | ||
272 | } | ||
273 | |||
269 | pub fn resolve_macro_call( | 274 | pub fn resolve_macro_call( |
270 | &self, | 275 | &self, |
271 | db: &impl HirDatabase, | 276 | db: &impl HirDatabase, |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 26ddf0317..5ad4f73ec 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -113,6 +113,7 @@ pub struct InferenceResult { | |||
113 | method_resolutions: FxHashMap<ExprId, Function>, | 113 | method_resolutions: FxHashMap<ExprId, Function>, |
114 | /// For each field access expr, records the field it resolves to. | 114 | /// For each field access expr, records the field it resolves to. |
115 | field_resolutions: FxHashMap<ExprId, StructField>, | 115 | field_resolutions: FxHashMap<ExprId, StructField>, |
116 | variant_resolutions: FxHashMap<ExprId, VariantDef>, | ||
116 | /// For each associated item record what it resolves to | 117 | /// For each associated item record what it resolves to |
117 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, | 118 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, |
118 | diagnostics: Vec<InferenceDiagnostic>, | 119 | diagnostics: Vec<InferenceDiagnostic>, |
@@ -127,6 +128,9 @@ impl InferenceResult { | |||
127 | pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> { | 128 | pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> { |
128 | self.field_resolutions.get(&expr).copied() | 129 | self.field_resolutions.get(&expr).copied() |
129 | } | 130 | } |
131 | pub fn variant_resolution(&self, expr: ExprId) -> Option<VariantDef> { | ||
132 | self.variant_resolutions.get(&expr).copied() | ||
133 | } | ||
130 | pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<ImplItem> { | 134 | pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<ImplItem> { |
131 | self.assoc_resolutions.get(&id.into()).copied() | 135 | self.assoc_resolutions.get(&id.into()).copied() |
132 | } | 136 | } |
@@ -170,6 +174,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
170 | obligations: Vec<Obligation>, | 174 | obligations: Vec<Obligation>, |
171 | method_resolutions: FxHashMap<ExprId, Function>, | 175 | method_resolutions: FxHashMap<ExprId, Function>, |
172 | field_resolutions: FxHashMap<ExprId, StructField>, | 176 | field_resolutions: FxHashMap<ExprId, StructField>, |
177 | variant_resolutions: FxHashMap<ExprId, VariantDef>, | ||
173 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, | 178 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, |
174 | type_of_expr: ArenaMap<ExprId, Ty>, | 179 | type_of_expr: ArenaMap<ExprId, Ty>, |
175 | type_of_pat: ArenaMap<PatId, Ty>, | 180 | type_of_pat: ArenaMap<PatId, Ty>, |
@@ -183,6 +188,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
183 | InferenceContext { | 188 | InferenceContext { |
184 | method_resolutions: FxHashMap::default(), | 189 | method_resolutions: FxHashMap::default(), |
185 | field_resolutions: FxHashMap::default(), | 190 | field_resolutions: FxHashMap::default(), |
191 | variant_resolutions: FxHashMap::default(), | ||
186 | assoc_resolutions: FxHashMap::default(), | 192 | assoc_resolutions: FxHashMap::default(), |
187 | type_of_expr: ArenaMap::default(), | 193 | type_of_expr: ArenaMap::default(), |
188 | type_of_pat: ArenaMap::default(), | 194 | type_of_pat: ArenaMap::default(), |
@@ -213,6 +219,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
213 | InferenceResult { | 219 | InferenceResult { |
214 | method_resolutions: self.method_resolutions, | 220 | method_resolutions: self.method_resolutions, |
215 | field_resolutions: self.field_resolutions, | 221 | field_resolutions: self.field_resolutions, |
222 | variant_resolutions: self.variant_resolutions, | ||
216 | assoc_resolutions: self.assoc_resolutions, | 223 | assoc_resolutions: self.assoc_resolutions, |
217 | type_of_expr: expr_types, | 224 | type_of_expr: expr_types, |
218 | type_of_pat: pat_types, | 225 | type_of_pat: pat_types, |
@@ -232,6 +239,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
232 | self.field_resolutions.insert(expr, field); | 239 | self.field_resolutions.insert(expr, field); |
233 | } | 240 | } |
234 | 241 | ||
242 | fn write_variant_resolution(&mut self, expr: ExprId, variant: VariantDef) { | ||
243 | self.variant_resolutions.insert(expr, variant); | ||
244 | } | ||
245 | |||
235 | fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: ImplItem) { | 246 | fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: ImplItem) { |
236 | self.assoc_resolutions.insert(id, item); | 247 | self.assoc_resolutions.insert(id, item); |
237 | } | 248 | } |
@@ -1069,6 +1080,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1069 | } | 1080 | } |
1070 | Expr::StructLit { path, fields, spread } => { | 1081 | Expr::StructLit { path, fields, spread } => { |
1071 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 1082 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
1083 | if let Some(variant) = def_id { | ||
1084 | self.write_variant_resolution(tgt_expr, variant); | ||
1085 | } | ||
1086 | |||
1072 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 1087 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
1073 | for (field_idx, field) in fields.iter().enumerate() { | 1088 | for (field_idx, field) in fields.iter().enumerate() { |
1074 | let field_ty = def_id | 1089 | let field_ty = def_id |