Merge pull request #5440 from roc-lang/i5429

Implement openness constraints under records
This commit is contained in:
Ayaz 2023-05-24 17:03:34 -05:00 committed by GitHub
commit af3ee5e5f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 6 deletions

View file

@ -448,8 +448,9 @@ pub fn find_type_def_symbols(
As(actual, _, _) => {
stack.push(&actual.value);
}
Tuple { elems: _, ext: _ } => {
todo!("find_type_def_symbols: Tuple");
Tuple { elems, ext } => {
stack.extend(elems.iter().map(|t| &t.value));
stack.extend(ext.iter().map(|t| &t.value));
}
Record { fields, ext } => {
let mut inner_stack = Vec::with_capacity(fields.items.len());

View file

@ -512,13 +512,13 @@ pub fn constrain_pattern(
let expected =
constraints.push_pat_expected_type(PExpected::NoExpectation(pat_type_index));
let (guard_var, loc_guard) = typ;
let (guard_var, loc_pattern) = typ;
let elem_type = {
let guard_type = constraints.push_variable(*guard_var);
let expected_pat = constraints.push_pat_expected_type(PExpected::ForReason(
PReason::PatternGuard,
pat_type_index,
loc_guard.region,
loc_pattern.region,
));
state.constraints.push(constraints.pattern_presence(
@ -533,8 +533,8 @@ pub fn constrain_pattern(
types,
constraints,
env,
&loc_guard.value,
loc_guard.region,
&loc_pattern.value,
loc_pattern.region,
expected,
state,
);
@ -676,6 +676,17 @@ pub fn constrain_pattern(
RecordField::Optional(pat_type)
}
DestructType::Required => {
// Named destructures like
// {foo} -> ...
// are equivalent to wildcards on the type of `foo`, so if `foo` is a tag
// union, we must add a constraint to ensure that this destructure opens it
// up.
if could_be_a_tag_union(types, pat_type_index) {
state
.delayed_is_open_constraints
.push(constraints.is_open_type(pat_type_index));
}
// No extra constraints necessary.
RecordField::Demanded(pat_type)
}

View file

@ -0,0 +1,16 @@
# +opt infer:print_only_under_alias
app "test" provides [limitedKind] to "./platform"
Kind : [ A, B, C ]
Data : {kind: Kind}
limitedKind : Data -> Str
limitedKind = \data ->
when data is
# ^^^^ { kind : [A, B, C] }
{kind: A} -> "A is special"
{kind} -> when kind is
B -> "B"
C -> "C"
_ -> ""

View file

@ -0,0 +1,16 @@
# +opt infer:print_only_under_alias
app "test" provides [limitedKind] to "./platform"
Kind : [ A, B, C ]
Data : ({}, Kind)
limitedKind : Data -> Str
limitedKind = \data ->
when data is
# ^^^^ ( {}, [A, B, C] )*
({}, A) -> "A is special"
({}, kind) -> when kind is
B -> "B"
C -> "C"
_ -> ""