constraint default unique

This commit is contained in:
Folkert 2020-07-20 13:44:45 +02:00
parent 36574e6ff7
commit ae966c8933
3 changed files with 123 additions and 9 deletions

View file

@ -230,7 +230,6 @@ pub fn constrain_pattern(
RecordField::Required(pat_type) RecordField::Required(pat_type)
} }
DestructType::Optional(expr_var, loc_expr) => { DestructType::Optional(expr_var, loc_expr) => {
// Eq(Type, Expected<Type>, Category, Region),
let expr_expected = Expected::ForReason( let expr_expected = Expected::ForReason(
Reason::RecordDefaultField(label.clone()), Reason::RecordDefaultField(label.clone()),
pat_type.clone(), pat_type.clone(),

View file

@ -144,7 +144,10 @@ pub struct PatternState {
} }
fn constrain_pattern( fn constrain_pattern(
env: &Env,
var_store: &mut VarStore, var_store: &mut VarStore,
var_usage: &VarUsage,
applied_usage_constraint: &mut ImSet<Symbol>,
state: &mut PatternState, state: &mut PatternState,
pattern: &Located<Pattern>, pattern: &Located<Pattern>,
expected: PExpected<Type>, expected: PExpected<Type>,
@ -246,14 +249,46 @@ fn constrain_pattern(
PExpected::NoExpectation(pat_type.clone()), PExpected::NoExpectation(pat_type.clone()),
)); ));
state.vars.push(*guard_var); state.vars.push(*guard_var);
constrain_pattern(var_store, state, loc_guard, expected); constrain_pattern(
env,
var_store,
var_usage,
applied_usage_constraint,
state,
loc_guard,
expected,
);
RecordField::Required(pat_type) RecordField::Required(pat_type)
} }
DestructType::Optional(_expr_var, _loc_expr) => { DestructType::Optional(expr_var, loc_expr) => {
todo!("Add a constraint for the default value."); let expr_expected = Expected::ForReason(
Reason::RecordDefaultField(label.clone()),
pat_type.clone(),
loc_expr.region,
);
// RecordField::Optional(pat_type) state.constraints.push(Constraint::Eq(
Type::Variable(*expr_var),
expr_expected.clone(),
Category::DefaultValue(label.clone()),
region,
));
state.vars.push(*expr_var);
let expr_con = constrain_expr(
env,
var_store,
var_usage,
applied_usage_constraint,
loc_expr.region,
&loc_expr.value,
expr_expected,
);
state.constraints.push(expr_con);
RecordField::Optional(pat_type)
} }
DestructType::Required => { DestructType::Required => {
// No extra constraints necessary. // No extra constraints necessary.
@ -317,7 +352,15 @@ fn constrain_pattern(
argument_types.push(pattern_type.clone()); argument_types.push(pattern_type.clone());
let expected = PExpected::NoExpectation(pattern_type); let expected = PExpected::NoExpectation(pattern_type);
constrain_pattern(var_store, state, loc_pattern, expected); constrain_pattern(
env,
var_store,
var_usage,
applied_usage_constraint,
state,
loc_pattern,
expected,
);
} }
let tag_union_uniq_type = { let tag_union_uniq_type = {
@ -673,7 +716,15 @@ pub fn constrain_expr(
pattern_types.push(pattern_type); pattern_types.push(pattern_type);
constrain_pattern(var_store, &mut state, loc_pattern, pattern_expected); constrain_pattern(
env,
var_store,
var_usage,
applied_usage_constraint,
&mut state,
loc_pattern,
pattern_expected,
);
vars.push(*pattern_var); vars.push(*pattern_var);
} }
@ -1690,7 +1741,10 @@ fn constrain_when_branch(
for loc_pattern in &when_branch.patterns { for loc_pattern in &when_branch.patterns {
// mutates the state, so return value is not used // mutates the state, so return value is not used
constrain_pattern( constrain_pattern(
env,
var_store, var_store,
var_usage,
applied_usage_constraint,
&mut state, &mut state,
&loc_pattern, &loc_pattern,
pattern_expected.clone(), pattern_expected.clone(),
@ -1743,7 +1797,10 @@ fn constrain_when_branch(
} }
fn constrain_def_pattern( fn constrain_def_pattern(
env: &Env,
var_store: &mut VarStore, var_store: &mut VarStore,
var_usage: &VarUsage,
applied_usage_constraint: &mut ImSet<Symbol>,
loc_pattern: &Located<Pattern>, loc_pattern: &Located<Pattern>,
expr_type: Type, expr_type: Type,
) -> PatternState { ) -> PatternState {
@ -1757,7 +1814,15 @@ fn constrain_def_pattern(
constraints: Vec::with_capacity(1), constraints: Vec::with_capacity(1),
}; };
constrain_pattern(var_store, &mut state, loc_pattern, pattern_expected); constrain_pattern(
env,
var_store,
var_usage,
applied_usage_constraint,
&mut state,
loc_pattern,
pattern_expected,
);
state state
} }
@ -2042,7 +2107,14 @@ fn constrain_def(
let expr_var = def.expr_var; let expr_var = def.expr_var;
let expr_type = Type::Variable(expr_var); let expr_type = Type::Variable(expr_var);
let mut pattern_state = constrain_def_pattern(var_store, &def.loc_pattern, expr_type.clone()); let mut pattern_state = constrain_def_pattern(
env,
var_store,
var_usage,
applied_usage_constraint,
&def.loc_pattern,
expr_type.clone(),
);
pattern_state.vars.push(expr_var); pattern_state.vars.push(expr_var);
@ -2236,7 +2308,10 @@ pub fn rec_defs_help(
pattern_state.vars.push(expr_var); pattern_state.vars.push(expr_var);
constrain_pattern( constrain_pattern(
env,
var_store, var_store,
var_usage,
applied_usage_constraint,
&mut pattern_state, &mut pattern_state,
&def.loc_pattern, &def.loc_pattern,
pattern_expected, pattern_expected,

View file

@ -3075,4 +3075,44 @@ mod solve_uniq_expr {
"Attr * { a : (Attr * { x : (Attr * (Num (Attr * a))), y : (Attr * Float), z : (Attr * c) }), b : (Attr * { blah : (Attr * Str), x : (Attr * (Num (Attr * a))), y : (Attr * Float), z : (Attr * c) }) }" "Attr * { a : (Attr * { x : (Attr * (Num (Attr * a))), y : (Attr * Float), z : (Attr * c) }), b : (Attr * { blah : (Attr * Str), x : (Attr * (Num (Attr * a))), y : (Attr * Float), z : (Attr * c) }) }"
); );
} }
#[test]
fn optional_field_function() {
infer_eq(
indoc!(
r#"
\{ x, y ? 0 } -> x + y
"#
),
"Attr * (Attr (* | b | c) { x : (Attr b (Num (Attr b a))), y ? (Attr c (Num (Attr c a))) }* -> Attr d (Num (Attr d a)))"
);
}
#[test]
fn optional_field_let() {
infer_eq(
indoc!(
r#"
{ x, y ? 0 } = { x: 32 }
x + y
"#
),
"Attr a (Num (Attr a *))",
);
}
#[test]
fn optional_field_when() {
infer_eq(
indoc!(
r#"
\r ->
when r is
{ x, y ? 0 } -> x + y
"#
),
"Attr * (Attr (* | b | c) { x : (Attr b (Num (Attr b a))), y ? (Attr c (Num (Attr c a))) }* -> Attr d (Num (Attr d a)))"
);
}
} }