diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-03-02 15:28:41 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-03-02 15:28:41 +0000 |
commit | 04abf80b5f51b0efd1884fabc441bef16b75e89a (patch) | |
tree | c83a205fd1684eb7427c20d99a9d4bc3f07ff5ae /crates | |
parent | f8152171bbe160c4273d692d42c06eb7c6d66e1a (diff) | |
parent | 2c3c728e0aea90f80b6d066f97e59663371e91c5 (diff) |
Merge #7824
7824: feat: add type ascription r=matklad a=conradludgate
Based on this conversation: https://twitter.com/rust_analyzer/status/1366092401278922757
Built off of `add_turbo_fish`, finds the current `let` statement, checks if it has type/turbofish already and checks if the rhs function is generic.
There's one case I couldn't figure out how to implement that would be nice:
```rust
#[test]
fn add_type_ascription_function_result() {
check_assist(
add_type_ascription,
r#"
fn make<T>() -> Result<T, &'static str> {}
fn main() {
let x = make()$0;
}
"#,
r#"
fn make<T>() -> Result<T, &'static str> {}
fn main() {
let x: Result<${0:_}, &'static str> = make();
}
"#,
);
}
```
The `Function::ret_type` fn wasn't returning anything much useful so I'm not sure how to identity such scenarios just yet
Co-authored-by: Conrad Ludgate <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ide_assists/src/handlers/add_turbo_fish.rs | 108 |
1 files changed, 107 insertions, 1 deletions
diff --git a/crates/ide_assists/src/handlers/add_turbo_fish.rs b/crates/ide_assists/src/handlers/add_turbo_fish.rs index 8e9ea4fad..a08b55ebb 100644 --- a/crates/ide_assists/src/handlers/add_turbo_fish.rs +++ b/crates/ide_assists/src/handlers/add_turbo_fish.rs | |||
@@ -31,6 +31,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<( | |||
31 | return None; | 31 | return None; |
32 | } | 32 | } |
33 | mark::hit!(add_turbo_fish_after_call); | 33 | mark::hit!(add_turbo_fish_after_call); |
34 | mark::hit!(add_type_ascription_after_call); | ||
34 | arg_list.l_paren_token()?.prev_token().filter(|it| it.kind() == SyntaxKind::IDENT) | 35 | arg_list.l_paren_token()?.prev_token().filter(|it| it.kind() == SyntaxKind::IDENT) |
35 | })?; | 36 | })?; |
36 | let next_token = ident.next_token()?; | 37 | let next_token = ident.next_token()?; |
@@ -52,6 +53,24 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<( | |||
52 | mark::hit!(add_turbo_fish_non_generic); | 53 | mark::hit!(add_turbo_fish_non_generic); |
53 | return None; | 54 | return None; |
54 | } | 55 | } |
56 | |||
57 | if let Some(let_stmt) = ctx.find_node_at_offset::<ast::LetStmt>() { | ||
58 | if let_stmt.colon_token().is_none() { | ||
59 | let type_pos = let_stmt.pat()?.syntax().last_token()?.text_range().end(); | ||
60 | acc.add( | ||
61 | AssistId("add_type_ascription", AssistKind::RefactorRewrite), | ||
62 | "Add `: _` before assignment operator", | ||
63 | ident.text_range(), | ||
64 | |builder| match ctx.config.snippet_cap { | ||
65 | Some(cap) => builder.insert_snippet(cap, type_pos, ": ${0:_}"), | ||
66 | None => builder.insert(type_pos, ": _"), | ||
67 | }, | ||
68 | )? | ||
69 | } else { | ||
70 | mark::hit!(add_type_ascription_already_typed); | ||
71 | } | ||
72 | } | ||
73 | |||
55 | acc.add( | 74 | acc.add( |
56 | AssistId("add_turbo_fish", AssistKind::RefactorRewrite), | 75 | AssistId("add_turbo_fish", AssistKind::RefactorRewrite), |
57 | "Add `::<>`", | 76 | "Add `::<>`", |
@@ -65,7 +84,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<( | |||
65 | 84 | ||
66 | #[cfg(test)] | 85 | #[cfg(test)] |
67 | mod tests { | 86 | mod tests { |
68 | use crate::tests::{check_assist, check_assist_not_applicable}; | 87 | use crate::tests::{check_assist, check_assist_by_label, check_assist_not_applicable}; |
69 | 88 | ||
70 | use super::*; | 89 | use super::*; |
71 | use test_utils::mark; | 90 | use test_utils::mark; |
@@ -161,4 +180,91 @@ fn main() { | |||
161 | "#, | 180 | "#, |
162 | ); | 181 | ); |
163 | } | 182 | } |
183 | |||
184 | #[test] | ||
185 | fn add_type_ascription_function() { | ||
186 | check_assist_by_label( | ||
187 | add_turbo_fish, | ||
188 | r#" | ||
189 | fn make<T>() -> T {} | ||
190 | fn main() { | ||
191 | let x = make$0(); | ||
192 | } | ||
193 | "#, | ||
194 | r#" | ||
195 | fn make<T>() -> T {} | ||
196 | fn main() { | ||
197 | let x: ${0:_} = make(); | ||
198 | } | ||
199 | "#, | ||
200 | "Add `: _` before assignment operator", | ||
201 | ); | ||
202 | } | ||
203 | |||
204 | #[test] | ||
205 | fn add_type_ascription_after_call() { | ||
206 | mark::check!(add_type_ascription_after_call); | ||
207 | check_assist_by_label( | ||
208 | add_turbo_fish, | ||
209 | r#" | ||
210 | fn make<T>() -> T {} | ||
211 | fn main() { | ||
212 | let x = make()$0; | ||
213 | } | ||
214 | "#, | ||
215 | r#" | ||
216 | fn make<T>() -> T {} | ||
217 | fn main() { | ||
218 | let x: ${0:_} = make(); | ||
219 | } | ||
220 | "#, | ||
221 | "Add `: _` before assignment operator", | ||
222 | ); | ||
223 | } | ||
224 | |||
225 | #[test] | ||
226 | fn add_type_ascription_method() { | ||
227 | check_assist_by_label( | ||
228 | add_turbo_fish, | ||
229 | r#" | ||
230 | struct S; | ||
231 | impl S { | ||
232 | fn make<T>(&self) -> T {} | ||
233 | } | ||
234 | fn main() { | ||
235 | let x = S.make$0(); | ||
236 | } | ||
237 | "#, | ||
238 | r#" | ||
239 | struct S; | ||
240 | impl S { | ||
241 | fn make<T>(&self) -> T {} | ||
242 | } | ||
243 | fn main() { | ||
244 | let x: ${0:_} = S.make(); | ||
245 | } | ||
246 | "#, | ||
247 | "Add `: _` before assignment operator", | ||
248 | ); | ||
249 | } | ||
250 | |||
251 | #[test] | ||
252 | fn add_type_ascription_already_typed() { | ||
253 | mark::check!(add_type_ascription_already_typed); | ||
254 | check_assist( | ||
255 | add_turbo_fish, | ||
256 | r#" | ||
257 | fn make<T>() -> T {} | ||
258 | fn main() { | ||
259 | let x: () = make$0(); | ||
260 | } | ||
261 | "#, | ||
262 | r#" | ||
263 | fn make<T>() -> T {} | ||
264 | fn main() { | ||
265 | let x: () = make::<${0:_}>(); | ||
266 | } | ||
267 | "#, | ||
268 | ); | ||
269 | } | ||
164 | } | 270 | } |