Skip to content

Commit efb9b89

Browse files
bors[bot]Vannevelj
andauthored
Merge #11220
11220: Turbo fish assist: don't include lifetime parameters r=Veykril a=Vannevelj Fixes #11219 The issue talks about three different types of params: type, const & lifetime. I wasn't entirely sure which ones are intended to be included here so I've gone for the type & const params (i.e. exclude lifetime). I've added a test case for both a lifetime param and a const param. I'm still making my way through the rust book (chapter 7, yay) so I'm not too sure yet what these are but my testing shows that this approach generates code that compiles. Co-authored-by: Jeroen Vannevel <[email protected]>
2 parents b70493d + 0a240e3 commit efb9b89

File tree

1 file changed

+60
-5
lines changed

1 file changed

+60
-5
lines changed

crates/ide_assists/src/handlers/add_turbo_fish.rs

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use ide_db::defs::{Definition, NameRefClass};
2+
use itertools::Itertools;
23
use syntax::{ast, AstNode, SyntaxKind, T};
34

45
use crate::{
@@ -77,26 +78,42 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
7778
}
7879
}
7980

80-
let number_of_arguments = generics.len();
81-
let fish_head = std::iter::repeat("_").take(number_of_arguments).collect::<Vec<_>>().join(",");
81+
let number_of_arguments = generics
82+
.iter()
83+
.filter(|param| {
84+
matches!(param, hir::GenericParam::TypeParam(_) | hir::GenericParam::ConstParam(_))
85+
})
86+
.count();
8287

8388
acc.add(
8489
AssistId("add_turbo_fish", AssistKind::RefactorRewrite),
8590
"Add `::<>`",
8691
ident.text_range(),
8792
|builder| match ctx.config.snippet_cap {
8893
Some(cap) => {
89-
let snip = format!("::<${{0:{}}}>", fish_head);
94+
let snip = format!("::<{}>", get_snippet_fish_head(number_of_arguments));
9095
builder.insert_snippet(cap, ident.text_range().end(), snip)
9196
}
9297
None => {
98+
let fish_head = std::iter::repeat("_").take(number_of_arguments).format(", ");
9399
let snip = format!("::<{}>", fish_head);
94100
builder.insert(ident.text_range().end(), snip);
95101
}
96102
},
97103
)
98104
}
99105

106+
/// This will create a snippet string with tabstops marked
107+
fn get_snippet_fish_head(number_of_arguments: usize) -> String {
108+
let mut fish_head = (1..number_of_arguments)
109+
.format_with("", |i, f| f(&format_args!("${{{}:_}}, ", i)))
110+
.to_string();
111+
112+
// tabstop 0 is a special case and always the last one
113+
fish_head.push_str("${0:_}");
114+
fish_head
115+
}
116+
100117
#[cfg(test)]
101118
mod tests {
102119
use crate::tests::{check_assist, check_assist_by_label, check_assist_not_applicable};
@@ -135,7 +152,7 @@ fn main() {
135152
r#"
136153
fn make<T, A>() -> T {}
137154
fn main() {
138-
make::<${0:_,_}>();
155+
make::<${1:_}, ${0:_}>();
139156
}
140157
"#,
141158
);
@@ -154,7 +171,7 @@ fn main() {
154171
r#"
155172
fn make<T, A, B, C, D, E, F>() -> T {}
156173
fn main() {
157-
make::<${0:_,_,_,_,_,_,_}>();
174+
make::<${1:_}, ${2:_}, ${3:_}, ${4:_}, ${5:_}, ${6:_}, ${0:_}>();
158175
}
159176
"#,
160177
);
@@ -339,4 +356,42 @@ fn main() {
339356
"Add `: _` before assignment operator",
340357
);
341358
}
359+
360+
#[test]
361+
fn add_turbo_fish_function_lifetime_parameter() {
362+
check_assist(
363+
add_turbo_fish,
364+
r#"
365+
fn make<'a, T, A>(t: T, a: A) {}
366+
fn main() {
367+
make$0(5, 2);
368+
}
369+
"#,
370+
r#"
371+
fn make<'a, T, A>(t: T, a: A) {}
372+
fn main() {
373+
make::<${1:_}, ${0:_}>(5, 2);
374+
}
375+
"#,
376+
);
377+
}
378+
379+
#[test]
380+
fn add_turbo_fish_function_const_parameter() {
381+
check_assist(
382+
add_turbo_fish,
383+
r#"
384+
fn make<T, const N: usize>(t: T) {}
385+
fn main() {
386+
make$0(3);
387+
}
388+
"#,
389+
r#"
390+
fn make<T, const N: usize>(t: T) {}
391+
fn main() {
392+
make::<${1:_}, ${0:_}>(3);
393+
}
394+
"#,
395+
);
396+
}
342397
}

0 commit comments

Comments
 (0)