mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
Parse destructured tag annotations as annotations rather than aliases
Closes #178
This commit is contained in:
parent
fe62e59e31
commit
b3ddfa7515
8 changed files with 192 additions and 34 deletions
|
@ -265,6 +265,17 @@ pub enum Def<'a> {
|
||||||
NotYetImplemented(&'static str),
|
NotYetImplemented(&'static str),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Def<'a> {
|
||||||
|
pub fn unroll_spaces_before(&self) -> (&'a [CommentOrNewline<'a>], &Def) {
|
||||||
|
let (spaces, def): (&'a [_], &Def) = match self {
|
||||||
|
Def::SpaceBefore(def, spaces) => (spaces, def),
|
||||||
|
def => (&[], def),
|
||||||
|
};
|
||||||
|
debug_assert!(!matches!(def, Def::SpaceBefore(_, _)));
|
||||||
|
(spaces, def)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
pub enum TypeAnnotation<'a> {
|
pub enum TypeAnnotation<'a> {
|
||||||
/// A function. The types of its arguments, then the type of its return value.
|
/// A function. The types of its arguments, then the type of its return value.
|
||||||
|
|
|
@ -571,27 +571,8 @@ fn append_body_definition<'a>(
|
||||||
|
|
||||||
if spaces.len() <= 1 {
|
if spaces.len() <= 1 {
|
||||||
let last = defs.pop();
|
let last = defs.pop();
|
||||||
match last {
|
match last.map(|d| d.value.unroll_spaces_before()) {
|
||||||
Some(Loc {
|
Some((before_ann_spaces, Def::Annotation(ann_pattern, ann_type))) => {
|
||||||
value: Def::Annotation(ann_pattern, ann_type),
|
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
return append_body_definition_help(
|
|
||||||
arena,
|
|
||||||
defs,
|
|
||||||
region,
|
|
||||||
&[],
|
|
||||||
spaces,
|
|
||||||
loc_pattern,
|
|
||||||
loc_def_body,
|
|
||||||
ann_pattern,
|
|
||||||
ann_type,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Some(Loc {
|
|
||||||
value: Def::SpaceBefore(Def::Annotation(ann_pattern, ann_type), before_ann_spaces),
|
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
return append_body_definition_help(
|
return append_body_definition_help(
|
||||||
arena,
|
arena,
|
||||||
defs,
|
defs,
|
||||||
|
@ -604,6 +585,37 @@ fn append_body_definition<'a>(
|
||||||
ann_type,
|
ann_type,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Some((
|
||||||
|
before_ann_spaces,
|
||||||
|
Def::Alias {
|
||||||
|
name,
|
||||||
|
vars,
|
||||||
|
ann: ann_type,
|
||||||
|
},
|
||||||
|
)) => {
|
||||||
|
// This is a case like
|
||||||
|
// UserId x : [ UserId Int ]
|
||||||
|
// UserId x = UserId 42
|
||||||
|
// We optimistically parsed the first line as an alias; we now turn it
|
||||||
|
// into an annotation.
|
||||||
|
let loc_name = arena.alloc(name.map(|x| Pattern::GlobalTag(x)));
|
||||||
|
let ann_pattern = Pattern::Apply(loc_name, vars);
|
||||||
|
let vars_region = Region::across_all(vars.iter().map(|v| &v.region));
|
||||||
|
let region_ann_pattern = Region::span_across(&loc_name.region, &vars_region);
|
||||||
|
let loc_ann_pattern = Loc::at(region_ann_pattern, ann_pattern);
|
||||||
|
|
||||||
|
return append_body_definition_help(
|
||||||
|
arena,
|
||||||
|
defs,
|
||||||
|
region,
|
||||||
|
before_ann_spaces,
|
||||||
|
spaces,
|
||||||
|
loc_pattern,
|
||||||
|
loc_def_body,
|
||||||
|
arena.alloc(loc_ann_pattern),
|
||||||
|
ann_type,
|
||||||
|
);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
defs.extend(last);
|
defs.extend(last);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
Defs(
|
||||||
|
[
|
||||||
|
|L 1-1, C 0-34| AnnotatedBody {
|
||||||
|
ann_pattern: |L 0-0, C 0-8| RecordDestructure(
|
||||||
|
[
|
||||||
|
|L 0-0, C 2-3| Identifier(
|
||||||
|
"x",
|
||||||
|
),
|
||||||
|
|L 0-0, C 5-7| Identifier(
|
||||||
|
"y",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ann_type: |L 0-0, C 11-14| Apply(
|
||||||
|
"",
|
||||||
|
"Foo",
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
comment: None,
|
||||||
|
body_pattern: |L 1-1, C 0-8| RecordDestructure(
|
||||||
|
[
|
||||||
|
|L 1-1, C 2-3| Identifier(
|
||||||
|
"x",
|
||||||
|
),
|
||||||
|
|L 1-1, C 5-6| Identifier(
|
||||||
|
"y",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body_expr: |L 1-1, C 11-34| Record(
|
||||||
|
[
|
||||||
|
|L 1-1, C 13-22| RequiredValue(
|
||||||
|
|L 1-1, C 13-14| "x",
|
||||||
|
[],
|
||||||
|
|L 1-1, C 17-22| Str(
|
||||||
|
PlainLine(
|
||||||
|
"foo",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|L 1-1, C 24-32| RequiredValue(
|
||||||
|
|L 1-1, C 24-25| "y",
|
||||||
|
[],
|
||||||
|
|L 1-1, C 28-32| Float(
|
||||||
|
"3.14",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|L 3-3, C 0-1| SpaceBefore(
|
||||||
|
Var {
|
||||||
|
module_name: "",
|
||||||
|
ident: "x",
|
||||||
|
},
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
|
@ -0,0 +1,4 @@
|
||||||
|
{ x, y } : Foo
|
||||||
|
{ x, y } = { x : "foo", y : 3.14 }
|
||||||
|
|
||||||
|
x
|
|
@ -0,0 +1,63 @@
|
||||||
|
Defs(
|
||||||
|
[
|
||||||
|
|L 1-1, C 0-20| AnnotatedBody {
|
||||||
|
ann_pattern: |L 0-0, C 0-8| Apply(
|
||||||
|
|L 0-0, C 0-6| GlobalTag(
|
||||||
|
"UserId",
|
||||||
|
),
|
||||||
|
[
|
||||||
|
|L 0-0, C 7-8| Identifier(
|
||||||
|
"x",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ann_type: |L 0-0, C 11-25| TagUnion {
|
||||||
|
ext: None,
|
||||||
|
tags: [
|
||||||
|
|L 0-0, C 13-23| Global {
|
||||||
|
name: |L 0-0, C 13-19| "UserId",
|
||||||
|
args: [
|
||||||
|
|L 0-0, C 20-23| Apply(
|
||||||
|
"",
|
||||||
|
"I64",
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
comment: None,
|
||||||
|
body_pattern: |L 1-1, C 0-8| Apply(
|
||||||
|
|L 1-1, C 0-6| GlobalTag(
|
||||||
|
"UserId",
|
||||||
|
),
|
||||||
|
[
|
||||||
|
|L 1-1, C 7-8| Identifier(
|
||||||
|
"x",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body_expr: |L 1-1, C 11-20| Apply(
|
||||||
|
|L 1-1, C 11-17| GlobalTag(
|
||||||
|
"UserId",
|
||||||
|
),
|
||||||
|
[
|
||||||
|
|L 1-1, C 18-20| Num(
|
||||||
|
"42",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
Space,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|L 3-3, C 0-1| SpaceBefore(
|
||||||
|
Var {
|
||||||
|
module_name: "",
|
||||||
|
ident: "x",
|
||||||
|
},
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
|
@ -0,0 +1,4 @@
|
||||||
|
UserId x : [ UserId I64 ]
|
||||||
|
UserId x = UserId 42
|
||||||
|
|
||||||
|
x
|
|
@ -110,6 +110,8 @@ mod test_parse {
|
||||||
fail/type_double_comma.expr,
|
fail/type_double_comma.expr,
|
||||||
pass/add_var_with_spaces.expr,
|
pass/add_var_with_spaces.expr,
|
||||||
pass/add_with_spaces.expr,
|
pass/add_with_spaces.expr,
|
||||||
|
pass/annotated_record_destructure.expr,
|
||||||
|
pass/annotated_tag_destructure.expr,
|
||||||
pass/apply_global_tag.expr,
|
pass/apply_global_tag.expr,
|
||||||
pass/apply_parenthetical_global_tag_args.expr,
|
pass/apply_parenthetical_global_tag_args.expr,
|
||||||
pass/apply_private_tag.expr,
|
pass/apply_private_tag.expr,
|
||||||
|
|
|
@ -2981,20 +2981,20 @@ mod solve_expr {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn let_tag_pattern_with_annotation() {
|
fn let_tag_pattern_with_annotation() {
|
||||||
// infer_eq_without_problem(
|
infer_eq_without_problem(
|
||||||
// indoc!(
|
indoc!(
|
||||||
// r#"
|
r#"
|
||||||
// UserId x : [ UserId I64 ]
|
UserId x : [ UserId I64 ]
|
||||||
// UserId x = UserId 42
|
UserId x = UserId 42
|
||||||
|
|
||||||
// x
|
x
|
||||||
// "#
|
"#
|
||||||
// ),
|
),
|
||||||
// "I64",
|
"I64",
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn typecheck_record_linked_list_map() {
|
fn typecheck_record_linked_list_map() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue