9552: internal: `add_explicit_type` respects coercions r=Veykril a=Veykril

or so I'd like to say but there is one odd case here where it doesn't work(see [review](https://github.com/rust-analyzer/rust-analyzer/pull/9552#discussion_r667351856))

Fixes https://github.com/rust-analyzer/rust-analyzer/issues/6107

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-07-10 16:25:58 +00:00 committed by GitHub
commit f83f069f94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 2 deletions

View File

@ -216,6 +216,10 @@ pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
self.imp.type_of_expr(expr)
}
pub fn type_of_expr_with_coercion(&self, expr: &ast::Expr) -> Option<Type> {
self.imp.type_of_expr_with_coercion(expr)
}
pub fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> {
self.imp.type_of_pat(pat)
}
@ -560,6 +564,10 @@ fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
self.analyze(expr.syntax()).type_of_expr(self.db, expr)
}
fn type_of_expr_with_coercion(&self, expr: &ast::Expr) -> Option<Type> {
self.analyze(expr.syntax()).type_of_expr_with_coercion(self.db, expr)
}
fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> {
self.analyze(pat.syntax()).type_of_pat(self.db, pat)
}

View File

@ -122,6 +122,21 @@ pub(crate) fn type_of_expr(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Opt
Type::new_with_resolver(db, &self.resolver, ty)
}
pub(crate) fn type_of_expr_with_coercion(
&self,
db: &dyn HirDatabase,
expr: &ast::Expr,
) -> Option<Type> {
let expr_id = self.expr_id(db, expr)?;
let infer = self.infer.as_ref()?;
let ty = infer
.expr_adjustments
.get(&expr_id)
.and_then(|adjusts| adjusts.last().map(|adjust| &adjust.target))
.unwrap_or_else(|| &infer[expr_id]);
Type::new_with_resolver(db, &self.resolver, ty.clone())
}
pub(crate) fn type_of_pat(&self, db: &dyn HirDatabase, pat: &ast::Pat) -> Option<Type> {
let pat_id = self.pat_id(pat)?;
let ty = self.infer.as_ref()?[pat_id].clone();

View File

@ -407,6 +407,12 @@ fn resolve_all(mut self) -> InferenceResult {
for (_, subst) in result.method_resolutions.values_mut() {
*subst = self.table.resolve_completely(subst.clone());
}
for adjustment in result.expr_adjustments.values_mut().flatten() {
adjustment.target = self.table.resolve_completely(adjustment.target.clone());
}
for adjustment in result.pat_adjustments.values_mut().flatten() {
adjustment.target = self.table.resolve_completely(adjustment.target.clone());
}
result
}

View File

@ -46,7 +46,7 @@ fn test2() {
#[test]
fn let_stmt_coerce() {
check_no_mismatches(
check(
r"
//- minicore: coerce_unsized
fn test() {

View File

@ -55,7 +55,7 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
}
// Infer type
let ty = ctx.sema.type_of_expr(&expr)?;
let ty = ctx.sema.type_of_expr_with_coercion(&expr)?;
if ty.contains_unknown() || ty.is_closure() {
cov_mark::hit!(add_explicit_type_not_applicable_if_ty_not_inferred);
return None;
@ -258,6 +258,24 @@ fn main() {
fn main() {
let test @ (): () = ();
}
"#,
);
}
#[test]
fn add_explicit_type_inserts_coercions() {
check_assist(
add_explicit_type,
r#"
//- minicore: coerce_unsized
fn f() {
let $0x: *const [_] = &[3];
}
"#,
r#"
fn f() {
let x: *const [i32] = &[3];
}
"#,
);
}