aboutsummaryrefslogtreecommitdiff
path: root/crates/hir
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-05-23 17:10:40 +0100
committerFlorian Diebold <[email protected]>2021-05-23 17:45:44 +0100
commit7a0c93c58ac17b089edd8c9763fef303b7a81414 (patch)
tree49cb56219cd7aea41376c49252601264ebabcf1a /crates/hir
parent4a6cdd776d403bacce0a5471d77e8c76695c5bc5 (diff)
Infer correct expected type for generic struct fields
Diffstat (limited to 'crates/hir')
-rw-r--r--crates/hir/src/lib.rs18
1 files changed, 15 insertions, 3 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index a7c42ca1e..edee99356 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -513,9 +513,9 @@ impl Field {
513 } 513 }
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). This is good for showing 516 /// placeholder types for type parameters). Only use this in the context of
517 /// signature help, but not so good to actually get the type of the field 517 /// the field *definition*; if you've already got a variable of the struct
518 /// when you actually have a variable of the struct. 518 /// type, use `Type::field_type` to get to the field type.
519 pub fn ty(&self, db: &dyn HirDatabase) -> Type { 519 pub fn ty(&self, db: &dyn HirDatabase) -> Type {
520 let var_id = self.parent.into(); 520 let var_id = self.parent.into();
521 let generic_def_id: GenericDefId = match self.parent { 521 let generic_def_id: GenericDefId = match self.parent {
@@ -1944,6 +1944,18 @@ impl Type {
1944 } 1944 }
1945 } 1945 }
1946 1946
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
1947 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1959 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1948 let (variant_id, substs) = match self.ty.kind(&Interner) { 1960 let (variant_id, substs) = match self.ty.kind(&Interner) {
1949 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), 1961 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),