Fix round-trip parse->fmt->parse for dbg stmts with more than one arg

This commit is contained in:
Joshua Warner 2024-12-01 11:25:57 -08:00
parent cfd83ffcdf
commit 912db1b76b
No known key found for this signature in database
GPG key ID: 89AD497003F93FDD
25 changed files with 244 additions and 66 deletions

View file

@ -491,7 +491,11 @@ pub enum Expr<'a> {
Backpassing(&'a [Loc<Pattern<'a>>], &'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
Dbg,
DbgStmt(&'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
DbgStmt {
first: &'a Loc<Expr<'a>>,
extra_args: &'a [&'a Loc<Expr<'a>>],
continuation: &'a Loc<Expr<'a>>,
},
// This form of debug is a desugared call to roc_dbg
LowLevelDbg(&'a (&'a str, &'a str), &'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
@ -671,7 +675,15 @@ pub fn is_expr_suffixed(expr: &Expr) -> bool {
Expr::OpaqueRef(_) => false,
Expr::Backpassing(_, _, _) => false, // TODO: we might want to check this?
Expr::Dbg => false,
Expr::DbgStmt(a, b) => is_expr_suffixed(&a.value) || is_expr_suffixed(&b.value),
Expr::DbgStmt {
first,
extra_args,
continuation,
} => {
is_expr_suffixed(&first.value)
|| extra_args.iter().any(|a| is_expr_suffixed(&a.value))
|| is_expr_suffixed(&continuation.value)
}
Expr::LowLevelDbg(_, a, b) => is_expr_suffixed(&a.value) || is_expr_suffixed(&b.value),
Expr::Try => false,
Expr::UnaryOp(a, _) => is_expr_suffixed(&a.value),
@ -930,10 +942,17 @@ impl<'a, 'b> RecursiveValueDefIter<'a, 'b> {
expr_stack.push(&a.value);
expr_stack.push(&b.value);
}
DbgStmt(condition, cont) => {
DbgStmt {
first,
extra_args,
continuation,
} => {
expr_stack.reserve(2);
expr_stack.push(&condition.value);
expr_stack.push(&cont.value);
expr_stack.push(&first.value);
for arg in extra_args.iter() {
expr_stack.push(&arg.value);
}
expr_stack.push(&continuation.value);
}
LowLevelDbg(_, condition, cont) => {
expr_stack.reserve(2);
@ -2476,7 +2495,7 @@ impl<'a> Malformed for Expr<'a> {
Defs(defs, body) => defs.is_malformed() || body.is_malformed(),
Backpassing(args, call, body) => args.iter().any(|arg| arg.is_malformed()) || call.is_malformed() || body.is_malformed(),
Dbg => false,
DbgStmt(condition, continuation) => condition.is_malformed() || continuation.is_malformed(),
DbgStmt { first, extra_args, continuation } => first.is_malformed() || extra_args.iter().any(|a| a.is_malformed()) || continuation.is_malformed(),
LowLevelDbg(_, condition, continuation) => condition.is_malformed() || continuation.is_malformed(),
Try => false,
Return(return_value, after_return) => return_value.is_malformed() || after_return.is_some_and(|ar| ar.is_malformed()),