8945: fix: Make expected type work in more situations r=flodiebold a=flodiebold

Also makes call info show the correct types for generic methods.

![2021-05-23-182952_1134x616_scrot](https://user-images.githubusercontent.com/906069/119269023-dd5a5b00-bbf5-11eb-993a-b6e122c3b9a6.png)
![2021-05-23-183117_922x696_scrot](https://user-images.githubusercontent.com/906069/119269025-dfbcb500-bbf5-11eb-983c-fc415b8428e0.png)


Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
bors[bot] 2021-05-23 21:55:51 +00:00 committed by GitHub
commit 495c9586ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 175 additions and 69 deletions

View file

@ -143,7 +143,7 @@ impl SourceAnalyzer {
&self,
db: &dyn HirDatabase,
call: &ast::MethodCallExpr,
) -> Option<FunctionId> {
) -> Option<(FunctionId, Substitution)> {
let expr_id = self.expr_id(db, &call.clone().into())?;
self.infer.as_ref()?.method_resolution(expr_id)
}
@ -161,7 +161,7 @@ impl SourceAnalyzer {
&self,
db: &dyn HirDatabase,
field: &ast::RecordExprField,
) -> Option<(Field, Option<Local>)> {
) -> Option<(Field, Option<Local>, Type)> {
let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
let expr = ast::Expr::from(record_expr);
let expr_id = self.body_source_map.as_ref()?.node_expr(InFile::new(self.file_id, &expr))?;
@ -178,10 +178,13 @@ impl SourceAnalyzer {
_ => None,
}
};
let (_, subst) = self.infer.as_ref()?.type_of_expr.get(expr_id)?.as_adt()?;
let variant = self.infer.as_ref()?.variant_resolution_for_expr(expr_id)?;
let variant_data = variant.variant_data(db.upcast());
let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
Some((field.into(), local))
let field_ty =
db.field_types(variant).get(field.local_id)?.clone().substitute(&Interner, subst);
Some((field.into(), local, Type::new_with_resolver(db, &self.resolver, field_ty)?))
}
pub(crate) fn resolve_record_pat_field(