Skip to content

Commit 77b5fe6

Browse files
committed
impl PartialOrd codegen for record enum
1 parent 95eff43 commit 77b5fe6

File tree

2 files changed

+77
-16
lines changed

2 files changed

+77
-16
lines changed

crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,35 @@ impl PartialOrd for Foo {
712712
)
713713
}
714714

715+
#[test]
716+
fn add_custom_impl_partial_ord_tuple_struct() {
717+
check_assist(
718+
replace_derive_with_manual_impl,
719+
r#"
720+
//- minicore: ord
721+
#[derive(Partial$0Ord)]
722+
struct Foo(usize, usize, usize);
723+
"#,
724+
r#"
725+
struct Foo(usize, usize, usize);
726+
727+
impl PartialOrd for Foo {
728+
$0fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
729+
match self.0.partial_cmp(other.0) {
730+
Some(core::cmp::Ordering::Eq) => {}
731+
ord => return ord,
732+
}
733+
match self.1.partial_cmp(other.1) {
734+
Some(core::cmp::Ordering::Eq) => {}
735+
ord => return ord,
736+
}
737+
self.2.partial_cmp(other.2)
738+
}
739+
}
740+
"#,
741+
)
742+
}
743+
715744
#[test]
716745
fn add_custom_impl_partial_ord_enum() {
717746
check_assist(
@@ -742,28 +771,50 @@ impl PartialOrd for Foo {
742771
}
743772

744773
#[test]
745-
fn add_custom_impl_partial_ord_tuple_struct() {
774+
fn add_custom_impl_partial_ord_record_enum() {
746775
check_assist(
747776
replace_derive_with_manual_impl,
748777
r#"
749778
//- minicore: ord
750779
#[derive(Partial$0Ord)]
751-
struct Foo(usize, usize, usize);
780+
enum Foo {
781+
Bar {
782+
bin: String,
783+
},
784+
Baz {
785+
qux: String,
786+
fez: String,
787+
},
788+
Qux {},
789+
Bin,
790+
}
752791
"#,
753792
r#"
754-
struct Foo(usize, usize, usize);
793+
enum Foo {
794+
Bar {
795+
bin: String,
796+
},
797+
Baz {
798+
qux: String,
799+
fez: String,
800+
},
801+
Qux {},
802+
Bin,
803+
}
755804
756805
impl PartialOrd for Foo {
757806
$0fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
758-
match self.0.partial_cmp(other.0) {
759-
Some(core::cmp::Ordering::Eq) => {}
760-
ord => return ord,
761-
}
762-
match self.1.partial_cmp(other.1) {
763-
Some(core::cmp::Ordering::Eq) => {}
764-
ord => return ord,
807+
match (self, other) {
808+
(Self::Bar { bin: l_bin }, Self::Bar { bin: r_bin }) => l_bin.partial_cmp(r_bin),
809+
(Self::Baz { qux: l_qux, fez: l_fez }, Self::Baz { qux: r_qux, fez: r_fez }) => {
810+
match l_qux.partial_cmp(r_qux) {
811+
Some(core::cmp::Ordering::Eq) => {}
812+
ord => return ord,
813+
}
814+
l_fez.partial_cmp(r_fez)
815+
}
816+
_ => core::mem::discriminant(self).partial_cmp(core::mem::discriminant(other)),
765817
}
766-
self.2.partial_cmp(other.2)
767818
}
768819
}
769820
"#,

crates/ide_assists/src/utils/gen_trait_fn_body.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
644644
match variant.field_list() {
645645
// => (Self::Bar { bin: l_bin }, Self::Bar { bin: r_bin }) => l_bin == r_bin,
646646
Some(ast::FieldList::RecordFieldList(list)) => {
647-
let mut expr = None;
647+
let mut exprs = vec![];
648648
let mut l_fields = vec![];
649649
let mut r_fields = vec![];
650650

@@ -659,16 +659,26 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
659659

660660
let lhs = make::expr_path(make::ext::ident_path(l_name));
661661
let rhs = make::expr_path(make::ext::ident_path(r_name));
662-
let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
663-
expr = gen_eq_chain(expr, cmp);
662+
let ord = gen_partial_cmp_call(lhs, rhs);
663+
exprs.push(ord);
664664
}
665665

666666
let left = gen_record_pat(gen_variant_path(&variant)?, l_fields);
667667
let right = gen_record_pat(gen_variant_path(&variant)?, r_fields);
668668
let tuple = make::tuple_pat(vec![left.into(), right.into()]);
669669

670-
if let Some(expr) = expr {
671-
arms.push(make::match_arm(Some(tuple.into()), None, expr));
670+
if let Some(tail) = exprs.pop() {
671+
let stmts = exprs
672+
.into_iter()
673+
.map(gen_partial_eq_match)
674+
.collect::<Option<Vec<ast::Stmt>>>()?;
675+
let expr = match stmts.len() {
676+
0 => tail,
677+
_ => make::block_expr(stmts.into_iter(), Some(tail))
678+
.indent(ast::edit::IndentLevel(1))
679+
.into(),
680+
};
681+
arms.push(make::match_arm(Some(tuple.into()), None, expr.into()));
672682
}
673683
}
674684

0 commit comments

Comments
 (0)