mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Merge branch 'trunk' into fix-uniq-principality
This commit is contained in:
commit
e019a4b662
8 changed files with 82 additions and 28 deletions
|
@ -73,8 +73,9 @@ pub fn fmt_expr<'a>(
|
|||
}
|
||||
buf.push_str("\"\"\"");
|
||||
}
|
||||
Int(string) => buf.push_str(string),
|
||||
Float(string) => buf.push_str(string),
|
||||
Int(string) | Float(string) | GlobalTag(string) | PrivateTag(string) => {
|
||||
buf.push_str(string)
|
||||
}
|
||||
NonBase10Int {
|
||||
base,
|
||||
string,
|
||||
|
@ -480,7 +481,7 @@ pub fn fmt_closure<'a>(
|
|||
any_args_printed = true;
|
||||
}
|
||||
|
||||
fmt_pattern(buf, &loc_pattern.value, indent, true);
|
||||
fmt_pattern(buf, &loc_pattern.value, indent, false);
|
||||
}
|
||||
|
||||
if !arguments_are_multiline {
|
||||
|
|
|
@ -430,7 +430,7 @@ pub fn loc_parenthetical_def<'a>(min_indent: u16) -> impl Parser<'a, Located<Exp
|
|||
space0_after(
|
||||
between!(
|
||||
char('('),
|
||||
space0_around(loc!(pattern(min_indent)), min_indent),
|
||||
space0_around(loc_pattern(min_indent), min_indent),
|
||||
char(')')
|
||||
),
|
||||
min_indent,
|
||||
|
@ -752,23 +752,32 @@ fn parse_closure_param<'a>(
|
|||
// e.g. \User.UserId userId -> ...
|
||||
between!(
|
||||
char('('),
|
||||
space0_around(loc!(pattern(min_indent)), min_indent),
|
||||
space0_around(loc_pattern(min_indent), min_indent),
|
||||
char(')')
|
||||
),
|
||||
// The least common, but still allowed, e.g. \Foo -> ...
|
||||
loc!(tag_pattern())
|
||||
loc_tag_pattern(min_indent)
|
||||
)
|
||||
.parse(arena, state)
|
||||
}
|
||||
|
||||
fn pattern<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>> {
|
||||
fn loc_pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>> {
|
||||
one_of!(
|
||||
underscore_pattern(),
|
||||
tag_pattern(),
|
||||
ident_pattern(),
|
||||
record_destructure(min_indent),
|
||||
string_pattern(),
|
||||
int_pattern()
|
||||
loc_parenthetical_pattern(min_indent),
|
||||
loc!(underscore_pattern()),
|
||||
loc_tag_pattern(min_indent),
|
||||
loc!(ident_pattern()),
|
||||
loc!(record_destructure(min_indent)),
|
||||
loc!(string_pattern()),
|
||||
loc!(int_pattern())
|
||||
)
|
||||
}
|
||||
|
||||
fn loc_parenthetical_pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>> {
|
||||
between!(
|
||||
char('('),
|
||||
move |arena, state| loc_pattern(min_indent).parse(arena, state),
|
||||
char(')')
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -796,7 +805,7 @@ fn underscore_pattern<'a>() -> impl Parser<'a, Pattern<'a>> {
|
|||
|
||||
fn record_destructure<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>> {
|
||||
then(
|
||||
record_without_update!(loc!(pattern(min_indent)), min_indent),
|
||||
record_without_update!(loc_pattern(min_indent), min_indent),
|
||||
move |arena, state, assigned_fields| {
|
||||
let mut patterns = Vec::with_capacity_in(assigned_fields.len(), arena);
|
||||
for assigned_field in assigned_fields {
|
||||
|
@ -815,10 +824,29 @@ fn record_destructure<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>> {
|
|||
)
|
||||
}
|
||||
|
||||
fn tag_pattern<'a>() -> impl Parser<'a, Pattern<'a>> {
|
||||
one_of!(
|
||||
map!(private_tag(), Pattern::PrivateTag),
|
||||
map!(global_tag(), Pattern::GlobalTag)
|
||||
fn loc_tag_pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>> {
|
||||
map_with_arena!(
|
||||
and!(
|
||||
loc!(one_of!(
|
||||
map!(private_tag(), Pattern::PrivateTag),
|
||||
map!(global_tag(), Pattern::GlobalTag)
|
||||
)),
|
||||
// This can optionally be an applied pattern, e.g. (Foo bar) instead of (Foo)
|
||||
zero_or_more!(space1_before(loc_pattern(min_indent), min_indent))
|
||||
),
|
||||
|arena: &'a Bump,
|
||||
(loc_tag, loc_args): (Located<Pattern<'a>>, Vec<'a, Located<Pattern<'a>>>)| {
|
||||
if loc_args.is_empty() {
|
||||
loc_tag
|
||||
} else {
|
||||
// TODO FIME this region doesn't cover the tag's
|
||||
// arguments; need to add them to the region!
|
||||
let region = loc_tag.region;
|
||||
let value = Pattern::Apply(&*arena.alloc(loc_tag), loc_args.into_bump_slice());
|
||||
|
||||
Located { region, value }
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -868,7 +896,7 @@ pub fn case_branches<'a>(
|
|||
// 2. Parse the other branches. Their indentation levels must be == the first branch's.
|
||||
|
||||
let (mut loc_first_pattern, state) =
|
||||
space1_before(loc!(pattern(min_indent)), min_indent).parse(arena, state)?;
|
||||
space1_before(loc_pattern(min_indent), min_indent).parse(arena, state)?;
|
||||
let original_indent = state.indent_col;
|
||||
let indented_more = original_indent + 1;
|
||||
let (spaces_before_arrow, state) = space0(min_indent).parse(arena, state)?;
|
||||
|
@ -898,7 +926,7 @@ pub fn case_branches<'a>(
|
|||
|
||||
let branch_parser = and!(
|
||||
then(
|
||||
space1_around(loc!(pattern(min_indent)), min_indent),
|
||||
space1_around(loc_pattern(min_indent), min_indent),
|
||||
move |_arena, state, loc_pattern| {
|
||||
if state.indent_col == original_indent {
|
||||
Ok((loc_pattern, state))
|
||||
|
|
|
@ -208,6 +208,13 @@ fn write_flat_type(flat_type: FlatType, subs: &mut Subs, buf: &mut String, paren
|
|||
EmptyTagUnion => buf.push_str(EMPTY_TAG_UNION),
|
||||
Func(args, ret) => write_fn(args, ret, subs, buf, parens),
|
||||
Record(fields, ext_var) => {
|
||||
use crate::unify::gather_fields;
|
||||
use crate::unify::RecordStructure;
|
||||
|
||||
// If the `ext` has concrete fields (e.g. { foo : Int}{ bar : Bool }), merge them
|
||||
let RecordStructure { fields, ext } = gather_fields(subs, fields, ext_var);
|
||||
let ext_var = ext;
|
||||
|
||||
if fields.is_empty() {
|
||||
buf.push_str(EMPTY_RECORD)
|
||||
} else {
|
||||
|
|
|
@ -16,9 +16,9 @@ struct Context {
|
|||
second_desc: Descriptor,
|
||||
}
|
||||
|
||||
struct RecordStructure {
|
||||
fields: ImMap<RecordFieldLabel, Variable>,
|
||||
ext: Variable,
|
||||
pub struct RecordStructure {
|
||||
pub fields: ImMap<RecordFieldLabel, Variable>,
|
||||
pub ext: Variable,
|
||||
}
|
||||
|
||||
struct TagUnionStructure {
|
||||
|
@ -519,7 +519,7 @@ fn unify_flex(
|
|||
}
|
||||
}
|
||||
|
||||
fn gather_fields(
|
||||
pub fn gather_fields(
|
||||
subs: &mut Subs,
|
||||
fields: ImMap<RecordFieldLabel, Variable>,
|
||||
var: Variable,
|
||||
|
|
|
@ -241,7 +241,7 @@ mod test_format {
|
|||
expr_formats_same(indoc!(
|
||||
r#"
|
||||
"""
|
||||
|
||||
|
||||
"" \""" ""\"
|
||||
|
||||
"""
|
||||
|
@ -294,6 +294,24 @@ mod test_format {
|
|||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn destructure_tag_closure() {
|
||||
expr_formats_same(indoc!(
|
||||
r#"
|
||||
\Foo a -> Foo a
|
||||
"#
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn destructure_nested_tag_closure() {
|
||||
expr_formats_same(indoc!(
|
||||
r#"
|
||||
\Foo (Bar a) -> Foo (Bar a)
|
||||
"#
|
||||
));
|
||||
}
|
||||
|
||||
// DEFS
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1005,7 +1005,7 @@ mod test_infer {
|
|||
{ user & year: "foo" }
|
||||
"#
|
||||
),
|
||||
"{ year : Str }{ name : Str }",
|
||||
"{ name : Str, year : Str }",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -641,7 +641,7 @@ mod test_parse {
|
|||
assert_eq!(Ok(expected), actual);
|
||||
}
|
||||
|
||||
// VARIANT
|
||||
// TAG
|
||||
|
||||
#[test]
|
||||
fn basic_global_tag() {
|
||||
|
|
|
@ -899,7 +899,7 @@ mod test_infer_uniq {
|
|||
{ user & year: "foo" }
|
||||
"#
|
||||
),
|
||||
"Attr.Attr * { year : (Attr.Attr * Str) }{ name : (Attr.Attr * Str) }",
|
||||
"Attr.Attr * { name : (Attr.Attr * Str), year : (Attr.Attr * Str) }",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue