mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Support bound variables in multiple patterns
This commit is contained in:
parent
bf8fc0d0de
commit
ce8b50caea
3 changed files with 59 additions and 4 deletions
|
@ -1824,14 +1824,45 @@ fn constrain_when_branch_help(
|
||||||
for (i, loc_pattern) in when_branch.patterns.iter().enumerate() {
|
for (i, loc_pattern) in when_branch.patterns.iter().enumerate() {
|
||||||
let pattern_expected = pattern_expected(HumanIndex::zero_based(i), loc_pattern.region);
|
let pattern_expected = pattern_expected(HumanIndex::zero_based(i), loc_pattern.region);
|
||||||
|
|
||||||
|
let mut partial_state = PatternState::default();
|
||||||
constrain_pattern(
|
constrain_pattern(
|
||||||
constraints,
|
constraints,
|
||||||
env,
|
env,
|
||||||
&loc_pattern.value,
|
&loc_pattern.value,
|
||||||
loc_pattern.region,
|
loc_pattern.region,
|
||||||
pattern_expected,
|
pattern_expected,
|
||||||
&mut state,
|
&mut partial_state,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
state.vars.extend(partial_state.vars);
|
||||||
|
state.constraints.extend(partial_state.constraints);
|
||||||
|
state
|
||||||
|
.delayed_is_open_constraints
|
||||||
|
.extend(partial_state.delayed_is_open_constraints);
|
||||||
|
|
||||||
|
if i == 0 {
|
||||||
|
state.headers.extend(partial_state.headers);
|
||||||
|
} else {
|
||||||
|
debug_assert!(
|
||||||
|
state.headers.keys().all(|sym| partial_state.headers.contains_key(sym)) &&
|
||||||
|
partial_state.headers.keys().all(|sym| state.headers.contains_key(sym)),
|
||||||
|
"State and partial state headers differ in bound symbols, should have been caught in canonicalization");
|
||||||
|
|
||||||
|
// Make sure the bound variables in the patterns on the same branch agree in their types.
|
||||||
|
for (sym, typ1) in state.headers.iter() {
|
||||||
|
let typ2 = partial_state
|
||||||
|
.headers
|
||||||
|
.get(sym)
|
||||||
|
.expect("bound variable in branch not bound in pattern!");
|
||||||
|
|
||||||
|
state.constraints.push(constraints.equal_types(
|
||||||
|
typ1.value.clone(),
|
||||||
|
Expected::NoExpectation(typ2.value.clone()),
|
||||||
|
Category::When,
|
||||||
|
typ2.region,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (pattern_constraints, body_constraints) = if let Some(loc_guard) = &when_branch.guard {
|
let (pattern_constraints, body_constraints) = if let Some(loc_guard) = &when_branch.guard {
|
||||||
|
|
|
@ -7360,15 +7360,21 @@ mod solve_expr {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn shared_pattern_variable_in_when_branches() {
|
fn shared_pattern_variable_in_when_branches() {
|
||||||
infer_eq_without_problem(
|
infer_queries!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when A "" is
|
when A "" is
|
||||||
|
# ^^^^
|
||||||
A x | B x -> x
|
A x | B x -> x
|
||||||
C y | D y -> y
|
# ^ ^ ^
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"",
|
@r###"
|
||||||
|
A "" : [A Str, B Str]
|
||||||
|
x : Str
|
||||||
|
x : Str
|
||||||
|
x : Str
|
||||||
|
"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3641,3 +3641,21 @@ fn recursive_call_capturing_function() {
|
||||||
i64
|
i64
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
|
fn shared_pattern_variable_in_when_branches() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
f = \t ->
|
||||||
|
when t is
|
||||||
|
A x | B x -> x
|
||||||
|
|
||||||
|
{a: f (A 15u8), b: (B 31u8)}
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
(15u8, 31u8),
|
||||||
|
(u8, u8)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue