mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
constraint default unique
This commit is contained in:
parent
36574e6ff7
commit
ae966c8933
3 changed files with 123 additions and 9 deletions
|
@ -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(),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)))"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue