Skip to content

Commit 00950ec

Browse files
committed
add_explicit_type respects coercions
1 parent 637dbb2 commit 00950ec

File tree

4 files changed

+47
-4
lines changed

4 files changed

+47
-4
lines changed

crates/hir/src/semantics.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
216216
self.imp.type_of_expr(expr)
217217
}
218218

219+
pub fn type_of_expr_with_coercion(&self, expr: &ast::Expr) -> Option<Type> {
220+
self.imp.type_of_expr_with_coercion(expr)
221+
}
222+
219223
pub fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> {
220224
self.imp.type_of_pat(pat)
221225
}
@@ -560,6 +564,10 @@ impl<'db> SemanticsImpl<'db> {
560564
self.analyze(expr.syntax()).type_of_expr(self.db, expr)
561565
}
562566

567+
fn type_of_expr_with_coercion(&self, expr: &ast::Expr) -> Option<Type> {
568+
self.analyze(expr.syntax()).type_of_expr_with_coercion(self.db, expr)
569+
}
570+
563571
fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> {
564572
self.analyze(pat.syntax()).type_of_pat(self.db, pat)
565573
}

crates/hir/src/source_analyzer.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,21 @@ impl SourceAnalyzer {
122122
Type::new_with_resolver(db, &self.resolver, ty)
123123
}
124124

125+
pub(crate) fn type_of_expr_with_coercion(
126+
&self,
127+
db: &dyn HirDatabase,
128+
expr: &ast::Expr,
129+
) -> Option<Type> {
130+
let expr_id = self.expr_id(db, expr)?;
131+
let infer = self.infer.as_ref()?;
132+
let ty = infer
133+
.expr_adjustments
134+
.get(&expr_id)
135+
.and_then(|adjusts| adjusts.last().map(|adjust| &adjust.target))
136+
.unwrap_or_else(|| &infer[expr_id]);
137+
Type::new_with_resolver(db, &self.resolver, ty.clone())
138+
}
139+
125140
pub(crate) fn type_of_pat(&self, db: &dyn HirDatabase, pat: &ast::Pat) -> Option<Type> {
126141
let pat_id = self.pat_id(pat)?;
127142
let ty = self.infer.as_ref()?[pat_id].clone();

crates/hir_ty/src/tests/coercion.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ fn test2() {
4646

4747
#[test]
4848
fn let_stmt_coerce() {
49-
check_no_mismatches(
49+
check(
5050
r"
5151
//- minicore: coerce_unsized
5252
fn test() {
5353
let x: &[isize] = &[1];
5454
// ^^^^ adjustments: Deref(None), Borrow(Ref(Not)), Pointer(Unsize)
55-
let x: *const [isize] = &[1];
56-
// ^^^^ adjustments: Deref(None), Borrow(RawPtr(Not)), Pointer(Unsize)
55+
let x: *const [_] = &[1];
56+
// ^ type: *const [i32]
57+
// ^^^^ adjustments: Deref(None), Borrow(RawPtr(Not)), Pointer(Unsize)
5758
}
5859
",
5960
);

crates/ide_assists/src/handlers/add_explicit_type.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
5555
}
5656

5757
// Infer type
58-
let ty = ctx.sema.type_of_expr(&expr)?;
58+
let ty = ctx.sema.type_of_expr_with_coercion(&expr)?;
5959
if ty.contains_unknown() || ty.is_closure() {
6060
cov_mark::hit!(add_explicit_type_not_applicable_if_ty_not_inferred);
6161
return None;
@@ -258,6 +258,25 @@ fn main() {
258258
fn main() {
259259
let test @ (): () = ();
260260
}
261+
"#,
262+
);
263+
}
264+
265+
#[test]
266+
fn add_explicit_type_inserts_coercions() {
267+
// This should set `*const [u32]`
268+
check_assist(
269+
add_explicit_type,
270+
r#"
271+
//- minicore: coerce_unsized
272+
fn f() {
273+
let $0x: *const [_] = &[3];
274+
}
275+
"#,
276+
r#"
277+
fn f() {
278+
let x: *const [_] = &[3];
279+
}
261280
"#,
262281
);
263282
}

0 commit comments

Comments
 (0)