Infer multiple assignments

This commit is contained in:
Richard Feldman 2019-08-30 00:57:47 -04:00
parent eae1f564db
commit 2e12651858
3 changed files with 31 additions and 11 deletions

View file

@ -53,15 +53,23 @@ pub fn constrain(
Assign(assignments, ret_expr) => {
let ret_con = constrain(bound_vars, subs, *ret_expr, expected);
if assignments.len() > 1 {
panic!("TODO can't handle multiple assignments yet");
}
if assignments.len() == 1 {
// Don't bother allocating a Vec of them if there's only one!
let (loc_pattern, loc_expr) = assignments.into_iter().next().unwrap();
constrain_def(loc_pattern, loc_expr, bound_vars, subs, ret_con)
} else {
let mut constraints = Vec::with_capacity(assignments.len());
for (loc_pattern, loc_expr) in assignments {
return constrain_def(loc_pattern, loc_expr, bound_vars, subs, ret_con);
let constraint =
constrain_def(loc_pattern, loc_expr, bound_vars, subs, ret_con.clone());
constraints.push(constraint);
}
unreachable!();
And(constraints)
}
}
_ => { panic!("TODO constraints for {:?}", loc_expr.value) }
}

View file

@ -19,7 +19,7 @@ pub enum Type {
Erroneous(Problem),
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Expected<T> {
NoExpectation(T),
ForReason(Reason, T, Region),
@ -34,7 +34,7 @@ impl<T> Expected<T> {
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Reason {
OperatorLeftArg(Operator),
OperatorRightArg(Operator),
@ -43,7 +43,7 @@ pub enum Reason {
ElemInList,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Constraint {
Eq(Type, Expected<Type>, Region),
Lookup(Symbol, Expected<Type>, Region),
@ -52,7 +52,7 @@ pub enum Constraint {
And(Vec<Constraint>)
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct LetConstraint {
pub rigid_vars: Vec<Variable>,
pub flex_vars: Vec<Variable>,

View file

@ -357,7 +357,19 @@ mod test_infer {
);
}
#[test]
fn assign_multiple() {
infer_eq(
indoc!(r#"
a = \_ _ _ -> "test!"
b = a
b
"#),
"*, *, * -> String.String"
);
}
// #[test]
// fn int_thunk() {