mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
make expression
return Type errors
This commit is contained in:
parent
2db94cf4e8
commit
21efa8cd71
1 changed files with 3 additions and 51 deletions
|
@ -19,7 +19,7 @@ use roc_region::all::{Located, Region};
|
||||||
pub fn located<'a>(
|
pub fn located<'a>(
|
||||||
min_indent: u16,
|
min_indent: u16,
|
||||||
) -> impl Parser<'a, Located<TypeAnnotation<'a>>, SyntaxError<'a>> {
|
) -> impl Parser<'a, Located<TypeAnnotation<'a>>, SyntaxError<'a>> {
|
||||||
specialize(|x, _, _| SyntaxError::Type(x), expression_e(min_indent))
|
specialize(|x, _, _| SyntaxError::Type(x), expression(min_indent))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -190,7 +190,7 @@ fn loc_type_in_parens<'a>(
|
||||||
between!(
|
between!(
|
||||||
word1(b'(', TInParens::Open),
|
word1(b'(', TInParens::Open),
|
||||||
space0_around_e(
|
space0_around_e(
|
||||||
move |arena, state| specialize_ref(TInParens::Type, expression_e(min_indent))
|
move |arena, state| specialize_ref(TInParens::Type, expression(min_indent))
|
||||||
.parse(arena, state),
|
.parse(arena, state),
|
||||||
min_indent,
|
min_indent,
|
||||||
TInParens::Space,
|
TInParens::Space,
|
||||||
|
@ -366,55 +366,7 @@ fn loc_applied_args_e<'a>(
|
||||||
zero_or_more!(loc_applied_arg_help(min_indent))
|
zero_or_more!(loc_applied_arg_help(min_indent))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expression<'a>(
|
fn expression<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>>, Type<'a>> {
|
||||||
min_indent: u16,
|
|
||||||
) -> impl Parser<'a, Located<TypeAnnotation<'a>>, SyntaxError<'a>> {
|
|
||||||
move |arena, state: State<'a>| {
|
|
||||||
let (p1, first, state) = space0_before(term(min_indent), min_indent).parse(arena, state)?;
|
|
||||||
let (p2, rest, state) = zero_or_more!(skip_first!(
|
|
||||||
ascii_char(b','),
|
|
||||||
space0_around(term(min_indent), min_indent)
|
|
||||||
))
|
|
||||||
.parse(arena, state)?;
|
|
||||||
|
|
||||||
// TODO this space0 is dropped, so newlines just before the function arrow when there
|
|
||||||
// is only one argument are not seen by the formatter. Can we do better?
|
|
||||||
let (p3, is_function, state) =
|
|
||||||
optional(skip_first!(space0(min_indent), ascii_string("->"))).parse(arena, state)?;
|
|
||||||
|
|
||||||
if is_function.is_some() {
|
|
||||||
let (p4, return_type, state) =
|
|
||||||
space0_before(term(min_indent), min_indent).parse(arena, state)?;
|
|
||||||
|
|
||||||
// prepare arguments
|
|
||||||
let mut arguments = Vec::with_capacity_in(rest.len() + 1, &arena);
|
|
||||||
arguments.push(first);
|
|
||||||
arguments.extend(rest);
|
|
||||||
let output = arena.alloc(arguments);
|
|
||||||
|
|
||||||
let result = Located {
|
|
||||||
region: return_type.region,
|
|
||||||
value: TypeAnnotation::Function(output, arena.alloc(return_type)),
|
|
||||||
};
|
|
||||||
let progress = p1.or(p2).or(p3).or(p4);
|
|
||||||
Ok((progress, result, state))
|
|
||||||
} else {
|
|
||||||
let progress = p1.or(p2).or(p3);
|
|
||||||
// if there is no function arrow, there cannot be more than 1 "argument"
|
|
||||||
if rest.is_empty() {
|
|
||||||
Ok((progress, first, state))
|
|
||||||
} else {
|
|
||||||
// e.g. `Int,Int` without an arrow and return type
|
|
||||||
let msg =
|
|
||||||
"TODO: Decide the correct error to return for 'Invalid function signature'"
|
|
||||||
.to_string();
|
|
||||||
Err((progress, SyntaxError::NotYetImplemented(msg), state))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expression_e<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>>, Type<'a>> {
|
|
||||||
move |arena, state: State<'a>| {
|
move |arena, state: State<'a>| {
|
||||||
let (p1, first, state) = space0_before_e(
|
let (p1, first, state) = space0_before_e(
|
||||||
term_help(min_indent),
|
term_help(min_indent),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue