about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs73
-rw-r--r--crates/ide_assists/src/utils/gen_trait_fn_body.rs20
2 files changed, 77 insertions, 16 deletions
diff --git a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
index 03211f728a8..0f5a3843153 100644
--- a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -713,6 +713,35 @@ impl PartialOrd for Foo {
     }
 
     #[test]
+    fn add_custom_impl_partial_ord_tuple_struct() {
+        check_assist(
+            replace_derive_with_manual_impl,
+            r#"
+//- minicore: ord
+#[derive(Partial$0Ord)]
+struct Foo(usize, usize, usize);
+"#,
+            r#"
+struct Foo(usize, usize, usize);
+
+impl PartialOrd for Foo {
+    $0fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
+        match self.0.partial_cmp(other.0) {
+            Some(core::cmp::Ordering::Eq) => {}
+            ord => return ord,
+        }
+        match self.1.partial_cmp(other.1) {
+            Some(core::cmp::Ordering::Eq) => {}
+            ord => return ord,
+        }
+        self.2.partial_cmp(other.2)
+    }
+}
+"#,
+        )
+    }
+
+    #[test]
     fn add_custom_impl_partial_ord_enum() {
         check_assist(
             replace_derive_with_manual_impl,
@@ -742,28 +771,50 @@ impl PartialOrd for Foo {
     }
 
     #[test]
-    fn add_custom_impl_partial_ord_tuple_struct() {
+    fn add_custom_impl_partial_ord_record_enum() {
         check_assist(
             replace_derive_with_manual_impl,
             r#"
 //- minicore: ord
 #[derive(Partial$0Ord)]
-struct Foo(usize, usize, usize);
+enum Foo {
+    Bar {
+        bin: String,
+    },
+    Baz {
+        qux: String,
+        fez: String,
+    },
+    Qux {},
+    Bin,
+}
 "#,
             r#"
-struct Foo(usize, usize, usize);
+enum Foo {
+    Bar {
+        bin: String,
+    },
+    Baz {
+        qux: String,
+        fez: String,
+    },
+    Qux {},
+    Bin,
+}
 
 impl PartialOrd for Foo {
     $0fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
-        match self.0.partial_cmp(other.0) {
-            Some(core::cmp::Ordering::Eq) => {}
-            ord => return ord,
-        }
-        match self.1.partial_cmp(other.1) {
-            Some(core::cmp::Ordering::Eq) => {}
-            ord => return ord,
+        match (self, other) {
+            (Self::Bar { bin: l_bin }, Self::Bar { bin: r_bin }) => l_bin.partial_cmp(r_bin),
+            (Self::Baz { qux: l_qux, fez: l_fez }, Self::Baz { qux: r_qux, fez: r_fez }) => {
+                match l_qux.partial_cmp(r_qux) {
+                    Some(core::cmp::Ordering::Eq) => {}
+                    ord => return ord,
+                }
+                l_fez.partial_cmp(r_fez)
+            }
+            _ => core::mem::discriminant(self).partial_cmp(core::mem::discriminant(other)),
         }
-        self.2.partial_cmp(other.2)
     }
 }
 "#,
diff --git a/crates/ide_assists/src/utils/gen_trait_fn_body.rs b/crates/ide_assists/src/utils/gen_trait_fn_body.rs
index 9bafae46c5c..9633fd263b6 100644
--- a/crates/ide_assists/src/utils/gen_trait_fn_body.rs
+++ b/crates/ide_assists/src/utils/gen_trait_fn_body.rs
@@ -644,7 +644,7 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
                 match variant.field_list() {
                     // => (Self::Bar { bin: l_bin }, Self::Bar { bin: r_bin }) => l_bin == r_bin,
                     Some(ast::FieldList::RecordFieldList(list)) => {
-                        let mut expr = None;
+                        let mut exprs = vec![];
                         let mut l_fields = vec![];
                         let mut r_fields = vec![];
 
@@ -659,16 +659,26 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
 
                             let lhs = make::expr_path(make::ext::ident_path(l_name));
                             let rhs = make::expr_path(make::ext::ident_path(r_name));
-                            let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
-                            expr = gen_eq_chain(expr, cmp);
+                            let ord = gen_partial_cmp_call(lhs, rhs);
+                            exprs.push(ord);
                         }
 
                         let left = gen_record_pat(gen_variant_path(&variant)?, l_fields);
                         let right = gen_record_pat(gen_variant_path(&variant)?, r_fields);
                         let tuple = make::tuple_pat(vec![left.into(), right.into()]);
 
-                        if let Some(expr) = expr {
-                            arms.push(make::match_arm(Some(tuple.into()), None, expr));
+                        if let Some(tail) = exprs.pop() {
+                            let stmts = exprs
+                                .into_iter()
+                                .map(gen_partial_eq_match)
+                                .collect::<Option<Vec<ast::Stmt>>>()?;
+                            let expr = match stmts.len() {
+                                0 => tail,
+                                _ => make::block_expr(stmts.into_iter(), Some(tail))
+                                    .indent(ast::edit::IndentLevel(1))
+                                    .into(),
+                            };
+                            arms.push(make::match_arm(Some(tuple.into()), None, expr.into()));
                         }
                     }