mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-02 19:32:17 +00:00
Merge pull request #5440 from roc-lang/i5429
Implement openness constraints under records
This commit is contained in:
commit
af3ee5e5f1
4 changed files with 50 additions and 6 deletions
|
@ -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());
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
_ -> ""
|
|
@ -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"
|
||||
_ -> ""
|
Loading…
Add table
Add a link
Reference in a new issue