Repository: rust-analyzer/rust-analyzer
Pull request #2091 (2019-10-27 14:02:49)

use new api for flip_trait_bound assist


Patch:
diff --git a/crates/ra_assists/src/assists/flip_trait_bound.rs b/crates/ra_assists/src/assists/flip_trait_bound.rs
index 203092d03f..1625b241f1 100644
--- a/crates/ra_assists/src/assists/flip_trait_bound.rs
+++ b/crates/ra_assists/src/assists/flip_trait_bound.rs
@@ -1,21 +1,32 @@
-//! Assist for swapping traits inside of a trait bound list
-//!
-//! E.g. `A + B` => `B + A` when the cursor is placed by the `+` inside of a
-//! trait bound list
-
 use hir::db::HirDatabase;
-use ra_syntax::{algo::non_trivia_sibling, ast::TypeBoundList, Direction, T};
+use ra_syntax::{
+    algo::non_trivia_sibling,
+    ast::{self, AstNode},
+    Direction, T,
+};
 
 use crate::{Assist, AssistCtx, AssistId};
 
-/// Flip trait bound assist.
+// Assist: flip_trait_bound
+//
+// Flips two trait bounds.
+//
+// ```
+// fn foo<T: Clone +<|> Copy>() { }
+// ```
+// ->
+// ```
+// fn foo<T: Copy + Clone>() { }
+// ```
 pub(crate) fn flip_trait_bound(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
-    // Make sure we're in a `TypeBoundList`
-    ctx.node_at_offset::<TypeBoundList>()?;
-
     // We want to replicate the behavior of `flip_binexpr` by only suggesting
     // the assist when the cursor is on a `+`
-    let plus = ctx.token_at_offset().find(|tkn| tkn.kind() == T![+])?;
+    let plus = ctx.find_token_at_offset(T![+])?;
+
+    // Make sure we're in a `TypeBoundList`
+    if ast::TypeBoundList::cast(plus.parent()).is_none() {
+        return None;
+    }
 
     let (before, after) = (
         non_trivia_sibling(plus.clone().into(), Direction::Prev)?,
diff --git a/docs/user/assists.md b/docs/user/assists.md
index e4d08a7dca..b1fe44d840 100644
--- a/docs/user/assists.md
+++ b/docs/user/assists.md
@@ -248,6 +248,18 @@ fn main() {
 }
 ```
 
+## `flip_trait_bound`
+
+Flips two trait bounds.
+
+```rust
+// BEFORE
+fn foo<T: Clone +┃ Copy>() { }
+
+// AFTER
+fn foo<T: Copy + Clone>() { }
+```
+
 ## `inline_local_variable`
 
 Inlines local variable.


Test patch:
diff --git a/crates/ra_assists/src/doc_tests.rs b/crates/ra_assists/src/doc_tests.rs
index 0ccf9d7308..6e1e3de843 100644
--- a/crates/ra_assists/src/doc_tests.rs
+++ b/crates/ra_assists/src/doc_tests.rs
@@ -17,7 +17,17 @@ fn check(assist_id: &str, before: &str, after: &str) {
     let (_assist_id, action) = crate::assists(&db, frange)
         .into_iter()
         .find(|(id, _)| id.id.0 == assist_id)
-        .unwrap_or_else(|| panic!("Assist {:?} is not applicable", assist_id));
+        .unwrap_or_else(|| {
+            panic!(
+                "\n\nAssist is not applicable: {}\nAvailable assists: {}",
+                assist_id,
+                crate::assists(&db, frange)
+                    .into_iter()
+                    .map(|(id, _)| id.id.0)
+                    .collect::<Vec<_>>()
+                    .join(", ")
+            )
+        });
 
     let actual = action.edit.apply(&before);
     assert_eq_text!(after, &actual);
diff --git a/crates/ra_assists/src/doc_tests/generated.rs b/crates/ra_assists/src/doc_tests/generated.rs
index b8d335911f..ebe49aecfe 100644
--- a/crates/ra_assists/src/doc_tests/generated.rs
+++ b/crates/ra_assists/src/doc_tests/generated.rs
@@ -255,6 +255,19 @@ fn main() {
     )
 }
 
+#[test]
+fn doctest_flip_trait_bound() {
+    check(
+        "flip_trait_bound",
+        r#####"
+fn foo<T: Clone +<|> Copy>() { }
+"#####,
+        r#####"
+fn foo<T: Copy + Clone>() { }
+"#####,
+    )
+}
+
 #[test]
 fn doctest_inline_local_variable() {
     check(