Infer correct expected type for generic struct fields

This commit is contained in:
Florian Diebold
2021-05-23 18:10:40 +02:00
parent 4a6cdd776d
commit 7a0c93c58a
4 changed files with 46 additions and 19 deletions

View File

@@ -513,9 +513,9 @@ impl Field {
}
/// Returns the type as in the signature of the struct (i.e., with
/// placeholder types for type parameters). This is good for showing
/// signature help, but not so good to actually get the type of the field
/// when you actually have a variable of the struct.
/// placeholder types for type parameters). Only use this in the context of
/// the field *definition*; if you've already got a variable of the struct
/// type, use `Type::field_type` to get to the field type.
pub fn ty(&self, db: &dyn HirDatabase) -> Type {
let var_id = self.parent.into();
let generic_def_id: GenericDefId = match self.parent {
@@ -1944,6 +1944,18 @@ impl Type {
}
}
pub fn field_type(&self, db: &dyn HirDatabase, field: Field) -> Option<Type> {
let (adt_id, substs) = self.ty.as_adt()?;
let variant_id: hir_def::VariantId = field.parent.into();
if variant_id.adt_id() != adt_id {
return None;
}
let ty = db.field_types(variant_id).get(field.id)?.clone();
let ty = ty.substitute(&Interner, substs);
Some(self.derived(ty))
}
pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
let (variant_id, substs) = match self.ty.kind(&Interner) {
&TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),