diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/src/handlers/add_explicit_type.rs | 48 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 4 |
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#" | ||
184 | fn 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#" | ||
196 | struct Test<K, T = u8> { | ||
197 | k: K, | ||
198 | t: T, | ||
199 | } | ||
200 | |||
201 | fn main() { | ||
202 | let test<|> = Test { t: 23, k: 33 }; | ||
203 | }"#, | ||
204 | r#" | ||
205 | struct Test<K, T = u8> { | ||
206 | k: K, | ||
207 | t: T, | ||
208 | } | ||
209 | |||
210 | fn 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 | ||