Skip to content

Commit 1cf7af7

Browse files
committed
wip enum record/tuple generation
1 parent 65ce87c commit 1cf7af7

File tree

3 files changed

+78
-8
lines changed

3 files changed

+78
-8
lines changed

crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ enum Foo {
765765
Baz {
766766
quz: String,
767767
fez: String,
768-
}
768+
},
769769
}
770770
771771
impl PartialEq for Foo {

crates/ide_assists/src/utils/gen_trait_fn_body.rs

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -346,15 +346,73 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
346346
// `Hash` cannot be derived for unions, so no default impl can be provided.
347347
ast::Adt::Union(_) => return None,
348348

349-
// FIXME: generate trait variants
350349
ast::Adt::Enum(enum_) => {
351350
// => std::mem::discriminant(self) == std::mem::discriminant(other)
352-
let lhs = make::expr_path(make::ext::ident_path("self"));
353-
let lhs = make::expr_call(gen_discriminant(), make::arg_list(Some(lhs)));
354-
let rhs = make::expr_path(make::ext::ident_path("other"));
355-
let rhs = make::expr_call(gen_discriminant(), make::arg_list(Some(rhs)));
356-
let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
357-
make::block_expr(None, Some(cmp)).indent(ast::edit::IndentLevel(1))
351+
let self_name = make::expr_path(make::ext::ident_path("self"));
352+
let lhs = make::expr_call(gen_discriminant(), make::arg_list(Some(self_name.clone())));
353+
let other_name = make::expr_path(make::ext::ident_path("other"));
354+
let rhs = make::expr_call(gen_discriminant(), make::arg_list(Some(other_name.clone())));
355+
let eq_check = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
356+
357+
let mut case_count = 0;
358+
let mut arms = vec![];
359+
for variant in enum_.variant_list()?.variants() {
360+
case_count += 1;
361+
match variant.field_list() {
362+
// => (Self::Bar { bin: l_bin }, Self::Bar { bin: r_bin }) => l_bin == r_bin,
363+
Some(ast::FieldList::RecordFieldList(list)) => {
364+
// let mut pats = vec![];
365+
// let mut fields = vec![];
366+
for field in list.fields() {
367+
// let field_name = field.name()?;
368+
// let pat = make::record_pat(path, pats);
369+
// let pat = make::ident_pat(false, false, field_name.clone());
370+
// pats.push(pat.into());
371+
372+
// let path = make::ext::ident_path(&field_name.to_string());
373+
// let method_call = gen_clone_call(make::expr_path(path));
374+
// let name_ref = make::name_ref(&field_name.to_string());
375+
// let field = make::record_expr_field(name_ref, Some(method_call));
376+
// fields.push(field);
377+
}
378+
// let pat = make::record_pat(variant_name.clone(), pats.into_iter());
379+
// let fields = make::record_expr_field_list(fields);
380+
// let record_expr = make::record_expr(variant_name, fields).into();
381+
// arms.push(make::match_arm(Some(pat.into()), None, record_expr));
382+
todo!("implement tuple record iteration")
383+
}
384+
Some(ast::FieldList::TupleFieldList(list)) => {
385+
todo!("implement tuple enum iteration")
386+
}
387+
None => continue,
388+
}
389+
}
390+
391+
if !arms.is_empty() && case_count > arms.len() {
392+
let lhs = make::wildcard_pat().into();
393+
arms.push(make::match_arm(Some(lhs), None, make::expr_literal("true").into()));
394+
}
395+
396+
let expr = match arms.len() {
397+
0 => eq_check,
398+
_ => {
399+
let condition = make::condition(eq_check, None);
400+
401+
let match_target = make::expr_tuple(vec![self_name, other_name]);
402+
let list = make::match_arm_list(arms).indent(ast::edit::IndentLevel(1));
403+
let match_expr = Some(make::expr_match(match_target, list));
404+
let then_branch = make::block_expr(None, match_expr);
405+
let then_branch = then_branch.indent(ast::edit::IndentLevel(1));
406+
407+
let else_branche = make::expr_literal("false");
408+
let else_branche = make::block_expr(None, Some(else_branche.into()))
409+
.indent(ast::edit::IndentLevel(1));
410+
411+
make::expr_if(condition, then_branch, Some(else_branche.into()))
412+
}
413+
};
414+
415+
make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1))
358416
}
359417
ast::Adt::Struct(strukt) => match strukt.field_list() {
360418
Some(ast::FieldList::RecordFieldList(field_list)) => {

crates/syntax/src/ast/expr_ext.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,18 @@ pub enum ElseBranch {
160160
IfExpr(ast::IfExpr),
161161
}
162162

163+
impl From<ast::BlockExpr> for ElseBranch {
164+
fn from(block_expr: ast::BlockExpr) -> Self {
165+
Self::Block(block_expr)
166+
}
167+
}
168+
169+
impl From<ast::IfExpr> for ElseBranch {
170+
fn from(if_expr: ast::IfExpr) -> Self {
171+
Self::IfExpr(if_expr)
172+
}
173+
}
174+
163175
impl ast::IfExpr {
164176
pub fn then_branch(&self) -> Option<ast::BlockExpr> {
165177
self.blocks().next()

0 commit comments

Comments
 (0)