Merge #9552
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:
commit
f83f069f94
@ -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)
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ fn test2() {
|
||||
|
||||
#[test]
|
||||
fn let_stmt_coerce() {
|
||||
check_no_mismatches(
|
||||
check(
|
||||
r"
|
||||
//- minicore: coerce_unsized
|
||||
fn test() {
|
||||
|
@ -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];
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user