Skip to content

Commit 5f72bd8

Browse files
committed
impl PartialOrd codegen for tuple enum
1 parent 77b5fe6 commit 5f72bd8

File tree

2 files changed

+56
-12
lines changed

2 files changed

+56
-12
lines changed

crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,47 @@ impl PartialOrd for Foo {
821821
)
822822
}
823823

824+
#[test]
825+
fn add_custom_impl_partial_ord_tuple_enum() {
826+
check_assist(
827+
replace_derive_with_manual_impl,
828+
r#"
829+
//- minicore: ord
830+
#[derive(Partial$0Ord)]
831+
enum Foo {
832+
Bar(String),
833+
Baz(String, String),
834+
Qux(),
835+
Bin,
836+
}
837+
"#,
838+
r#"
839+
enum Foo {
840+
Bar(String),
841+
Baz(String, String),
842+
Qux(),
843+
Bin,
844+
}
845+
846+
impl PartialOrd for Foo {
847+
$0fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
848+
match (self, other) {
849+
(Self::Bar(l0), Self::Bar(r0)) => l0.partial_cmp(r0),
850+
(Self::Baz(l0, l1), Self::Baz(r0, r1)) => {
851+
match l0.partial_cmp(r0) {
852+
Some(core::cmp::Ordering::Eq) => {}
853+
ord => return ord,
854+
}
855+
l1.partial_cmp(r1)
856+
}
857+
_ => core::mem::discriminant(self).partial_cmp(core::mem::discriminant(other)),
858+
}
859+
}
860+
}
861+
"#,
862+
)
863+
}
864+
824865
#[test]
825866
fn add_custom_impl_partial_eq_record_struct() {
826867
check_assist(

crates/ide_assists/src/utils/gen_trait_fn_body.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -574,13 +574,6 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
574574
}
575575

576576
fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
577-
fn gen_eq_chain(expr: Option<ast::Expr>, cmp: ast::Expr) -> Option<ast::Expr> {
578-
match expr {
579-
Some(expr) => Some(make::expr_op(ast::BinOp::BooleanAnd, expr, cmp)),
580-
None => Some(cmp),
581-
}
582-
}
583-
584577
fn gen_partial_eq_match(match_target: ast::Expr) -> Option<ast::Stmt> {
585578
let mut arms = vec![];
586579

@@ -683,7 +676,7 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
683676
}
684677

685678
Some(ast::FieldList::TupleFieldList(list)) => {
686-
let mut expr = None;
679+
let mut exprs = vec![];
687680
let mut l_fields = vec![];
688681
let mut r_fields = vec![];
689682

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

699692
let lhs = make::expr_path(make::ext::ident_path(&l_name));
700693
let rhs = make::expr_path(make::ext::ident_path(&r_name));
701-
let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
702-
expr = gen_eq_chain(expr, cmp);
694+
let ord = gen_partial_cmp_call(lhs, rhs);
695+
exprs.push(ord);
703696
}
704697

705698
let left = make::tuple_struct_pat(gen_variant_path(&variant)?, l_fields);
706699
let right = make::tuple_struct_pat(gen_variant_path(&variant)?, r_fields);
707700
let tuple = make::tuple_pat(vec![left.into(), right.into()]);
708701

709-
if let Some(expr) = expr {
710-
arms.push(make::match_arm(Some(tuple.into()), None, expr));
702+
if let Some(tail) = exprs.pop() {
703+
let stmts = exprs
704+
.into_iter()
705+
.map(gen_partial_eq_match)
706+
.collect::<Option<Vec<ast::Stmt>>>()?;
707+
let expr = match stmts.len() {
708+
0 => tail,
709+
_ => make::block_expr(stmts.into_iter(), Some(tail))
710+
.indent(ast::edit::IndentLevel(1))
711+
.into(),
712+
};
713+
arms.push(make::match_arm(Some(tuple.into()), None, expr.into()));
711714
}
712715
}
713716
None => continue,

0 commit comments

Comments
 (0)