constrain_pattern takes an expected index

This commit is contained in:
Ayaz Hafiz 2022-11-07 17:05:05 -06:00
parent b85465d74d
commit 24b6d4a3a9
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
2 changed files with 34 additions and 34 deletions

View file

@ -76,7 +76,8 @@ fn constrain_untyped_args(
let pattern_type = Variable(*pattern_var);
let pattern_type_index = constraints.push_type(Variable(*pattern_var));
let pattern_expected = PExpected::NoExpectation(pattern_type_index);
let pattern_expected =
constraints.push_pat_expected_type(PExpected::NoExpectation(pattern_type_index));
pattern_types.push(pattern_type);
@ -2004,8 +2005,10 @@ fn constrain_when_branch_help(
};
for (i, loc_pattern) in when_branch.patterns.iter().enumerate() {
let pattern_expected =
pattern_expected(HumanIndex::zero_based(i), loc_pattern.pattern.region);
let pattern_expected = constraints.push_pat_expected_type(pattern_expected(
HumanIndex::zero_based(i),
loc_pattern.pattern.region,
));
let mut partial_state = PatternState::default();
constrain_pattern(
@ -2255,7 +2258,7 @@ pub(crate) fn constrain_def_pattern(
loc_pattern: &Loc<Pattern>,
expr_type: TypeOrVar,
) -> PatternState {
let pattern_expected = PExpected::NoExpectation(expr_type);
let pattern_expected = constraints.push_pat_expected_type(PExpected::NoExpectation(expr_type));
let mut state = PatternState {
headers: VecMap::default(),
@ -2512,14 +2515,14 @@ fn constrain_typed_function_arguments(
if loc_pattern.value.surely_exhaustive() {
// OPT: we don't need to perform any type-level exhaustiveness checking.
// Check instead only that the pattern unifies with the annotation type.
let pattern_expected = PExpected::ForReason(
let pattern_expected = constraints.push_pat_expected_type(PExpected::ForReason(
PReason::TypedArg {
index: HumanIndex::zero_based(index),
opt_name: opt_label,
},
ann_index,
loc_pattern.region,
);
));
constrain_pattern(
constraints,
@ -2559,7 +2562,8 @@ fn constrain_typed_function_arguments(
{
// First, solve the type that the pattern is expecting to match in this
// position.
let pattern_expected = PExpected::NoExpectation(pattern_var_index);
let pattern_expected =
constraints.push_pat_expected_type(PExpected::NoExpectation(pattern_var_index));
constrain_pattern(
constraints,
env,
@ -2639,14 +2643,14 @@ fn constrain_typed_function_arguments_simple(
if loc_pattern.value.surely_exhaustive() {
// OPT: we don't need to perform any type-level exhaustiveness checking.
// Check instead only that the pattern unifies with the annotation type.
let pattern_expected = PExpected::ForReason(
let pattern_expected = constraints.push_pat_expected_type(PExpected::ForReason(
PReason::TypedArg {
index: HumanIndex::zero_based(index),
opt_name: Some(symbol),
},
ann_index,
loc_pattern.region,
);
));
constrain_pattern(
constraints,
@ -2686,7 +2690,8 @@ fn constrain_typed_function_arguments_simple(
{
// First, solve the type that the pattern is expecting to match in this
// position.
let pattern_expected = PExpected::NoExpectation(pattern_var_index);
let pattern_expected =
constraints.push_pat_expected_type(PExpected::NoExpectation(pattern_var_index));
constrain_pattern(
constraints,
env,

View file

@ -1,6 +1,6 @@
use crate::builtins;
use crate::expr::{constrain_expr, Env};
use roc_can::constraint::{Constraint, Constraints, TypeOrVar};
use roc_can::constraint::{Constraint, Constraints, PExpectedTypeIndex, TypeOrVar};
use roc_can::expected::{Expected, PExpected};
use roc_can::pattern::Pattern::{self, *};
use roc_can::pattern::{DestructType, ListPatterns, RecordDestruct};
@ -187,7 +187,7 @@ pub fn constrain_pattern(
env: &mut Env,
pattern: &Pattern,
region: Region,
expected: PExpected<TypeOrVar>,
expected: PExpectedTypeIndex,
state: &mut PatternState,
) {
match pattern {
@ -198,12 +198,11 @@ pub fn constrain_pattern(
// A -> ""
// _ -> ""
// so, we know that "x" (in this case, a tag union) must be open.
if could_be_a_tag_union(constraints, *expected.get_type_ref()) {
let type_index = expected.get_type();
let expected_type = *constraints.pattern_expectations[expected.index()].get_type_ref();
if could_be_a_tag_union(constraints, expected_type) {
state
.delayed_is_open_constraints
.push(constraints.is_open_type(type_index));
.push(constraints.is_open_type(expected_type));
}
}
UnsupportedPattern(_) | MalformedPattern(_, _) | OpaqueNotInScope(..) => {
@ -211,6 +210,7 @@ pub fn constrain_pattern(
}
Identifier(symbol) | Shadowed(_, _, symbol) => {
let expected = &constraints.pattern_expectations[expected.index()];
let type_index = *expected.get_type_ref();
if could_be_a_tag_union(constraints, type_index) {
@ -232,6 +232,7 @@ pub fn constrain_pattern(
ident: symbol,
specializes: _,
} => {
let expected = &constraints.pattern_expectations[expected.index()];
let type_index = *expected.get_type_ref();
if could_be_a_tag_union(constraints, type_index) {
@ -261,8 +262,6 @@ pub fn constrain_pattern(
);
let num_type = constraints.push_type(num_type);
let expected = constraints.push_pat_expected_type(expected);
state.constraints.push(constraints.equal_pattern_types(
num_type,
expected,
@ -295,7 +294,6 @@ pub fn constrain_pattern(
});
// Also constrain the pattern against the num var, again to reuse aliases if they're present.
let expected = constraints.push_pat_expected_type(expected);
state.constraints.push(constraints.equal_pattern_types(
num_type,
expected,
@ -329,7 +327,6 @@ pub fn constrain_pattern(
});
// Also constrain the pattern against the num var, again to reuse aliases if they're present.
let expected = constraints.push_pat_expected_type(expected);
state.constraints.push(constraints.equal_pattern_types(
num_type_index,
expected,
@ -340,7 +337,6 @@ pub fn constrain_pattern(
StrLiteral(_) => {
let str_type = constraints.push_type(builtins::str_type());
let expected = constraints.push_pat_expected_type(expected);
state.constraints.push(constraints.equal_pattern_types(
str_type,
expected,
@ -379,7 +375,6 @@ pub fn constrain_pattern(
});
// Also constrain the pattern against the num var, again to reuse aliases if they're present.
let expected = constraints.push_pat_expected_type(expected);
state.constraints.push(constraints.equal_pattern_types(
num_type_index,
expected,
@ -412,7 +407,8 @@ pub fn constrain_pattern(
{
let pat_type = Type::Variable(*var);
let pat_type_index = constraints.push_type(pat_type.clone());
let expected = PExpected::NoExpectation(pat_type_index);
let expected =
constraints.push_pat_expected_type(PExpected::NoExpectation(pat_type_index));
if !state.headers.contains_key(symbol) {
state
@ -510,8 +506,6 @@ pub fn constrain_pattern(
region,
);
let expected = constraints.push_pat_expected_type(expected);
let record_con = constraints.pattern_presence(
whole_var_index,
expected,
@ -535,8 +529,11 @@ pub fn constrain_pattern(
let elem_var_index = constraints.push_type(Type::Variable(*elem_var));
for loc_pat in patterns.iter() {
let expected =
PExpected::ForReason(PReason::ListElem, elem_var_index, loc_pat.region);
let expected = constraints.push_pat_expected_type(PExpected::ForReason(
PReason::ListElem,
elem_var_index,
loc_pat.region,
));
constrain_pattern(
constraints,
@ -556,7 +553,6 @@ pub fn constrain_pattern(
));
let store_solved_list = constraints.store(solved_list, *list_var, file!(), line!());
let expected = constraints.push_pat_expected_type(expected);
let expected_constraint = constraints.pattern_presence(
list_var_index,
expected,
@ -583,14 +579,14 @@ pub fn constrain_pattern(
let pattern_type = constraints.push_type(Type::Variable(*pattern_var));
let expected = PExpected::ForReason(
let expected = constraints.push_pat_expected_type(PExpected::ForReason(
PReason::TagArg {
tag_name: tag_name.clone(),
index: HumanIndex::zero_based(index),
},
pattern_type,
region,
);
));
constrain_pattern(
constraints,
env,
@ -602,7 +598,7 @@ pub fn constrain_pattern(
}
let pat_category = PatternCategory::Ctor(tag_name.clone());
let expected_type = *expected.get_type_ref();
let expected_type = *constraints.pattern_expectations[expected.index()].get_type_ref();
let whole_con = constraints.includes_tag(
expected_type,
@ -613,7 +609,6 @@ pub fn constrain_pattern(
);
let whole_type = constraints.push_type(Type::Variable(*whole_var));
let expected = constraints.push_pat_expected_type(expected);
let tag_con = constraints.pattern_presence(whole_type, expected, pat_category, region);
@ -652,7 +647,8 @@ pub fn constrain_pattern(
});
// First, add a constraint for the argument "who"
let arg_pattern_expected = PExpected::NoExpectation(arg_pattern_type_index);
let arg_pattern_expected = constraints
.push_pat_expected_type(PExpected::NoExpectation(arg_pattern_type_index));
constrain_pattern(
constraints,
env,
@ -700,7 +696,6 @@ pub fn constrain_pattern(
// Next, link `whole_var` (the type of "@Id who") to the expected type
let whole_type = constraints.push_type(Type::Variable(*whole_var));
let expected = constraints.push_pat_expected_type(expected);
let opaque_pattern_con = constraints.pattern_presence(
whole_type,
expected,