about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-01-07 14:02:01 +0000
committerGitHub <noreply@github.com>2022-01-07 14:02:01 +0000
commitefb9b89163e4a6080f5d87133028de28cbaf310c (patch)
treec3143be3f189cdb132967d863d781710ef3bd920
parentb70493d095dd24a1b5c5721d2a1bd873444a63ec (diff)
parent0a240e31c5327cf509d335d0dfb6a5d97100ac0a (diff)
downloadrust-efb9b89163e4a6080f5d87133028de28cbaf310c.tar.gz
rust-efb9b89163e4a6080f5d87133028de28cbaf310c.zip
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 <jer_vannevel@outlook.com>
-rw-r--r--crates/ide_assists/src/handlers/add_turbo_fish.rs65
1 files changed, 60 insertions, 5 deletions
diff --git a/crates/ide_assists/src/handlers/add_turbo_fish.rs b/crates/ide_assists/src/handlers/add_turbo_fish.rs
index 2872edc9e10..c3d27f7ea65 100644
--- a/crates/ide_assists/src/handlers/add_turbo_fish.rs
+++ b/crates/ide_assists/src/handlers/add_turbo_fish.rs
@@ -1,4 +1,5 @@
 use ide_db::defs::{Definition, NameRefClass};
+use itertools::Itertools;
 use syntax::{ast, AstNode, SyntaxKind, T};
 
 use crate::{
@@ -77,8 +78,12 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
         }
     }
 
-    let number_of_arguments = generics.len();
-    let fish_head = std::iter::repeat("_").take(number_of_arguments).collect::<Vec<_>>().join(",");
+    let number_of_arguments = generics
+        .iter()
+        .filter(|param| {
+            matches!(param, hir::GenericParam::TypeParam(_) | hir::GenericParam::ConstParam(_))
+        })
+        .count();
 
     acc.add(
         AssistId("add_turbo_fish", AssistKind::RefactorRewrite),
@@ -86,10 +91,11 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
         ident.text_range(),
         |builder| match ctx.config.snippet_cap {
             Some(cap) => {
-                let snip = format!("::<${{0:{}}}>", fish_head);
+                let snip = format!("::<{}>", get_snippet_fish_head(number_of_arguments));
                 builder.insert_snippet(cap, ident.text_range().end(), snip)
             }
             None => {
+                let fish_head = std::iter::repeat("_").take(number_of_arguments).format(", ");
                 let snip = format!("::<{}>", fish_head);
                 builder.insert(ident.text_range().end(), snip);
             }
@@ -97,6 +103,17 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
     )
 }
 
+/// This will create a snippet string with tabstops marked
+fn get_snippet_fish_head(number_of_arguments: usize) -> String {
+    let mut fish_head = (1..number_of_arguments)
+        .format_with("", |i, f| f(&format_args!("${{{}:_}}, ", i)))
+        .to_string();
+
+    // tabstop 0 is a special case and always the last one
+    fish_head.push_str("${0:_}");
+    fish_head
+}
+
 #[cfg(test)]
 mod tests {
     use crate::tests::{check_assist, check_assist_by_label, check_assist_not_applicable};
@@ -135,7 +152,7 @@ fn main() {
             r#"
 fn make<T, A>() -> T {}
 fn main() {
-    make::<${0:_,_}>();
+    make::<${1:_}, ${0:_}>();
 }
 "#,
         );
@@ -154,7 +171,7 @@ fn main() {
             r#"
 fn make<T, A, B, C, D, E, F>() -> T {}
 fn main() {
-    make::<${0:_,_,_,_,_,_,_}>();
+    make::<${1:_}, ${2:_}, ${3:_}, ${4:_}, ${5:_}, ${6:_}, ${0:_}>();
 }
 "#,
         );
@@ -339,4 +356,42 @@ fn main() {
             "Add `: _` before assignment operator",
         );
     }
+
+    #[test]
+    fn add_turbo_fish_function_lifetime_parameter() {
+        check_assist(
+            add_turbo_fish,
+            r#"
+fn make<'a, T, A>(t: T, a: A) {}
+fn main() {
+    make$0(5, 2);
+}
+"#,
+            r#"
+fn make<'a, T, A>(t: T, a: A) {}
+fn main() {
+    make::<${1:_}, ${0:_}>(5, 2);
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn add_turbo_fish_function_const_parameter() {
+        check_assist(
+            add_turbo_fish,
+            r#"
+fn make<T, const N: usize>(t: T) {}
+fn main() {
+    make$0(3);
+}
+"#,
+            r#"
+fn make<T, const N: usize>(t: T) {}
+fn main() {
+    make::<${1:_}, ${0:_}>(3);
+}
+"#,
+        );
+    }
 }