Revert "Merge pull request #7267 from joshuawarner32/fuzzing-bugs-2"

This reverts commit 364249a29d, reversing
changes made to 0e550a7f68.
This commit is contained in:
Anton-4 2024-11-30 18:43:16 +01:00
parent a92cf2fdf9
commit 74d137cad4
No known key found for this signature in database
GPG key ID: 0971D718C0A9B937
347 changed files with 1157 additions and 8214 deletions

View file

@ -298,11 +298,8 @@ fn loc_possibly_negative_or_negated_term<'a>(
let parse_unary_negate = move |arena, state: State<'a>, min_indent: u32| {
let initial = state.clone();
let (_, (loc_op, loc_expr), state) = and(
loc(unary_negate()),
loc_possibly_negative_or_negated_term(options),
)
.parse(arena, state, min_indent)?;
let (_, (loc_op, loc_expr), state) =
and(loc(unary_negate()), loc_term(options)).parse(arena, state, min_indent)?;
let loc_expr = numeric_negate_expression(arena, initial, loc_op, loc_expr, &[]);
@ -310,23 +307,19 @@ fn loc_possibly_negative_or_negated_term<'a>(
};
one_of![
parse_unary_negate.trace("d"),
parse_unary_negate,
// this will parse negative numbers, which the unary negate thing up top doesn't (for now)
loc(specialize_err(EExpr::Number, number_literal_help())).trace("c"),
loc(specialize_err(EExpr::Number, number_literal_help())),
loc(map_with_arena(
and(
loc(byte(b'!', EExpr::Start)),
space0_before_e(
loc_possibly_negative_or_negated_term(options),
EExpr::IndentStart
)
space0_before_e(loc_term(options), EExpr::IndentStart)
),
|arena: &'a Bump, (loc_op, loc_expr): (Loc<_>, _)| {
Expr::UnaryOp(arena.alloc(loc_expr), Loc::at(loc_op.region, UnaryOp::Not))
}
))
.trace("b"),
loc_term_or_underscore_or_conditional(options).trace("a")
)),
loc_term_or_underscore_or_conditional(options)
]
}
@ -335,7 +328,7 @@ fn fail_expr_start_e<'a, T: 'a>() -> impl Parser<'a, T, EExpr<'a>> {
}
fn unary_negate<'a>() -> impl Parser<'a, (), EExpr<'a>> {
move |_arena: &'a Bump, state: State<'a>, min_indent: u32| {
move |_arena: &'a Bump, state: State<'a>, _min_indent: u32| {
// a minus is unary iff
//
// - it is preceded by whitespace (spaces, newlines, comments)
@ -346,10 +339,7 @@ fn unary_negate<'a>() -> impl Parser<'a, (), EExpr<'a>> {
.map(|c| c.is_ascii_whitespace() || *c == b'#')
.unwrap_or(false);
if state.bytes().starts_with(b"-")
&& !followed_by_whitespace
&& state.column() >= min_indent
{
if state.bytes().starts_with(b"-") && !followed_by_whitespace {
// the negate is only unary if it is not followed by whitespace
let state = state.advance(1);
Ok((MadeProgress, (), state))
@ -469,7 +459,7 @@ fn parse_expr_after_apply<'a>(
before_op: State<'a>,
initial_state: State<'a>,
) -> Result<(Progress, Expr<'a>, State<'a>), (Progress, EExpr<'a>)> {
match loc(bin_op(check_for_defs)).parse(arena, state.clone(), call_min_indent) {
match loc(bin_op(check_for_defs)).parse(arena, state.clone(), min_indent) {
Err((MadeProgress, f)) => Err((MadeProgress, f)),
Ok((_, loc_op, state)) => {
expr_state.consume_spaces(arena);
@ -855,13 +845,13 @@ fn numeric_negate_expression<'a, T>(
let region = Region::new(start, expr.region.end());
let new_expr = match expr.value {
Expr::Num(string) if !string.starts_with('-') => {
Expr::Num(string) => {
let new_string =
unsafe { std::str::from_utf8_unchecked(&state.bytes()[..string.len() + 1]) };
Expr::Num(new_string)
}
Expr::Float(string) if !string.starts_with('-') => {
Expr::Float(string) => {
let new_string =
unsafe { std::str::from_utf8_unchecked(&state.bytes()[..string.len() + 1]) };
@ -870,11 +860,11 @@ fn numeric_negate_expression<'a, T>(
Expr::NonBase10Int {
string,
base,
is_negative: false,
is_negative,
} => {
// don't include the minus sign here; it will not be parsed right
Expr::NonBase10Int {
is_negative: true,
is_negative: !is_negative,
string,
base,
}
@ -1161,7 +1151,9 @@ fn parse_stmt_alias_or_opaque<'a>(
AliasOrOpaque::Alias => {
let (_, signature, state) = alias_signature().parse(arena, state, min_indent)?;
let signature = signature.map(|v| v.maybe_before(arena, spaces_after_operator));
// TODO: this code used to be broken and it dropped the spaces after the operator.
// The formatter is not expecting this, so let's keep it as is for now.
// let signature = signature.map(|v| v.maybe_before(arena, spaces_after_operator));
let header = TypeHeader {
name: Loc::at(expr.region, name),
@ -1180,7 +1172,9 @@ fn parse_stmt_alias_or_opaque<'a>(
let (_, (signature, derived), state) =
opaque_signature().parse(arena, state, indented_more)?;
let signature = signature.map(|v| v.maybe_before(arena, spaces_after_operator));
// TODO: this code used to be broken and it dropped the spaces after the operator.
// The formatter is not expecting this, so let's keep it as is for now.
// let signature = signature.map(|v| v.maybe_before(arena, spaces_after_operator));
let header = TypeHeader {
name: Loc::at(expr.region, name),
@ -1861,7 +1855,7 @@ fn parse_expr_end<'a>(
Err((NoProgress, _)) => {
let before_op = state.clone();
// try an operator
match loc(bin_op(check_for_defs)).parse(arena, state.clone(), call_min_indent) {
match loc(bin_op(check_for_defs)).parse(arena, state.clone(), min_indent) {
Err((MadeProgress, f)) => Err((MadeProgress, f)),
Ok((_, loc_op, state)) => {
expr_state.consume_spaces(arena);
@ -1905,7 +1899,7 @@ fn parse_stmt_after_apply<'a>(
initial_state: State<'a>,
) -> ParseResult<'a, Stmt<'a>, EExpr<'a>> {
let before_op = state.clone();
match loc(operator()).parse(arena, state.clone(), call_min_indent) {
match loc(operator()).parse(arena, state.clone(), min_indent) {
Err((MadeProgress, f)) => Err((MadeProgress, f)),
Ok((_, loc_op, state)) => {
expr_state.consume_spaces(arena);
@ -2178,7 +2172,7 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<
| Expr::If { .. }
| Expr::When(_, _)
| Expr::Dbg
| Expr::DbgStmt { .. }
| Expr::DbgStmt(_, _)
| Expr::LowLevelDbg(_, _, _)
| Expr::Return(_, _)
| Expr::MalformedSuffixed(..)
@ -3092,13 +3086,16 @@ fn stmts_to_defs<'a>(
_,
) = e
{
if args.len() != 1 {
// TODO: this should be done in can, not parsing!
return Err(EExpr::Dbg(
EExpect::DbgArity(sp_stmt.item.region.start()),
sp_stmt.item.region.start(),
));
}
let condition = &args[0];
let rest = stmts_to_expr(&stmts[i + 1..], arena)?;
let e = Expr::DbgStmt {
first: condition,
extra_args: &args[1..],
continuation: arena.alloc(rest),
};
let e = Expr::DbgStmt(condition, arena.alloc(rest));
let e = if sp_stmt.before.is_empty() {
e
@ -3214,11 +3211,7 @@ fn stmts_to_defs<'a>(
if exprify_dbg {
let e = if i + 1 < stmts.len() {
let rest = stmts_to_expr(&stmts[i + 1..], arena)?;
Expr::DbgStmt {
first: arena.alloc(condition),
extra_args: &[],
continuation: arena.alloc(rest),
}
Expr::DbgStmt(arena.alloc(condition), arena.alloc(rest))
} else {
Expr::Apply(
arena.alloc(Loc {
@ -3806,9 +3799,9 @@ enum OperatorOrDef {
}
fn bin_op<'a>(check_for_defs: bool) -> impl Parser<'a, BinOp, EExpr<'a>> {
move |_, state: State<'a>, min_indent| {
move |_, state: State<'a>, _m| {
let start = state.pos();
let (_, op, state) = operator_help(EExpr::Start, EExpr::BadOperator, state, min_indent)?;
let (_, op, state) = operator_help(EExpr::Start, EExpr::BadOperator, state)?;
let err_progress = if check_for_defs {
MadeProgress
} else {
@ -3829,8 +3822,7 @@ fn bin_op<'a>(check_for_defs: bool) -> impl Parser<'a, BinOp, EExpr<'a>> {
}
fn operator<'a>() -> impl Parser<'a, OperatorOrDef, EExpr<'a>> {
(move |_, state, min_indent| operator_help(EExpr::Start, EExpr::BadOperator, state, min_indent))
.trace("operator")
(move |_, state, _m| operator_help(EExpr::Start, EExpr::BadOperator, state)).trace("operator")
}
#[inline(always)]
@ -3838,7 +3830,6 @@ fn operator_help<'a, F, G, E>(
to_expectation: F,
to_error: G,
mut state: State<'a>,
min_indent: u32,
) -> ParseResult<'a, OperatorOrDef, E>
where
F: Fn(Position) -> E,
@ -3864,21 +3855,7 @@ where
match chomped {
"" => Err((NoProgress, to_expectation(state.pos()))),
"+" => good!(OperatorOrDef::BinOp(BinOp::Plus), 1),
"-" => {
// A unary minus must only match if we are at the correct indent level; indent level doesn't
// matter for the rest of the operators.
// Note that a unary minus is distinguished by not having a space after it
let has_whitespace = matches!(
state.bytes().get(1),
Some(b' ' | b'#' | b'\n' | b'\r' | b'\t') | None
);
if !has_whitespace && state.column() < min_indent {
return Err((NoProgress, to_expectation(state.pos())));
}
good!(OperatorOrDef::BinOp(BinOp::Minus), 1)
}
"-" => good!(OperatorOrDef::BinOp(BinOp::Minus), 1),
"*" => good!(OperatorOrDef::BinOp(BinOp::Star), 1),
"/" => good!(OperatorOrDef::BinOp(BinOp::Slash), 1),
"%" => good!(OperatorOrDef::BinOp(BinOp::Percent), 1),
@ -3906,10 +3883,6 @@ where
}
"<-" => good!(OperatorOrDef::Backpassing, 2),
"!" => Err((NoProgress, to_error("!", state.pos()))),
"&" => {
// makes no progress, so it does not interfere with record updaters / `&foo`
Err((NoProgress, to_error("&", state.pos())))
}
_ => bad_made_progress!(chomped),
}
}