mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Restore some stuff to how it was before
This commit is contained in:
parent
695fb30021
commit
65f384cb6a
2 changed files with 32 additions and 39 deletions
16
src/solve.rs
16
src/solve.rs
|
@ -4,9 +4,9 @@ use subs::{Content, Descriptor, FlatType, Subs, Variable};
|
||||||
use types::Constraint::{self, *};
|
use types::Constraint::{self, *};
|
||||||
use types::Type::{self, *};
|
use types::Type::{self, *};
|
||||||
|
|
||||||
type Env<'a> = ImMap<Symbol, Variable>;
|
type Env = ImMap<Symbol, Variable>;
|
||||||
|
|
||||||
pub fn solve<'a>(env: &Env<'a>, subs: &mut Subs, constraint: &Constraint) {
|
pub fn solve(env: &Env, subs: &mut Subs, constraint: &Constraint) {
|
||||||
match constraint {
|
match constraint {
|
||||||
True => (),
|
True => (),
|
||||||
Eq(typ, expected_type, _region) => {
|
Eq(typ, expected_type, _region) => {
|
||||||
|
@ -26,12 +26,6 @@ pub fn solve<'a>(env: &Env<'a>, subs: &mut Subs, constraint: &Constraint) {
|
||||||
|
|
||||||
subs.union(actual, expected);
|
subs.union(actual, expected);
|
||||||
}
|
}
|
||||||
And(sub_constraints) => {
|
|
||||||
// TODO drop And - we shouldn't need it anymore
|
|
||||||
for sub_constraint in sub_constraints.iter() {
|
|
||||||
solve(env, subs, sub_constraint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Let(let_con) => {
|
Let(let_con) => {
|
||||||
match let_con.ret_constraint {
|
match let_con.ret_constraint {
|
||||||
True => {
|
True => {
|
||||||
|
@ -66,6 +60,12 @@ pub fn solve<'a>(env: &Env<'a>, subs: &mut Subs, constraint: &Constraint) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
And(sub_constraints) => {
|
||||||
|
// TODO drop And - we shouldn't need it anymore
|
||||||
|
for sub_constraint in sub_constraints.iter() {
|
||||||
|
solve(env, subs, sub_constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
45
src/unify.rs
45
src/unify.rs
|
@ -3,24 +3,20 @@ use subs::{Descriptor, FlatType, Subs, Variable};
|
||||||
use types::Problem;
|
use types::Problem;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn unify_vars<'a>(subs: &'a mut Subs, left_key: Variable, right_key: Variable) -> Descriptor {
|
pub fn unify_vars(subs: &mut Subs, left_key: Variable, right_key: Variable) -> Descriptor {
|
||||||
let right = subs.get(right_key);
|
let right = subs.get(right_key);
|
||||||
|
|
||||||
unify_var_val(subs, left_key, &right)
|
unify_var_val(subs, left_key, &right)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn unify_var_val<'a>(
|
pub fn unify_var_val(subs: &mut Subs, left_key: Variable, right: &Descriptor) -> Descriptor {
|
||||||
subs: &'a mut Subs,
|
|
||||||
left_key: Variable,
|
|
||||||
right: &'a Descriptor,
|
|
||||||
) -> Descriptor {
|
|
||||||
let left = subs.get(left_key);
|
let left = subs.get(left_key);
|
||||||
|
|
||||||
unify(subs, &left, right)
|
unify(subs, &left, right)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unify<'a>(subs: &'a mut Subs, left: &'a Descriptor, right: &'a Descriptor) -> Descriptor {
|
pub fn unify(subs: &mut Subs, left: &Descriptor, right: &Descriptor) -> Descriptor {
|
||||||
let answer = match left.content {
|
let answer = match left.content {
|
||||||
FlexVar(ref opt_name) => unify_flex(opt_name, &right.content),
|
FlexVar(ref opt_name) => unify_flex(opt_name, &right.content),
|
||||||
RigidVar(ref name) => unify_rigid(name, &right.content),
|
RigidVar(ref name) => unify_rigid(name, &right.content),
|
||||||
|
@ -31,15 +27,13 @@ pub fn unify<'a>(subs: &'a mut Subs, left: &'a Descriptor, right: &'a Descriptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// println!("\nUnifying:\n\n\t{:?}\n\n\t{:?}\n\n\t-----\n\n\t{:?}\n\n", left.content, right.content, answer.content);
|
||||||
|
|
||||||
answer
|
answer
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn unify_structure<'a>(
|
fn unify_structure(subs: &mut Subs, flat_type: &FlatType, other: &Content) -> Descriptor {
|
||||||
subs: &'a mut Subs,
|
|
||||||
flat_type: &'a FlatType,
|
|
||||||
other: &'a Content,
|
|
||||||
) -> Descriptor {
|
|
||||||
match other {
|
match other {
|
||||||
FlexVar(_) => {
|
FlexVar(_) => {
|
||||||
// If the other is flex, Structure wins!
|
// If the other is flex, Structure wins!
|
||||||
|
@ -61,7 +55,7 @@ fn unify_structure<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn unify_flat_type<'a>(subs: &'a mut Subs, left: &'a FlatType, right: &'a FlatType) -> Descriptor {
|
fn unify_flat_type(subs: &mut Subs, left: &FlatType, right: &FlatType) -> Descriptor {
|
||||||
use subs::FlatType::*;
|
use subs::FlatType::*;
|
||||||
|
|
||||||
match (left, right) {
|
match (left, right) {
|
||||||
|
@ -112,13 +106,13 @@ fn unify_flat_type<'a>(subs: &'a mut Subs, left: &'a FlatType, right: &'a FlatTy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unify_args<'a, I>(subs: &'a mut Subs, left_iter: I, right_iter: I) -> Vec<Variable>
|
fn unify_args<'a, I>(subs: &mut Subs, left_iter: I, right_iter: I) -> Vec<Variable>
|
||||||
where
|
where
|
||||||
I: Iterator<Item = &'a Variable>,
|
I: Iterator<Item = &'a Variable>,
|
||||||
{
|
{
|
||||||
let mut answer = Vec::new();
|
left_iter
|
||||||
|
.zip(right_iter)
|
||||||
for (l_var, r_var) in left_iter.zip(right_iter) {
|
.map(|(l_var, r_var)| {
|
||||||
// Look up the descriptors we have for these variables, and unify them.
|
// Look up the descriptors we have for these variables, and unify them.
|
||||||
let descriptor = unify_vars(subs, l_var.clone(), r_var.clone());
|
let descriptor = unify_vars(subs, l_var.clone(), r_var.clone());
|
||||||
|
|
||||||
|
@ -126,13 +120,12 @@ where
|
||||||
subs.set(r_var.clone(), descriptor);
|
subs.set(r_var.clone(), descriptor);
|
||||||
subs.union(l_var.clone(), r_var.clone());
|
subs.union(l_var.clone(), r_var.clone());
|
||||||
|
|
||||||
answer.push(r_var.clone())
|
r_var.clone()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
answer
|
fn union_vars(subs: &mut Subs, l_var: Variable, r_var: Variable) -> Variable {
|
||||||
}
|
|
||||||
|
|
||||||
fn union_vars<'a>(subs: &'a mut Subs, l_var: Variable, r_var: Variable) -> Variable {
|
|
||||||
// Look up the descriptors we have for these variables, and unify them.
|
// Look up the descriptors we have for these variables, and unify them.
|
||||||
let descriptor = unify_vars(subs, l_var.clone(), r_var.clone());
|
let descriptor = unify_vars(subs, l_var.clone(), r_var.clone());
|
||||||
|
|
||||||
|
@ -144,11 +137,11 @@ fn union_vars<'a>(subs: &'a mut Subs, l_var: Variable, r_var: Variable) -> Varia
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn unify_rigid<'a>(name: &'a str, other: &'a Content) -> Descriptor {
|
fn unify_rigid(name: &String, other: &Content) -> Descriptor {
|
||||||
match other {
|
match other {
|
||||||
FlexVar(_) => {
|
FlexVar(_) => {
|
||||||
// If the other is flex, rigid wins!
|
// If the other is flex, rigid wins!
|
||||||
from_content(RigidVar(name.to_string()))
|
from_content(RigidVar(name.clone()))
|
||||||
}
|
}
|
||||||
RigidVar(_) | Structure(_) => {
|
RigidVar(_) | Structure(_) => {
|
||||||
// Type mismatch! Rigid can only unify with flex, even if the
|
// Type mismatch! Rigid can only unify with flex, even if the
|
||||||
|
@ -163,7 +156,7 @@ fn unify_rigid<'a>(name: &'a str, other: &'a Content) -> Descriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn unify_flex<'a>(opt_name: &'a Option<Box<str>>, other: &'a Content) -> Descriptor {
|
fn unify_flex(opt_name: &Option<Box<str>>, other: &Content) -> Descriptor {
|
||||||
match other {
|
match other {
|
||||||
FlexVar(None) => {
|
FlexVar(None) => {
|
||||||
// If both are flex, and only left has a name, keep the name around.
|
// If both are flex, and only left has a name, keep the name around.
|
||||||
|
@ -179,7 +172,7 @@ fn unify_flex<'a>(opt_name: &'a Option<Box<str>>, other: &'a Content) -> Descrip
|
||||||
|
|
||||||
/// TODO this was f/k/a merge() - got rid of the rank stuff...good idea? Bad?
|
/// TODO this was f/k/a merge() - got rid of the rank stuff...good idea? Bad?
|
||||||
/// TODO it used to be { rank: std::cmp::min(left_rank, right_rank), ... }
|
/// TODO it used to be { rank: std::cmp::min(left_rank, right_rank), ... }
|
||||||
fn from_content<'a>(content: Content) -> Descriptor {
|
fn from_content(content: Content) -> Descriptor {
|
||||||
Descriptor {
|
Descriptor {
|
||||||
content,
|
content,
|
||||||
rank: 0,
|
rank: 0,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue