Do not add default and closure types in 'add explicit type' assist

This commit is contained in:
Kirill Bulatov 2020-04-21 22:56:11 +03:00
parent 7ab28cacbb
commit ce06a6b422
2 changed files with 47 additions and 5 deletions

View file

@ -52,21 +52,22 @@ pub(crate) fn add_explicit_type(ctx: AssistCtx) -> Option<Assist> {
} }
// Infer type // Infer type
let ty = ctx.sema.type_of_expr(&expr)?; let ty = ctx.sema.type_of_expr(&expr)?;
// Assist not applicable if the type is unknown
if ty.contains_unknown() { if ty.contains_unknown() || ty.is_closure() {
return None; return None;
} }
let db = ctx.db; let db = ctx.db;
let new_type_string = ty.display_truncated(db, None).to_string();
ctx.add_assist( ctx.add_assist(
AssistId("add_explicit_type"), AssistId("add_explicit_type"),
format!("Insert explicit type '{}'", ty.display(db)), format!("Insert explicit type '{}'", new_type_string),
|edit| { |edit| {
edit.target(pat_range); edit.target(pat_range);
if let Some(ascribed_ty) = ascribed_ty { if let Some(ascribed_ty) = ascribed_ty {
edit.replace(ascribed_ty.syntax().text_range(), format!("{}", ty.display(db))); edit.replace(ascribed_ty.syntax().text_range(), new_type_string);
} else { } else {
edit.insert(name_range.end(), format!(": {}", ty.display(db))); edit.insert(name_range.end(), format!(": {}", new_type_string));
} }
}, },
) )
@ -174,4 +175,41 @@ mod tests {
"fn f() <|>{let a = match 1 {2 => 3, 3 => 5};}", "fn f() <|>{let a = match 1 {2 => 3, 3 => 5};}",
) )
} }
#[test]
fn closure_parameters_are_not_added() {
check_assist_not_applicable(
add_explicit_type,
r#"
fn main() {
let multiply_by_two<|> = |i| i * 3;
let six = multiply_by_two(2);
}"#,
)
}
#[test]
fn default_generics_should_not_be_added() {
check_assist(
add_explicit_type,
r#"
struct Test<K, T = u8> {
k: K,
t: T,
}
fn main() {
let test<|> = Test { t: 23, k: 33 };
}"#,
r#"
struct Test<K, T = u8> {
k: K,
t: T,
}
fn main() {
let test<|>: Test<i32> = Test { t: 23, k: 33 };
}"#,
);
}
} }

View file

@ -1132,6 +1132,10 @@ impl Type {
Some(self.ty.value.as_callable()?.0) Some(self.ty.value.as_callable()?.0)
} }
pub fn is_closure(&self) -> bool {
matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. }))
}
pub fn contains_unknown(&self) -> bool { pub fn contains_unknown(&self) -> bool {
return go(&self.ty.value); return go(&self.ty.value);