aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/adt.rs7
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/source_binder.rs5
-rw-r--r--crates/ra_hir/src/ty/infer.rs15
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 {
185impl_froms!(VariantDef: Struct, EnumVariant); 185impl_froms!(VariantDef: Struct, EnumVariant);
186 186
187impl VariantDef { 187impl 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
57pub use self::{ 57pub 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