diff options
-rw-r--r-- | crates/hir/src/lib.rs | 15 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 7 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 7 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/fix_visibility.rs | 2 | ||||
-rw-r--r-- | crates/ide_completion/src/context.rs | 7 | ||||
-rw-r--r-- | crates/ide_db/src/defs.rs | 2 |
6 files changed, 16 insertions, 24 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index edee99356..ca9a7f7fa 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -514,8 +514,7 @@ impl Field { | |||
514 | 514 | ||
515 | /// Returns the type as in the signature of the struct (i.e., with | 515 | /// Returns the type as in the signature of the struct (i.e., with |
516 | /// placeholder types for type parameters). Only use this in the context of | 516 | /// placeholder types for type parameters). Only use this in the context of |
517 | /// the field *definition*; if you've already got a variable of the struct | 517 | /// the field definition. |
518 | /// type, use `Type::field_type` to get to the field type. | ||
519 | pub fn ty(&self, db: &dyn HirDatabase) -> Type { | 518 | pub fn ty(&self, db: &dyn HirDatabase) -> Type { |
520 | let var_id = self.parent.into(); | 519 | let var_id = self.parent.into(); |
521 | let generic_def_id: GenericDefId = match self.parent { | 520 | let generic_def_id: GenericDefId = match self.parent { |
@@ -1944,18 +1943,6 @@ impl Type { | |||
1944 | } | 1943 | } |
1945 | } | 1944 | } |
1946 | 1945 | ||
1947 | pub fn field_type(&self, db: &dyn HirDatabase, field: Field) -> Option<Type> { | ||
1948 | let (adt_id, substs) = self.ty.as_adt()?; | ||
1949 | let variant_id: hir_def::VariantId = field.parent.into(); | ||
1950 | if variant_id.adt_id() != adt_id { | ||
1951 | return None; | ||
1952 | } | ||
1953 | |||
1954 | let ty = db.field_types(variant_id).get(field.id)?.clone(); | ||
1955 | let ty = ty.substitute(&Interner, substs); | ||
1956 | Some(self.derived(ty)) | ||
1957 | } | ||
1958 | |||
1959 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { | 1946 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { |
1960 | let (variant_id, substs) = match self.ty.kind(&Interner) { | 1947 | let (variant_id, substs) = match self.ty.kind(&Interner) { |
1961 | &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), | 1948 | &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index d65dd7df0..3aa467e3c 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -227,7 +227,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
227 | pub fn resolve_record_field( | 227 | pub fn resolve_record_field( |
228 | &self, | 228 | &self, |
229 | field: &ast::RecordExprField, | 229 | field: &ast::RecordExprField, |
230 | ) -> Option<(Field, Option<Local>)> { | 230 | ) -> Option<(Field, Option<Local>, Type)> { |
231 | self.imp.resolve_record_field(field) | 231 | self.imp.resolve_record_field(field) |
232 | } | 232 | } |
233 | 233 | ||
@@ -518,7 +518,10 @@ impl<'db> SemanticsImpl<'db> { | |||
518 | self.analyze(field.syntax()).resolve_field(self.db, field) | 518 | self.analyze(field.syntax()).resolve_field(self.db, field) |
519 | } | 519 | } |
520 | 520 | ||
521 | fn resolve_record_field(&self, field: &ast::RecordExprField) -> Option<(Field, Option<Local>)> { | 521 | fn resolve_record_field( |
522 | &self, | ||
523 | field: &ast::RecordExprField, | ||
524 | ) -> Option<(Field, Option<Local>, Type)> { | ||
522 | self.analyze(field.syntax()).resolve_record_field(self.db, field) | 525 | self.analyze(field.syntax()).resolve_record_field(self.db, field) |
523 | } | 526 | } |
524 | 527 | ||
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index a1a9c727a..5a3d80e8e 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -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( |
diff --git a/crates/ide_assists/src/handlers/fix_visibility.rs b/crates/ide_assists/src/handlers/fix_visibility.rs index 6c7824e55..89f7b2c2c 100644 --- a/crates/ide_assists/src/handlers/fix_visibility.rs +++ b/crates/ide_assists/src/handlers/fix_visibility.rs | |||
@@ -85,7 +85,7 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext) -> O | |||
85 | 85 | ||
86 | fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 86 | fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
87 | let record_field: ast::RecordExprField = ctx.find_node_at_offset()?; | 87 | let record_field: ast::RecordExprField = ctx.find_node_at_offset()?; |
88 | let (record_field_def, _) = ctx.sema.resolve_record_field(&record_field)?; | 88 | let (record_field_def, _, _) = ctx.sema.resolve_record_field(&record_field)?; |
89 | 89 | ||
90 | let current_module = ctx.sema.scope(record_field.syntax()).module()?; | 90 | let current_module = ctx.sema.scope(record_field.syntax()).module()?; |
91 | let visibility = record_field_def.visibility(ctx.db()); | 91 | let visibility = record_field_def.visibility(ctx.db()); |
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index efaf4792f..1ec59ff80 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs | |||
@@ -339,13 +339,12 @@ impl<'a> CompletionContext<'a> { | |||
339 | cov_mark::hit!(expected_type_struct_field_without_leading_char); | 339 | cov_mark::hit!(expected_type_struct_field_without_leading_char); |
340 | // wouldn't try {} be nice... | 340 | // wouldn't try {} be nice... |
341 | (|| { | 341 | (|| { |
342 | let record_ty = self.sema.type_of_expr(&ast::Expr::cast(node.parent()?)?)?; | ||
343 | let expr_field = self.token.prev_sibling_or_token()? | 342 | let expr_field = self.token.prev_sibling_or_token()? |
344 | .into_node() | 343 | .into_node() |
345 | .and_then(|node| ast::RecordExprField::cast(node))?; | 344 | .and_then(|node| ast::RecordExprField::cast(node))?; |
346 | let field = self.sema.resolve_record_field(&expr_field)?.0; | 345 | let (_, _, ty) = self.sema.resolve_record_field(&expr_field)?; |
347 | Some(( | 346 | Some(( |
348 | record_ty.field_type(self.db, field), | 347 | Some(ty), |
349 | expr_field.field_name().map(NameOrNameRef::NameRef), | 348 | expr_field.field_name().map(NameOrNameRef::NameRef), |
350 | )) | 349 | )) |
351 | })().unwrap_or((None, None)) | 350 | })().unwrap_or((None, None)) |
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index de0dc2a40..1dcccbb8b 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs | |||
@@ -311,7 +311,7 @@ impl NameRefClass { | |||
311 | } | 311 | } |
312 | 312 | ||
313 | if let Some(record_field) = ast::RecordExprField::for_field_name(name_ref) { | 313 | if let Some(record_field) = ast::RecordExprField::for_field_name(name_ref) { |
314 | if let Some((field, local)) = sema.resolve_record_field(&record_field) { | 314 | if let Some((field, local, _)) = sema.resolve_record_field(&record_field) { |
315 | let field = Definition::Field(field); | 315 | let field = Definition::Field(field); |
316 | let res = match local { | 316 | let res = match local { |
317 | None => NameRefClass::Definition(field), | 317 | None => NameRefClass::Definition(field), |