diff options
Diffstat (limited to 'crates/hir/src/source_analyzer.rs')
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index b5c65808e..3f940124c 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -143,7 +143,7 @@ impl SourceAnalyzer { | |||
143 | &self, | 143 | &self, |
144 | db: &dyn HirDatabase, | 144 | db: &dyn HirDatabase, |
145 | call: &ast::MethodCallExpr, | 145 | call: &ast::MethodCallExpr, |
146 | ) -> Option<FunctionId> { | 146 | ) -> Option<(FunctionId, Substitution)> { |
147 | let expr_id = self.expr_id(db, &call.clone().into())?; | 147 | let expr_id = self.expr_id(db, &call.clone().into())?; |
148 | self.infer.as_ref()?.method_resolution(expr_id) | 148 | self.infer.as_ref()?.method_resolution(expr_id) |
149 | } | 149 | } |
@@ -161,7 +161,7 @@ impl SourceAnalyzer { | |||
161 | &self, | 161 | &self, |
162 | db: &dyn HirDatabase, | 162 | db: &dyn HirDatabase, |
163 | field: &ast::RecordExprField, | 163 | field: &ast::RecordExprField, |
164 | ) -> Option<(Field, Option<Local>)> { | 164 | ) -> Option<(Field, Option<Local>, Type)> { |
165 | let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?; | 165 | let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?; |
166 | let expr = ast::Expr::from(record_expr); | 166 | let expr = ast::Expr::from(record_expr); |
167 | let expr_id = self.body_source_map.as_ref()?.node_expr(InFile::new(self.file_id, &expr))?; | 167 | let expr_id = self.body_source_map.as_ref()?.node_expr(InFile::new(self.file_id, &expr))?; |
@@ -178,10 +178,13 @@ impl SourceAnalyzer { | |||
178 | _ => None, | 178 | _ => None, |
179 | } | 179 | } |
180 | }; | 180 | }; |
181 | let (_, subst) = self.infer.as_ref()?.type_of_expr.get(expr_id)?.as_adt()?; | ||
181 | let variant = self.infer.as_ref()?.variant_resolution_for_expr(expr_id)?; | 182 | let variant = self.infer.as_ref()?.variant_resolution_for_expr(expr_id)?; |
182 | let variant_data = variant.variant_data(db.upcast()); | 183 | let variant_data = variant.variant_data(db.upcast()); |
183 | let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? }; | 184 | let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? }; |
184 | Some((field.into(), local)) | 185 | let field_ty = |
186 | db.field_types(variant).get(field.local_id)?.clone().substitute(&Interner, subst); | ||
187 | Some((field.into(), local, Type::new_with_resolver(db, &self.resolver, field_ty)?)) | ||
185 | } | 188 | } |
186 | 189 | ||
187 | pub(crate) fn resolve_record_pat_field( | 190 | pub(crate) fn resolve_record_pat_field( |
@@ -286,7 +289,7 @@ impl SourceAnalyzer { | |||
286 | let ctx = body::LowerCtx::with_hygiene(db.upcast(), &hygiene); | 289 | let ctx = body::LowerCtx::with_hygiene(db.upcast(), &hygiene); |
287 | let hir_path = Path::from_src(path.clone(), &ctx)?; | 290 | let hir_path = Path::from_src(path.clone(), &ctx)?; |
288 | 291 | ||
289 | // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we | 292 | // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we are |
290 | // trying to resolve foo::bar. | 293 | // trying to resolve foo::bar. |
291 | if let Some(outer_path) = parent().and_then(ast::Path::cast) { | 294 | if let Some(outer_path) = parent().and_then(ast::Path::cast) { |
292 | if let Some(qualifier) = outer_path.qualifier() { | 295 | if let Some(qualifier) = outer_path.qualifier() { |
@@ -295,6 +298,15 @@ impl SourceAnalyzer { | |||
295 | } | 298 | } |
296 | } | 299 | } |
297 | } | 300 | } |
301 | // Case where path is a qualifier of a use tree, e.g. foo::bar::{Baz, Qux} where we are | ||
302 | // trying to resolve foo::bar. | ||
303 | if let Some(use_tree) = parent().and_then(ast::UseTree::cast) { | ||
304 | if let Some(qualifier) = use_tree.path() { | ||
305 | if path == &qualifier && use_tree.coloncolon_token().is_some() { | ||
306 | return resolve_hir_path_qualifier(db, &self.resolver, &hir_path); | ||
307 | } | ||
308 | } | ||
309 | } | ||
298 | 310 | ||
299 | resolve_hir_path_(db, &self.resolver, &hir_path, prefer_value_ns) | 311 | resolve_hir_path_(db, &self.resolver, &hir_path, prefer_value_ns) |
300 | } | 312 | } |