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

View file

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