mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
better error message for type start
This commit is contained in:
parent
22f77ed966
commit
8d80dc97c8
4 changed files with 85 additions and 71 deletions
|
@ -221,10 +221,7 @@ fn loc_possibly_negative_or_negated_term<'a>(
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fail_expr_start_e<'a, T>() -> impl Parser<'a, T, EExpr<'a>>
|
fn fail_expr_start_e<'a, T: 'a>() -> impl Parser<'a, T, EExpr<'a>> {
|
||||||
where
|
|
||||||
T: 'a,
|
|
||||||
{
|
|
||||||
|_arena, state: State<'a>| Err((NoProgress, EExpr::Start(state.line, state.column), state))
|
|_arena, state: State<'a>| Err((NoProgress, EExpr::Start(state.line, state.column), state))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,7 +1016,7 @@ fn parse_expr_operator<'a>(
|
||||||
|
|
||||||
match expr_to_pattern_help(arena, &call.value) {
|
match expr_to_pattern_help(arena, &call.value) {
|
||||||
Ok(good) => {
|
Ok(good) => {
|
||||||
let (_, mut ann_type, state) = specialize(
|
let parser = specialize(
|
||||||
EExpr::Type,
|
EExpr::Type,
|
||||||
space0_before_e(
|
space0_before_e(
|
||||||
type_annotation::located_help(indented_more),
|
type_annotation::located_help(indented_more),
|
||||||
|
@ -1027,21 +1024,28 @@ fn parse_expr_operator<'a>(
|
||||||
Type::TSpace,
|
Type::TSpace,
|
||||||
Type::TIndentStart,
|
Type::TIndentStart,
|
||||||
),
|
),
|
||||||
)
|
);
|
||||||
.parse(arena, state)?;
|
|
||||||
|
|
||||||
// put the spaces from after the operator in front of the call
|
match parser.parse(arena, state) {
|
||||||
if !spaces_after_operator.is_empty() {
|
Err((_, fail, state)) => return Err((MadeProgress, fail, state)),
|
||||||
ann_type = arena
|
Ok((_, mut ann_type, state)) => {
|
||||||
.alloc(ann_type.value)
|
// put the spaces from after the operator in front of the call
|
||||||
.with_spaces_before(spaces_after_operator, ann_type.region);
|
if !spaces_after_operator.is_empty() {
|
||||||
|
ann_type = arena.alloc(ann_type.value).with_spaces_before(
|
||||||
|
spaces_after_operator,
|
||||||
|
ann_type.region,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let alias_region =
|
||||||
|
Region::span_across(&call.region, &ann_type.region);
|
||||||
|
|
||||||
|
let alias =
|
||||||
|
Def::Annotation(Located::at(expr_region, good), ann_type);
|
||||||
|
|
||||||
|
(&*arena.alloc(Located::at(alias_region, alias)), state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let alias_region = Region::span_across(&call.region, &ann_type.region);
|
|
||||||
|
|
||||||
let alias = Def::Annotation(Located::at(expr_region, good), ann_type);
|
|
||||||
|
|
||||||
(&*arena.alloc(Located::at(alias_region, alias)), state)
|
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// this `:` likely occured inline; treat it as an invalid operator
|
// this `:` likely occured inline; treat it as an invalid operator
|
||||||
|
|
|
@ -45,6 +45,10 @@ fn tag_union_type<'a>(min_indent: u16) -> impl Parser<'a, TypeAnnotation<'a>, TT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fail_type_start<'a, T: 'a>() -> impl Parser<'a, T, Type<'a>> {
|
||||||
|
|_arena, state: State<'a>| Err((NoProgress, Type::TStart(state.line, state.column), state))
|
||||||
|
}
|
||||||
|
|
||||||
fn term<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>>, Type<'a>> {
|
fn term<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>>, Type<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena!(
|
||||||
and!(
|
and!(
|
||||||
|
@ -54,7 +58,8 @@ fn term<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>>, Typ
|
||||||
loc!(specialize(Type::TRecord, record_type(min_indent))),
|
loc!(specialize(Type::TRecord, record_type(min_indent))),
|
||||||
loc!(specialize(Type::TTagUnion, tag_union_type(min_indent))),
|
loc!(specialize(Type::TTagUnion, tag_union_type(min_indent))),
|
||||||
loc!(applied_type(min_indent)),
|
loc!(applied_type(min_indent)),
|
||||||
loc!(parse_type_variable)
|
loc!(parse_type_variable),
|
||||||
|
fail_type_start(),
|
||||||
),
|
),
|
||||||
// Inline alias notation, e.g. [ Nil, Cons a (List a) ] as List a
|
// Inline alias notation, e.g. [ Nil, Cons a (List a) ] as List a
|
||||||
one_of![
|
one_of![
|
||||||
|
|
|
@ -1781,7 +1781,13 @@ fn to_type_report<'a>(
|
||||||
let doc = alloc.stack(vec![
|
let doc = alloc.stack(vec![
|
||||||
alloc.reflow(r"I just started parsing a type, but I got stuck here:"),
|
alloc.reflow(r"I just started parsing a type, but I got stuck here:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(surroundings, region),
|
||||||
alloc.note("I may be confused by indentation"),
|
alloc.concat(vec![
|
||||||
|
alloc.reflow(r"I am expecting a type next, like "),
|
||||||
|
alloc.parser_suggestion("Bool"),
|
||||||
|
alloc.reflow(r" or "),
|
||||||
|
alloc.parser_suggestion("List a"),
|
||||||
|
alloc.reflow("."),
|
||||||
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Report {
|
Report {
|
||||||
|
|
|
@ -3265,20 +3265,20 @@ mod test_reporting {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── TYPE MISMATCH ───────────────────────────────────────────────────────────────
|
── TYPE MISMATCH ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
Something is off with the body of the `x` definition:
|
Something is off with the body of the `x` definition:
|
||||||
|
|
||||||
4│ x : AList I64 I64
|
4│ x : AList I64 I64
|
||||||
5│ x = ACons 0 (BCons 1 (ACons "foo" BNil ))
|
5│ x = ACons 0 (BCons 1 (ACons "foo" BNil ))
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
This `ACons` global tag application has the type:
|
This `ACons` global tag application has the type:
|
||||||
|
|
||||||
[ ACons Num (Integer Signed64) [ BCons (Num a) [ ACons Str [ BNil
|
[ ACons Num (Integer Signed64) [ BCons (Num a) [ ACons Str [ BNil
|
||||||
]b ]c ]d, ANil ]
|
]b ]c ]d, ANil ]
|
||||||
|
|
||||||
But the type annotation on `x` says it should be:
|
But the type annotation on `x` says it should be:
|
||||||
|
|
||||||
[ ACons I64 BList I64 I64, ANil ]
|
[ ACons I64 BList I64 I64, ANil ]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -4155,12 +4155,12 @@ mod test_reporting {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── UNKNOWN OPERATOR ────────────────────────────────────────────────────────────
|
── UNKNOWN OPERATOR ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
This looks like an operator, but it's not one I recognize!
|
This looks like an operator, but it's not one I recognize!
|
||||||
|
|
||||||
1│ f :: I64
|
1│ f :: I64
|
||||||
^^
|
^^
|
||||||
|
|
||||||
I have no specific suggestion for this operator, see TODO for the full
|
I have no specific suggestion for this operator, see TODO for the full
|
||||||
list of operators in Roc.
|
list of operators in Roc.
|
||||||
"#
|
"#
|
||||||
|
@ -4188,12 +4188,12 @@ mod test_reporting {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── TOO MANY ARGS ───────────────────────────────────────────────────────────────
|
── TOO MANY ARGS ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
This value is not a function, but it was given 3 arguments:
|
This value is not a function, but it was given 3 arguments:
|
||||||
|
|
||||||
3│ x == 5
|
3│ x == 5
|
||||||
^
|
^
|
||||||
|
|
||||||
Are there any missing commas? Or missing parentheses?
|
Are there any missing commas? Or missing parentheses?
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -4474,16 +4474,16 @@ mod test_reporting {
|
||||||
report_problem_as(
|
report_problem_as(
|
||||||
"# comment with a \t\n4",
|
"# comment with a \t\n4",
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
"
|
||||||
── TAB CHARACTER ───────────────────────────────────────────────────────────────
|
── TAB CHARACTER ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
I encountered a tab character
|
I encountered a tab character
|
||||||
|
|
||||||
1│ # comment with a
|
1│ # comment with a \t
|
||||||
^
|
^
|
||||||
|
|
||||||
Tab characters are not allowed.
|
Tab characters are not allowed.
|
||||||
"#
|
"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -4499,12 +4499,14 @@ mod test_reporting {
|
||||||
),
|
),
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── BAD TYPE VARIABLE ───────────────────────────────────────────────────────────
|
── UNFINISHED TYPE ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
I am expecting a type variable, but I got stuck here:
|
I just started parsing a type, but I got stuck here:
|
||||||
|
|
||||||
1│ f : (
|
1│ f : (
|
||||||
^
|
^
|
||||||
|
|
||||||
|
I am expecting a type next, like Bool or List a.
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -4583,7 +4585,6 @@ mod test_reporting {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn type_apply_stray_dot() {
|
fn type_apply_stray_dot() {
|
||||||
// TODO good message
|
// TODO good message
|
||||||
report_problem_as(
|
report_problem_as(
|
||||||
|
@ -4594,16 +4595,14 @@ mod test_reporting {
|
||||||
),
|
),
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── UNFINISHED PARENTHESES ──────────────────────────────────────────────────────
|
── UNFINISHED TYPE ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
I am partway through parsing a type in parentheses, but I got stuck
|
I just started parsing a type, but I got stuck here:
|
||||||
here:
|
|
||||||
|
|
||||||
1│ f : ( I64
|
1│ f : .
|
||||||
^
|
^
|
||||||
|
|
||||||
I was expecting to see a closing parenthesis before this, so try
|
I am expecting a type next, like Bool or List a.
|
||||||
adding a ) and see if that helps?
|
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -4658,19 +4657,19 @@ mod test_reporting {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── MISSING FINAL EXPRESSION ────────────────────────────────────────────────────
|
── MISSING FINAL EXPRESSION ────────────────────────────────────────────────────
|
||||||
|
|
||||||
I am partway through parsing a definition's final expression, but I
|
I am partway through parsing a definition's final expression, but I
|
||||||
got stuck here:
|
got stuck here:
|
||||||
|
|
||||||
1│ f : Foo.foo
|
1│ f : Foo.foo
|
||||||
^
|
^
|
||||||
|
|
||||||
This definition is missing a final expression. A nested definition
|
This definition is missing a final expression. A nested definition
|
||||||
must be followed by either another definition, or an expression
|
must be followed by either another definition, or an expression
|
||||||
|
|
||||||
x = 4
|
x = 4
|
||||||
y = 2
|
y = 2
|
||||||
|
|
||||||
x + y
|
x + y
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -4973,13 +4972,13 @@ mod test_reporting {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── MISSING EXPRESSION ──────────────────────────────────────────────────────────
|
── MISSING EXPRESSION ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
I am partway through parsing a definition, but I got stuck here:
|
I am partway through parsing a definition, but I got stuck here:
|
||||||
|
|
||||||
1│ when Just 4 is
|
1│ when Just 4 is
|
||||||
2│ Just when ->
|
2│ Just when ->
|
||||||
^
|
^
|
||||||
|
|
||||||
I was expecting to see an expression like 42 or "hello".
|
I was expecting to see an expression like 42 or "hello".
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -5646,14 +5645,14 @@ mod test_reporting {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
I cannot find a `bar` value
|
I cannot find a `bar` value
|
||||||
|
|
||||||
1│ [ "foo", bar("") ]
|
1│ [ "foo", bar("") ]
|
||||||
^^^
|
^^^
|
||||||
|
|
||||||
these names seem close though:
|
these names seem close though:
|
||||||
|
|
||||||
Nat
|
Nat
|
||||||
Str
|
Str
|
||||||
U8
|
U8
|
||||||
|
@ -5729,16 +5728,16 @@ mod test_reporting {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── UNKNOWN OPERATOR ────────────────────────────────────────────────────────────
|
── UNKNOWN OPERATOR ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
This looks like an operator, but it's not one I recognize!
|
This looks like an operator, but it's not one I recognize!
|
||||||
|
|
||||||
1│ main =
|
1│ main =
|
||||||
2│ (\x -> x) : I64
|
2│ (\x -> x) : I64
|
||||||
^
|
^
|
||||||
|
|
||||||
The has-type operator : can only occur in a definition's type
|
The has-type operator : can only occur in a definition's type
|
||||||
signature, like
|
signature, like
|
||||||
|
|
||||||
increment : I64 -> I64
|
increment : I64 -> I64
|
||||||
increment = \x -> x + 1
|
increment = \x -> x + 1
|
||||||
"#
|
"#
|
||||||
|
@ -5759,19 +5758,19 @@ mod test_reporting {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── MISSING FINAL EXPRESSION ────────────────────────────────────────────────────
|
── MISSING FINAL EXPRESSION ────────────────────────────────────────────────────
|
||||||
|
|
||||||
I am partway through parsing a definition's final expression, but I
|
I am partway through parsing a definition's final expression, but I
|
||||||
got stuck here:
|
got stuck here:
|
||||||
|
|
||||||
1│ main = 5 -> 3
|
1│ main = 5 -> 3
|
||||||
^
|
^
|
||||||
|
|
||||||
This definition is missing a final expression. A nested definition
|
This definition is missing a final expression. A nested definition
|
||||||
must be followed by either another definition, or an expression
|
must be followed by either another definition, or an expression
|
||||||
|
|
||||||
x = 4
|
x = 4
|
||||||
y = 2
|
y = 2
|
||||||
|
|
||||||
x + y
|
x + y
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue