mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Merge pull request #7225 from joshuawarner32/fuzzing-bugs
Fix some bugs found via fuzzing
This commit is contained in:
commit
19a716b8e9
11 changed files with 152 additions and 6 deletions
|
@ -88,6 +88,7 @@ pub fn fmt_collection<'a, 'buf, T: ExtractSpaces<'a> + Formattable>(
|
||||||
buf.indent(item_indent);
|
buf.indent(item_indent);
|
||||||
item.item.format(buf, item_indent);
|
item.item.format(buf, item_indent);
|
||||||
|
|
||||||
|
buf.indent(item_indent);
|
||||||
buf.push(',');
|
buf.push(',');
|
||||||
|
|
||||||
if !item.after.is_empty() {
|
if !item.after.is_empty() {
|
||||||
|
|
|
@ -71,9 +71,7 @@ impl<'a> Formattable for Expr<'a> {
|
||||||
LowLevelDbg(_, _, _) => unreachable!(
|
LowLevelDbg(_, _, _) => unreachable!(
|
||||||
"LowLevelDbg should only exist after desugaring, not during formatting"
|
"LowLevelDbg should only exist after desugaring, not during formatting"
|
||||||
),
|
),
|
||||||
Return(return_value, after_return) => {
|
Return(_return_value, _after_return) => true,
|
||||||
return_value.is_multiline() || after_return.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
If {
|
If {
|
||||||
if_thens: branches,
|
if_thens: branches,
|
||||||
|
@ -1039,7 +1037,33 @@ fn fmt_dbg_stmt<'a>(
|
||||||
|
|
||||||
buf.spaces(1);
|
buf.spaces(1);
|
||||||
|
|
||||||
condition.format(buf, indent);
|
fn should_outdent(mut expr: &Expr) -> bool {
|
||||||
|
loop {
|
||||||
|
match expr {
|
||||||
|
Expr::ParensAround(_) | Expr::List(_) | Expr::Record(_) | Expr::Tuple(_) => {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
Expr::SpaceAfter(inner, _) => {
|
||||||
|
expr = inner;
|
||||||
|
}
|
||||||
|
_ => return false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let inner_indent = if should_outdent(&condition.value) {
|
||||||
|
indent
|
||||||
|
} else {
|
||||||
|
indent + INDENT
|
||||||
|
};
|
||||||
|
|
||||||
|
let cond_value = condition.value.extract_spaces();
|
||||||
|
|
||||||
|
let is_defs = matches!(cond_value.item, Expr::Defs(_, _));
|
||||||
|
|
||||||
|
let newlines = if is_defs { Newlines::Yes } else { Newlines::No };
|
||||||
|
|
||||||
|
condition.format_with_options(buf, Parens::NotNeeded, newlines, inner_indent);
|
||||||
|
|
||||||
// Always put a blank line after the `dbg` line(s)
|
// Always put a blank line after the `dbg` line(s)
|
||||||
buf.ensure_ends_with_blank_line();
|
buf.ensure_ends_with_blank_line();
|
||||||
|
@ -1097,6 +1121,9 @@ fn fmt_return<'a>(
|
||||||
return_value.format(buf, return_indent);
|
return_value.format(buf, return_indent);
|
||||||
|
|
||||||
if let Some(after_return) = after_return {
|
if let Some(after_return) = after_return {
|
||||||
|
if after_return.value.extract_spaces().before.is_empty() {
|
||||||
|
buf.ensure_ends_with_newline();
|
||||||
|
}
|
||||||
after_return.format_with_options(buf, parens, newlines, indent);
|
after_return.format_with_options(buf, parens, newlines, indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1681,6 +1708,7 @@ fn sub_expr_requests_parens(expr: &Expr<'_>) -> bool {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Expr::If { .. } => true,
|
Expr::If { .. } => true,
|
||||||
|
Expr::Defs(_, _) => true,
|
||||||
Expr::SpaceBefore(e, _) => sub_expr_requests_parens(e),
|
Expr::SpaceBefore(e, _) => sub_expr_requests_parens(e),
|
||||||
Expr::SpaceAfter(e, _) => sub_expr_requests_parens(e),
|
Expr::SpaceAfter(e, _) => sub_expr_requests_parens(e),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
|
@ -2094,7 +2094,7 @@ pub fn merge_spaces<'a>(
|
||||||
fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<'a>, ()> {
|
fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<'a>, ()> {
|
||||||
let mut expr = expr.extract_spaces();
|
let mut expr = expr.extract_spaces();
|
||||||
|
|
||||||
if let Expr::ParensAround(loc_expr) = &expr.item {
|
while let Expr::ParensAround(loc_expr) = &expr.item {
|
||||||
let expr_inner = loc_expr.extract_spaces();
|
let expr_inner = loc_expr.extract_spaces();
|
||||||
|
|
||||||
expr.before = merge_spaces(arena, expr.before, expr_inner.before);
|
expr.before = merge_spaces(arena, expr.before, expr_inner.before);
|
||||||
|
|
|
@ -1056,7 +1056,11 @@ where
|
||||||
// the next character should not be an identifier character
|
// the next character should not be an identifier character
|
||||||
// to prevent treating `whence` or `iffy` as keywords
|
// to prevent treating `whence` or `iffy` as keywords
|
||||||
match state.bytes().get(width) {
|
match state.bytes().get(width) {
|
||||||
Some(next) if *next == b' ' || *next == b'#' || *next == b'\n' || *next == b'\r' => {
|
Some(
|
||||||
|
b' ' | b'#' | b'\n' | b'\r' | b'\t' | b',' | b'(' | b')' | b'[' | b']' | b'{'
|
||||||
|
| b'}' | b'"' | b'\'' | b'/' | b'\\' | b'+' | b'*' | b'%' | b'^' | b'&' | b'|'
|
||||||
|
| b'<' | b'>' | b'=' | b'!' | b'~' | b'`' | b';' | b':' | b'?' | b'.',
|
||||||
|
) => {
|
||||||
state = state.advance(width);
|
state = state.advance(width);
|
||||||
Ok((MadeProgress, (), state))
|
Ok((MadeProgress, (), state))
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
dbg
|
||||||
|
q
|
||||||
|
qt
|
||||||
|
|
||||||
|
g
|
||||||
|
qt
|
|
@ -0,0 +1,70 @@
|
||||||
|
SpaceAfter(
|
||||||
|
DbgStmt(
|
||||||
|
@5-10 SpaceBefore(
|
||||||
|
Defs(
|
||||||
|
Defs {
|
||||||
|
tags: [
|
||||||
|
EitherIndex(2147483648),
|
||||||
|
],
|
||||||
|
regions: [
|
||||||
|
@5-6,
|
||||||
|
],
|
||||||
|
space_before: [
|
||||||
|
Slice { start: 0, length: 0 },
|
||||||
|
],
|
||||||
|
space_after: [
|
||||||
|
Slice { start: 0, length: 0 },
|
||||||
|
],
|
||||||
|
spaces: [],
|
||||||
|
type_defs: [],
|
||||||
|
value_defs: [
|
||||||
|
Stmt(
|
||||||
|
@5-6 Var {
|
||||||
|
module_name: "",
|
||||||
|
ident: "q",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
@8-10 SpaceBefore(
|
||||||
|
Var {
|
||||||
|
module_name: "",
|
||||||
|
ident: "qt",
|
||||||
|
},
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
@11-16 SpaceBefore(
|
||||||
|
Apply(
|
||||||
|
@11-12 Var {
|
||||||
|
module_name: "",
|
||||||
|
ident: "g",
|
||||||
|
},
|
||||||
|
[
|
||||||
|
@14-16 SpaceBefore(
|
||||||
|
Var {
|
||||||
|
module_name: "",
|
||||||
|
ident: "qt",
|
||||||
|
},
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
Space,
|
||||||
|
),
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,5 @@
|
||||||
|
dbg
|
||||||
|
q
|
||||||
|
qt
|
||||||
|
g
|
||||||
|
qt
|
|
@ -0,0 +1,3 @@
|
||||||
|
L [
|
||||||
|
try, # [then2[#
|
||||||
|
]
|
|
@ -0,0 +1,25 @@
|
||||||
|
SpaceAfter(
|
||||||
|
Apply(
|
||||||
|
@0-1 Tag(
|
||||||
|
"L",
|
||||||
|
),
|
||||||
|
[
|
||||||
|
@1-16 List(
|
||||||
|
[
|
||||||
|
@2-5 SpaceAfter(
|
||||||
|
Try,
|
||||||
|
[
|
||||||
|
LineComment(
|
||||||
|
"[then2[#",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
Space,
|
||||||
|
),
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,2 @@
|
||||||
|
L[try#[then2[#
|
||||||
|
]
|
|
@ -314,6 +314,7 @@ mod test_snapshots {
|
||||||
pass/dbg.expr,
|
pass/dbg.expr,
|
||||||
pass/dbg_stmt.expr,
|
pass/dbg_stmt.expr,
|
||||||
pass/dbg_stmt_multiline.expr,
|
pass/dbg_stmt_multiline.expr,
|
||||||
|
pass/dbg_stmt_two_exprs.expr,
|
||||||
pass/def_bang.expr,
|
pass/def_bang.expr,
|
||||||
pass/defs_suffixed_middle_extra_indents.moduledefs,
|
pass/defs_suffixed_middle_extra_indents.moduledefs,
|
||||||
pass/destructure_tag_assignment.expr,
|
pass/destructure_tag_assignment.expr,
|
||||||
|
@ -501,6 +502,7 @@ mod test_snapshots {
|
||||||
pass/tag_pattern.expr,
|
pass/tag_pattern.expr,
|
||||||
pass/ten_times_eleven.expr,
|
pass/ten_times_eleven.expr,
|
||||||
pass/three_arg_closure.expr,
|
pass/three_arg_closure.expr,
|
||||||
|
pass/try_blank_in_list.expr,
|
||||||
pass/try_function_after_pipe.expr,
|
pass/try_function_after_pipe.expr,
|
||||||
pass/try_pipe_suffix.expr,
|
pass/try_pipe_suffix.expr,
|
||||||
pass/try_plain_prefix.expr,
|
pass/try_plain_prefix.expr,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue