Skip to content

Commit 04abf80

Browse files
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 <conradludgate@gmail.com>
2 parents f815217 + 2c3c728 commit 04abf80

File tree

1 file changed

+107
-1
lines changed

1 file changed

+107
-1
lines changed

crates/ide_assists/src/handlers/add_turbo_fish.rs

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
3131
return None;
3232
}
3333
mark::hit!(add_turbo_fish_after_call);
34+
mark::hit!(add_type_ascription_after_call);
3435
arg_list.l_paren_token()?.prev_token().filter(|it| it.kind() == SyntaxKind::IDENT)
3536
})?;
3637
let next_token = ident.next_token()?;
@@ -52,6 +53,24 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
5253
mark::hit!(add_turbo_fish_non_generic);
5354
return None;
5455
}
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+
5574
acc.add(
5675
AssistId("add_turbo_fish", AssistKind::RefactorRewrite),
5776
"Add `::<>`",
@@ -65,7 +84,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
6584

6685
#[cfg(test)]
6786
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};
6988

7089
use super::*;
7190
use test_utils::mark;
@@ -158,6 +177,93 @@ fn make() -> () {}
158177
fn main() {
159178
make$0();
160179
}
180+
"#,
181+
);
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+
}
161267
"#,
162268
);
163269
}

0 commit comments

Comments
 (0)