diff options
author | Florian Diebold <[email protected]> | 2021-05-23 17:10:40 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-05-23 17:45:44 +0100 |
commit | 7a0c93c58ac17b089edd8c9763fef303b7a81414 (patch) | |
tree | 49cb56219cd7aea41376c49252601264ebabcf1a /crates/hir | |
parent | 4a6cdd776d403bacce0a5471d77e8c76695c5bc5 (diff) |
Infer correct expected type for generic struct fields
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/src/lib.rs | 18 |
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), |