aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/handlers/add_explicit_type.rs48
-rw-r--r--crates/ra_hir/src/code_model.rs4
2 files changed, 47 insertions, 5 deletions
diff --git a/crates/ra_assists/src/handlers/add_explicit_type.rs b/crates/ra_assists/src/handlers/add_explicit_type.rs
index d86d804b2..6c56d93d8 100644
--- a/crates/ra_assists/src/handlers/add_explicit_type.rs
+++ b/crates/ra_assists/src/handlers/add_explicit_type.rs
@@ -52,21 +52,22 @@ pub(crate) fn add_explicit_type(ctx: AssistCtx) -> Option<Assist> {
52 } 52 }
53 // Infer type 53 // Infer type
54 let ty = ctx.sema.type_of_expr(&expr)?; 54 let ty = ctx.sema.type_of_expr(&expr)?;
55 // Assist not applicable if the type is unknown 55
56 if ty.contains_unknown() { 56 if ty.contains_unknown() || ty.is_closure() {
57 return None; 57 return None;
58 } 58 }
59 59
60 let db = ctx.db; 60 let db = ctx.db;
61 let new_type_string = ty.display_truncated(db, None).to_string();
61 ctx.add_assist( 62 ctx.add_assist(
62 AssistId("add_explicit_type"), 63 AssistId("add_explicit_type"),
63 format!("Insert explicit type '{}'", ty.display(db)), 64 format!("Insert explicit type '{}'", new_type_string),
64 |edit| { 65 |edit| {
65 edit.target(pat_range); 66 edit.target(pat_range);
66 if let Some(ascribed_ty) = ascribed_ty { 67 if let Some(ascribed_ty) = ascribed_ty {
67 edit.replace(ascribed_ty.syntax().text_range(), format!("{}", ty.display(db))); 68 edit.replace(ascribed_ty.syntax().text_range(), new_type_string);
68 } else { 69 } else {
69 edit.insert(name_range.end(), format!(": {}", ty.display(db))); 70 edit.insert(name_range.end(), format!(": {}", new_type_string));
70 } 71 }
71 }, 72 },
72 ) 73 )
@@ -174,4 +175,41 @@ mod tests {
174 "fn f() <|>{let a = match 1 {2 => 3, 3 => 5};}", 175 "fn f() <|>{let a = match 1 {2 => 3, 3 => 5};}",
175 ) 176 )
176 } 177 }
178
179 #[test]
180 fn closure_parameters_are_not_added() {
181 check_assist_not_applicable(
182 add_explicit_type,
183 r#"
184fn main() {
185 let multiply_by_two<|> = |i| i * 3;
186 let six = multiply_by_two(2);
187}"#,
188 )
189 }
190
191 #[test]
192 fn default_generics_should_not_be_added() {
193 check_assist(
194 add_explicit_type,
195 r#"
196struct Test<K, T = u8> {
197 k: K,
198 t: T,
199}
200
201fn main() {
202 let test<|> = Test { t: 23, k: 33 };
203}"#,
204 r#"
205struct Test<K, T = u8> {
206 k: K,
207 t: T,
208}
209
210fn main() {
211 let test<|>: Test<i32> = Test { t: 23, k: 33 };
212}"#,
213 );
214 }
177} 215}
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 6e0d89466..43f932e20 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -1132,6 +1132,10 @@ impl Type {
1132 Some(self.ty.value.as_callable()?.0) 1132 Some(self.ty.value.as_callable()?.0)
1133 } 1133 }
1134 1134
1135 pub fn is_closure(&self) -> bool {
1136 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. }))
1137 }
1138
1135 pub fn contains_unknown(&self) -> bool { 1139 pub fn contains_unknown(&self) -> bool {
1136 return go(&self.ty.value); 1140 return go(&self.ty.value);
1137 1141