add lifetime to SyntaxError

This commit is contained in:
Folkert 2021-02-07 22:26:55 +01:00
parent 148fffe969
commit 38b21c3474
15 changed files with 208 additions and 158 deletions

View file

@ -21,7 +21,7 @@ use roc_module::operator::{BinOp, CalledVia, UnaryOp};
use roc_region::all::{Located, Region};
use crate::parser::Progress::{self, *};
pub fn expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
pub fn expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
// Recursive parsers must not directly invoke functions which return (impl Parser),
// as this causes rustc to stack overflow. Thus, parse_expr must be a
// separate function which recurses by calling itself directly.
@ -152,7 +152,7 @@ fn loc_parse_expr_body_without_operators<'a>(
min_indent: u16,
arena: &'a Bump,
state: State<'a>,
) -> ParseResult<'a, Located<Expr<'a>>, SyntaxError> {
) -> ParseResult<'a, Located<Expr<'a>>, SyntaxError<'a>> {
one_of!(
loc_parenthetical_expr!(min_indent, loc_function_args(min_indent)),
loc!(string_literal()),
@ -171,7 +171,7 @@ fn loc_parse_expr_body_without_operators<'a>(
/// Unary (!) or (-)
///
/// e.g. `!x` or `-x`
pub fn unary_op<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
pub fn unary_op<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
one_of!(
map_with_arena!(
// must backtrack to distinguish `!x` from `!= y`
@ -200,7 +200,7 @@ fn parse_expr<'a>(
min_indent: u16,
arena: &'a Bump,
state: State<'a>,
) -> ParseResult<'a, Expr<'a>, SyntaxError> {
) -> ParseResult<'a, Expr<'a>, SyntaxError<'a>> {
let expr_parser = crate::parser::map_with_arena(
and!(
// First parse the body without operators, then try to parse possible operators after.
@ -243,7 +243,7 @@ fn parse_expr<'a>(
/// If the given Expr would parse the same way as a valid Pattern, convert it.
/// Example: (foo) could be either an Expr::Var("foo") or Pattern::Identifier("foo")
fn expr_to_pattern<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<'a>, SyntaxError> {
fn expr_to_pattern<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<'a>, SyntaxError<'a>> {
match expr {
Expr::Var { module_name, ident } => {
if module_name.is_empty() {
@ -337,7 +337,7 @@ fn expr_to_pattern<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<'a>,
pub fn assigned_expr_field_to_pattern<'a>(
arena: &'a Bump,
assigned_field: &AssignedField<'a, Expr<'a>>,
) -> Result<Pattern<'a>, SyntaxError> {
) -> Result<Pattern<'a>, SyntaxError<'a>> {
// the assigned fields always store spaces, but this slice is often empty
Ok(match assigned_field {
AssignedField::RequiredValue(name, spaces, value) => {
@ -387,7 +387,7 @@ pub fn assigned_pattern_field_to_pattern<'a>(
arena: &'a Bump,
assigned_field: &AssignedField<'a, Expr<'a>>,
backup_region: Region,
) -> Result<Located<Pattern<'a>>, SyntaxError> {
) -> Result<Located<Pattern<'a>>, SyntaxError<'a>> {
// the assigned fields always store spaces, but this slice is often empty
Ok(match assigned_field {
AssignedField::RequiredValue(name, spaces, value) => {
@ -490,7 +490,7 @@ pub fn assigned_pattern_field_to_pattern<'a>(
/// The '=' used in a def can't be followed by another '=' (or else it's actually
/// an "==") and also it can't be followed by '>' (or else it's actually an "=>")
fn equals_for_def<'a>() -> impl Parser<'a, (), SyntaxError> {
fn equals_for_def<'a>() -> impl Parser<'a, (), SyntaxError<'a>> {
|arena, state: State<'a>| match state.bytes.get(0) {
Some(b'=') => match state.bytes.get(1) {
Some(b'=') | Some(b'>') => Err((
@ -518,7 +518,7 @@ fn equals_for_def<'a>() -> impl Parser<'a, (), SyntaxError> {
/// * A pattern followed by '=' and then an expression
/// * A type annotation
/// * A type annotation followed on the next line by a pattern, an `=`, and an expression
pub fn def<'a>(min_indent: u16) -> impl Parser<'a, Def<'a>, SyntaxError> {
pub fn def<'a>(min_indent: u16) -> impl Parser<'a, Def<'a>, SyntaxError<'a>> {
let indented_more = min_indent + 1;
enum DefKind {
@ -598,11 +598,11 @@ pub fn def<'a>(min_indent: u16) -> impl Parser<'a, Def<'a>, SyntaxError> {
// PARSER HELPERS
fn pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError> {
fn pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError<'a>> {
space0_after(loc_closure_param(min_indent), min_indent)
}
fn spaces_then_comment_or_newline<'a>() -> impl Parser<'a, Option<&'a str>, SyntaxError> {
fn spaces_then_comment_or_newline<'a>() -> impl Parser<'a, Option<&'a str>, SyntaxError<'a>> {
skip_first!(
zero_or_more!(ascii_char(b' ')),
map!(
@ -617,7 +617,7 @@ fn spaces_then_comment_or_newline<'a>() -> impl Parser<'a, Option<&'a str>, Synt
type Body<'a> = (Located<Pattern<'a>>, Located<Expr<'a>>);
fn body_at_indent<'a>(indent_level: u16) -> impl Parser<'a, Body<'a>, SyntaxError> {
fn body_at_indent<'a>(indent_level: u16) -> impl Parser<'a, Body<'a>, SyntaxError<'a>> {
let indented_more = indent_level + 1;
and!(
skip_first!(spaces_exactly(indent_level), pattern(indent_level)),
@ -720,7 +720,9 @@ fn annotation_or_alias<'a>(
}
}
fn parse_defs<'a>(min_indent: u16) -> impl Parser<'a, Vec<'a, &'a Located<Def<'a>>>, SyntaxError> {
fn parse_defs<'a>(
min_indent: u16,
) -> impl Parser<'a, Vec<'a, &'a Located<Def<'a>>>, SyntaxError<'a>> {
let parse_def = move |a, s| space1_before(loc!(def(min_indent)), min_indent).parse(a, s);
zero_or_more!(allocated(parse_def))
@ -734,7 +736,7 @@ fn parse_def_expr<'a>(
state: State<'a>,
loc_first_pattern: Located<Pattern<'a>>,
spaces_after_equals: &'a [CommentOrNewline<'a>],
) -> ParseResult<'a, Expr<'a>, SyntaxError> {
) -> ParseResult<'a, Expr<'a>, SyntaxError<'a>> {
if def_start_col < min_indent {
Err((
NoProgress,
@ -825,7 +827,7 @@ fn parse_def_signature<'a>(
arena: &'a Bump,
state: State<'a>,
loc_first_pattern: Located<Pattern<'a>>,
) -> ParseResult<'a, Expr<'a>, SyntaxError> {
) -> ParseResult<'a, Expr<'a>, SyntaxError<'a>> {
let original_indent = state.indent_col;
if original_indent < min_indent {
@ -937,11 +939,11 @@ fn parse_def_signature<'a>(
}
}
// fn to_expr<'a>(arena, state, ((loc_first_annotation, opt_body), (mut defs, loc_ret))-> ParseResult<'a, Expr<'a>, SyntaxError>{
// fn to_expr<'a>(arena, state, ((loc_first_annotation, opt_body), (mut defs, loc_ret))-> ParseResult<'a, Expr<'a>, SyntaxError<'a>>{
// }
fn loc_function_arg<'a>(min_indent: u16) -> impl Parser<'a, Located<Expr<'a>>, SyntaxError> {
fn loc_function_arg<'a>(min_indent: u16) -> impl Parser<'a, Located<Expr<'a>>, SyntaxError<'a>> {
skip_first!(
// If this is a reserved keyword ("if", "then", "case, "when"),
// followed by a blank space, then it is not a function argument!
@ -960,7 +962,7 @@ fn loc_parse_function_arg<'a>(
min_indent: u16,
arena: &'a Bump,
state: State<'a>,
) -> ParseResult<'a, Located<Expr<'a>>, SyntaxError> {
) -> ParseResult<'a, Located<Expr<'a>>, SyntaxError<'a>> {
one_of!(
loc_parenthetical_expr!(min_indent, fail() /* don't parse args within args! */),
loc!(string_literal()),
@ -976,7 +978,7 @@ fn loc_parse_function_arg<'a>(
.parse(arena, state)
}
fn reserved_keyword<'a>() -> impl Parser<'a, (), SyntaxError> {
fn reserved_keyword<'a>() -> impl Parser<'a, (), SyntaxError<'a>> {
one_of!(
ascii_string(keyword::IF),
ascii_string(keyword::THEN),
@ -987,7 +989,7 @@ fn reserved_keyword<'a>() -> impl Parser<'a, (), SyntaxError> {
)
}
fn closure<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
fn closure<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
map_with_arena!(
skip_first!(
// All closures start with a '\' - e.g. (\x -> x + 1)
@ -1030,7 +1032,9 @@ fn closure<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
)
}
fn loc_closure_param<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError> {
fn loc_closure_param<'a>(
min_indent: u16,
) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError<'a>> {
move |arena, state| parse_closure_param(arena, state, min_indent)
}
@ -1038,7 +1042,7 @@ fn parse_closure_param<'a>(
arena: &'a Bump,
state: State<'a>,
min_indent: u16,
) -> ParseResult<'a, Located<Pattern<'a>>, SyntaxError> {
) -> ParseResult<'a, Located<Pattern<'a>>, SyntaxError<'a>> {
one_of!(
// An ident is the most common param, e.g. \foo -> ...
loc_ident_pattern(min_indent, true),
@ -1057,7 +1061,7 @@ fn parse_closure_param<'a>(
.parse(arena, state)
}
fn loc_pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError> {
fn loc_pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError<'a>> {
skip_first!(
// If this is a reserved keyword ("if", "then", "case, "when"), then
// it is not a pattern!
@ -1075,11 +1079,13 @@ fn loc_pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>, Syn
fn loc_tag_pattern_args<'a>(
min_indent: u16,
) -> impl Parser<'a, Vec<'a, Located<Pattern<'a>>>, SyntaxError> {
) -> impl Parser<'a, Vec<'a, Located<Pattern<'a>>>, SyntaxError<'a>> {
zero_or_more!(space1_before(loc_tag_pattern_arg(min_indent), min_indent))
}
fn loc_tag_pattern_arg<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError> {
fn loc_tag_pattern_arg<'a>(
min_indent: u16,
) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError<'a>> {
skip_first!(
// If this is a reserved keyword ("if", "then", "case, "when"), then
// it is not a function argument!
@ -1094,7 +1100,7 @@ fn loc_parse_tag_pattern_arg<'a>(
min_indent: u16,
arena: &'a Bump,
state: State<'a>,
) -> ParseResult<'a, Located<Pattern<'a>>, SyntaxError> {
) -> ParseResult<'a, Located<Pattern<'a>>, SyntaxError<'a>> {
one_of!(
loc_parenthetical_pattern(min_indent),
loc!(underscore_pattern()),
@ -1109,7 +1115,7 @@ fn loc_parse_tag_pattern_arg<'a>(
fn loc_parenthetical_pattern<'a>(
min_indent: u16,
) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError> {
) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError<'a>> {
between!(
ascii_char(b'('),
space0_around(
@ -1120,17 +1126,17 @@ fn loc_parenthetical_pattern<'a>(
)
}
fn number_pattern<'a>() -> impl Parser<'a, Pattern<'a>, SyntaxError> {
fn number_pattern<'a>() -> impl Parser<'a, Pattern<'a>, SyntaxError<'a>> {
map_with_arena!(number_literal(), |arena, expr| {
expr_to_pattern(arena, &expr).unwrap()
})
}
fn string_pattern<'a>() -> impl Parser<'a, Pattern<'a>, SyntaxError> {
fn string_pattern<'a>() -> impl Parser<'a, Pattern<'a>, SyntaxError<'a>> {
map!(crate::string_literal::parse(), Pattern::StrLiteral)
}
fn underscore_pattern<'a>() -> impl Parser<'a, Pattern<'a>, SyntaxError> {
fn underscore_pattern<'a>() -> impl Parser<'a, Pattern<'a>, SyntaxError<'a>> {
move |arena: &'a Bump, state: State<'a>| {
let (_, _, next_state) = ascii_char(b'_').parse(arena, state)?;
@ -1143,7 +1149,7 @@ fn underscore_pattern<'a>() -> impl Parser<'a, Pattern<'a>, SyntaxError> {
}
}
fn record_destructure<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>, SyntaxError> {
fn record_destructure<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>, SyntaxError<'a>> {
then(
collection!(
ascii_char(b'{'),
@ -1230,7 +1236,7 @@ fn record_destructure<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>, Synta
fn loc_ident_pattern<'a>(
min_indent: u16,
can_have_arguments: bool,
) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError> {
) -> impl Parser<'a, Located<Pattern<'a>>, SyntaxError<'a>> {
move |arena: &'a Bump, state: State<'a>| {
let (_, loc_ident, state) = loc!(ident()).parse(arena, state)?;
@ -1343,7 +1349,7 @@ mod when {
use crate::ast::WhenBranch;
/// Parser for when expressions.
pub fn expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
pub fn expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
then(
and!(
when_with_indent(min_indent),
@ -1389,7 +1395,7 @@ mod when {
}
/// Parsing when with indentation.
fn when_with_indent<'a>(min_indent: u16) -> impl Parser<'a, u16, SyntaxError> {
fn when_with_indent<'a>(min_indent: u16) -> impl Parser<'a, u16, SyntaxError<'a>> {
move |arena, state: State<'a>| {
parser::keyword(keyword::WHEN, min_indent)
.parse(arena, state)
@ -1398,7 +1404,9 @@ mod when {
}
/// Parsing branches of when conditional.
fn branches<'a>(min_indent: u16) -> impl Parser<'a, Vec<'a, &'a WhenBranch<'a>>, SyntaxError> {
fn branches<'a>(
min_indent: u16,
) -> impl Parser<'a, Vec<'a, &'a WhenBranch<'a>>, SyntaxError<'a>> {
move |arena, state| {
let mut branches: Vec<'a, &'a WhenBranch<'a>> = Vec::with_capacity_in(2, arena);
@ -1476,7 +1484,7 @@ mod when {
/// Parsing alternative patterns in when branches.
fn branch_alternatives<'a>(
min_indent: u16,
) -> impl Parser<'a, (Vec<'a, Located<Pattern<'a>>>, Option<Located<Expr<'a>>>), SyntaxError>
) -> impl Parser<'a, (Vec<'a, Located<Pattern<'a>>>, Option<Located<Expr<'a>>>), SyntaxError<'a>>
{
and!(
sep_by1(
@ -1508,7 +1516,7 @@ mod when {
}
/// Parsing the righthandside of a branch in a when conditional.
fn branch_result<'a>(indent: u16) -> impl Parser<'a, Located<Expr<'a>>, SyntaxError> {
fn branch_result<'a>(indent: u16) -> impl Parser<'a, Located<Expr<'a>>, SyntaxError<'a>> {
skip_first!(
ascii_string("->"),
space0_before(
@ -1519,7 +1527,7 @@ mod when {
}
}
pub fn if_expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
pub fn if_expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
map_with_arena!(
and!(
skip_first!(
@ -1573,7 +1581,7 @@ pub fn if_expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
#[inline(always)]
fn unary_negate_function_arg<'a>(
min_indent: u16,
) -> impl Parser<'a, Located<Expr<'a>>, SyntaxError> {
) -> impl Parser<'a, Located<Expr<'a>>, SyntaxError<'a>> {
then(
// Spaces, then '-', then *not* more spaces.
not_followed_by(
@ -1638,7 +1646,7 @@ fn unary_negate_function_arg<'a>(
fn loc_function_args<'a>(
min_indent: u16,
) -> impl Parser<'a, Vec<'a, Located<Expr<'a>>>, SyntaxError> {
) -> impl Parser<'a, Vec<'a, Located<Expr<'a>>>, SyntaxError<'a>> {
one_or_more!(move |arena: &'a Bump, s| {
map!(
and!(
@ -1669,7 +1677,7 @@ fn loc_function_args<'a>(
/// 3. The beginning of a definition (e.g. `foo =`)
/// 4. The beginning of a type annotation (e.g. `foo :`)
/// 5. A reserved keyword (e.g. `if ` or `case `), meaning we should do something else.
fn ident_etc<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
fn ident_etc<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
then(
and!(
loc!(ident()),
@ -1818,14 +1826,14 @@ fn ident_etc<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
)
}
pub fn ident_without_apply<'a>() -> impl Parser<'a, Expr<'a>, SyntaxError> {
pub fn ident_without_apply<'a>() -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
then(loc!(ident()), move |arena, state, progress, loc_ident| {
Ok((progress, ident_to_expr(arena, loc_ident.value), state))
})
}
/// Like equals_for_def(), except it produces the indent_col of the state rather than ()
pub fn equals_with_indent<'a>() -> impl Parser<'a, u16, SyntaxError> {
pub fn equals_with_indent<'a>() -> impl Parser<'a, u16, SyntaxError<'a>> {
move |arena, state: State<'a>| {
match state.bytes.first() {
Some(b'=') => {
@ -1851,7 +1859,7 @@ pub fn equals_with_indent<'a>() -> impl Parser<'a, u16, SyntaxError> {
}
}
pub fn colon_with_indent<'a>() -> impl Parser<'a, u16, SyntaxError> {
pub fn colon_with_indent<'a>() -> impl Parser<'a, u16, SyntaxError<'a>> {
move |arena, state: State<'a>| match state.bytes.first() {
Some(&byte) if byte == b':' => Ok((
MadeProgress,
@ -1895,7 +1903,7 @@ pub fn ident_to_expr<'a>(arena: &'a Bump, src: Ident<'a>) -> Expr<'a> {
}
}
fn binop<'a>() -> impl Parser<'a, BinOp, SyntaxError> {
fn binop<'a>() -> impl Parser<'a, BinOp, SyntaxError<'a>> {
one_of!(
// Sorted from highest to lowest predicted usage in practice,
// so that successful matches short-circuit as early as possible.
@ -1923,7 +1931,7 @@ fn binop<'a>() -> impl Parser<'a, BinOp, SyntaxError> {
)
}
pub fn list_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
pub fn list_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
let elems = collection_trailing_sep!(
ascii_char(b'['),
loc!(expr(min_indent)),
@ -1954,7 +1962,7 @@ pub fn list_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxErro
}
// Parser<'a, Vec<'a, Located<AssignedField<'a, S>>>>
fn record_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError> {
fn record_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
then(
and!(
attempt!(
@ -2068,7 +2076,7 @@ fn record_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError>
}
/// This is mainly for matching tags in closure params, e.g. \@Foo -> ...
pub fn private_tag<'a>() -> impl Parser<'a, &'a str, SyntaxError> {
pub fn private_tag<'a>() -> impl Parser<'a, &'a str, SyntaxError<'a>> {
map_with_arena!(
skip_first!(ascii_char(b'@'), global_tag()),
|arena: &'a Bump, name: &'a str| {
@ -2082,10 +2090,10 @@ pub fn private_tag<'a>() -> impl Parser<'a, &'a str, SyntaxError> {
}
/// This is mainly for matching tags in closure params, e.g. \Foo -> ...
pub fn global_tag<'a>() -> impl Parser<'a, &'a str, SyntaxError> {
pub fn global_tag<'a>() -> impl Parser<'a, &'a str, SyntaxError<'a>> {
global_tag_or_ident(|first_char| first_char.is_uppercase())
}
pub fn string_literal<'a>() -> impl Parser<'a, Expr<'a>, SyntaxError> {
pub fn string_literal<'a>() -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
map!(crate::string_literal::parse(), Expr::Str)
}