mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Simply constraint matching in solve
This commit is contained in:
parent
d5bd58c298
commit
409ced0ef2
1 changed files with 51 additions and 57 deletions
|
@ -629,69 +629,63 @@ fn solve(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Present(typ, constr) => {
|
Present(typ, PresenceConstraint::IsOpen) => {
|
||||||
let actual = type_to_var(subs, rank, pools, cached_aliases, typ);
|
let actual = type_to_var(subs, rank, pools, cached_aliases, typ);
|
||||||
match constr {
|
let mut new_desc = subs.get(actual);
|
||||||
PresenceConstraint::IsOpen => {
|
match new_desc.content {
|
||||||
let mut new_desc = subs.get(actual);
|
Content::Structure(FlatType::TagUnion(tags, _)) => {
|
||||||
match new_desc.content {
|
let new_ext = subs.fresh_unnamed_flex_var();
|
||||||
Content::Structure(FlatType::TagUnion(tags, _)) => {
|
let new_union = Content::Structure(FlatType::TagUnion(tags, new_ext));
|
||||||
let new_ext = subs.fresh_unnamed_flex_var();
|
new_desc.content = new_union;
|
||||||
let new_union = Content::Structure(FlatType::TagUnion(tags, new_ext));
|
subs.set(actual, new_desc);
|
||||||
new_desc.content = new_union;
|
state
|
||||||
subs.set(actual, new_desc);
|
|
||||||
state
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// Today, an "open" constraint doesn't affect any types
|
|
||||||
// other than tag unions. Recursive tag unions are constructed
|
|
||||||
// at a later time (during occurs checks after tag unions are
|
|
||||||
// resolved), so that's not handled here either.
|
|
||||||
// NB: Handle record types here if we add presence constraints
|
|
||||||
// to their type inference as well.
|
|
||||||
state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PresenceConstraint::IncludesTag(tag_name, tys) => {
|
_ => {
|
||||||
let tag_ty = Type::TagUnion(
|
// Today, an "open" constraint doesn't affect any types
|
||||||
vec![(tag_name.clone(), tys.clone())],
|
// other than tag unions. Recursive tag unions are constructed
|
||||||
Box::new(Type::EmptyTagUnion),
|
// at a later time (during occurs checks after tag unions are
|
||||||
|
// resolved), so that's not handled here either.
|
||||||
|
// NB: Handle record types here if we add presence constraints
|
||||||
|
// to their type inference as well.
|
||||||
|
state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Present(typ, PresenceConstraint::IncludesTag(tag_name, tys)) => {
|
||||||
|
let actual = type_to_var(subs, rank, pools, cached_aliases, typ);
|
||||||
|
let tag_ty = Type::TagUnion(
|
||||||
|
vec![(tag_name.clone(), tys.clone())],
|
||||||
|
Box::new(Type::EmptyTagUnion),
|
||||||
|
);
|
||||||
|
let includes = type_to_var(subs, rank, pools, cached_aliases, &tag_ty);
|
||||||
|
|
||||||
|
match unify(subs, actual, includes, Mode::Present) {
|
||||||
|
Success(vars) => {
|
||||||
|
introduce(subs, rank, pools, &vars);
|
||||||
|
|
||||||
|
state
|
||||||
|
}
|
||||||
|
Failure(vars, actual_type, expected_type) => {
|
||||||
|
introduce(subs, rank, pools, &vars);
|
||||||
|
|
||||||
|
// TODO: do we need a better error type here?
|
||||||
|
let problem = TypeError::BadExpr(
|
||||||
|
Region::zero(),
|
||||||
|
Category::When,
|
||||||
|
actual_type,
|
||||||
|
Expected::NoExpectation(expected_type),
|
||||||
);
|
);
|
||||||
let includes = type_to_var(subs, rank, pools, cached_aliases, &tag_ty);
|
|
||||||
|
|
||||||
match unify(subs, actual, includes, Mode::Present) {
|
problems.push(problem);
|
||||||
Success(vars) => {
|
|
||||||
introduce(subs, rank, pools, &vars);
|
|
||||||
|
|
||||||
state
|
state
|
||||||
}
|
|
||||||
Failure(vars, actual_type, expected_type) => {
|
|
||||||
introduce(subs, rank, pools, &vars);
|
|
||||||
|
|
||||||
// TODO: do we need a better error type here?
|
|
||||||
let problem = TypeError::BadExpr(
|
|
||||||
Region::zero(),
|
|
||||||
Category::When,
|
|
||||||
actual_type,
|
|
||||||
Expected::NoExpectation(expected_type),
|
|
||||||
);
|
|
||||||
|
|
||||||
problems.push(problem);
|
|
||||||
|
|
||||||
state
|
|
||||||
}
|
|
||||||
BadType(vars, problem) => {
|
|
||||||
introduce(subs, rank, pools, &vars);
|
|
||||||
|
|
||||||
problems.push(TypeError::BadType(problem));
|
|
||||||
|
|
||||||
state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PresenceConstraint::Pattern(_, _, _) => {
|
BadType(vars, problem) => {
|
||||||
unreachable!("Handled in a previous branch")
|
introduce(subs, rank, pools, &vars);
|
||||||
|
|
||||||
|
problems.push(TypeError::BadType(problem));
|
||||||
|
|
||||||
|
state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue