From d5a43d1f859597dbdb566a717e7278acb8b2c767 Mon Sep 17 00:00:00 2001 From: Lukas Wirth <lukastw97@gmail.com> Date: Sat, 10 Jul 2021 18:19:23 +0200 Subject: [PATCH 1/2] Resolve type adjustments --- crates/hir_ty/src/infer.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index b1c0432273d..154c44afa42 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -407,6 +407,12 @@ impl<'a> InferenceContext<'a> { 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 } From 576e3a4e122ac7089d6e209a86cbf825e927908b Mon Sep 17 00:00:00 2001 From: Lukas Wirth <lukastw97@gmail.com> Date: Sat, 10 Jul 2021 18:19:46 +0200 Subject: [PATCH 2/2] `add_explicit_type` respects coercions --- crates/hir/src/semantics.rs | 8 ++++++++ crates/hir/src/source_analyzer.rs | 15 ++++++++++++++ crates/hir_ty/src/tests/coercion.rs | 2 +- .../src/handlers/add_explicit_type.rs | 20 ++++++++++++++++++- 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 43162797e3c..984021d59ec 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -216,6 +216,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { 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 @@ impl<'db> SemanticsImpl<'db> { 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) } diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index c9744d81d22..474fb3fe30a 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -122,6 +122,21 @@ impl SourceAnalyzer { 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(); diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs index 1e30e2e8c1d..aecc482cfdc 100644 --- a/crates/hir_ty/src/tests/coercion.rs +++ b/crates/hir_ty/src/tests/coercion.rs @@ -46,7 +46,7 @@ fn test2() { #[test] fn let_stmt_coerce() { - check_no_mismatches( + check( r" //- minicore: coerce_unsized fn test() { diff --git a/crates/ide_assists/src/handlers/add_explicit_type.rs b/crates/ide_assists/src/handlers/add_explicit_type.rs index b7617ca3da8..b0e8fb6559f 100644 --- a/crates/ide_assists/src/handlers/add_explicit_type.rs +++ b/crates/ide_assists/src/handlers/add_explicit_type.rs @@ -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]; +} "#, ); }