diff --git a/src/constrain.rs b/src/constrain.rs index bd5ea201cc..6d048d0642 100644 --- a/src/constrain.rs +++ b/src/constrain.rs @@ -1,6 +1,6 @@ use canonicalize::{Pattern, Procedure, Symbol}; use canonicalize::Expr::{self, *}; -use collections::{ImMap, MutMap}; +use collections::ImMap; use region::{Located, Region}; use subs::{Variable, Subs}; use types::{Expected, Expected::*, LetConstraint, Reason}; @@ -117,10 +117,10 @@ pub fn constrain_def( loc_expr: Located, bound_vars: BoundTypeVars, subs: &mut Subs, - body_constraint: Constraint + ret_constraint: Constraint ) -> Constraint { let mut state = PatternState { - headers: MutMap::default(), + assignment_types: ImMap::default(), vars: Vec::with_capacity(1), reversed_constraints: Vec::with_capacity(1) }; @@ -131,16 +131,16 @@ pub fn constrain_def( Let(Box::new(LetConstraint { rigid_vars: Vec::new(), flex_vars: args.vars, - header_constraint: + assignments_constraint: Let(Box::new(LetConstraint { rigid_vars: Vec::new(), flex_vars: state.vars, - header: state.headers, - header_constraint: And(state.reversed_constraints), - body_constraint: constrain(bound_vars, subs, loc_expr, NoExpectation(args.ret_type)) + assignment_types: state.assignment_types, + assignments_constraint: And(state.reversed_constraints), + ret_constraint: constrain(bound_vars, subs, loc_expr, NoExpectation(args.ret_type)) })), - body_constraint, - header: panic!("TODO Map.singleton name (A.At region tipe)"), + ret_constraint, + assignment_types: panic!("TODO Map.singleton name (A.At region tipe)"), })) } @@ -152,17 +152,17 @@ pub fn constrain_procedure( expected: Expected ) -> Constraint { let mut state = PatternState { - headers: MutMap::default(), + assignment_types: ImMap::default(), vars: Vec::with_capacity(proc.args.len()), reversed_constraints: Vec::with_capacity(1) }; let args = constrain_args(proc.args.into_iter(), subs, &mut state); let body_type = NoExpectation(args.ret_type); - let body_constraint = constrain(bound_vars, subs, proc.body, body_type); + let ret_constraint = constrain(bound_vars, subs, proc.body, body_type); state.reversed_constraints.reverse(); - let header_constraint = And(state.reversed_constraints); + let assignments_constraint = And(state.reversed_constraints); // panic!("TODO occurs check"); @@ -170,9 +170,9 @@ pub fn constrain_procedure( Let(Box::new(LetConstraint { rigid_vars: Vec::new(), flex_vars: state.vars, - header: state.headers, - header_constraint, - body_constraint + assignment_types: state.assignment_types, + assignments_constraint, + ret_constraint })), Eq(args.typ, expected, region) ]) @@ -215,13 +215,13 @@ where I: Iterator> } struct PatternState { - headers: MutMap>, + assignment_types: ImMap>, vars: Vec, reversed_constraints: Vec } -fn add_to_headers(region: Region, symbol: Symbol, expected: Expected, state: &mut PatternState) { - state.headers.insert(symbol, Located {region, value: expected.unwrap()}); +fn add_to_assignment_types(region: Region, symbol: Symbol, expected: Expected, state: &mut PatternState) { + state.assignment_types.insert(symbol, Located {region, value: expected.unwrap()}); } fn add_pattern(loc_pattern: Located, expected: Expected, state: &mut PatternState) { @@ -230,7 +230,7 @@ fn add_pattern(loc_pattern: Located, expected: Expected, state: & let region = loc_pattern.region; match loc_pattern.value { - Identifier(symbol) => add_to_headers(region, symbol, expected, state), + Identifier(symbol) => add_to_assignment_types(region, symbol, expected, state), Underscore => (), _ => panic!("TODO other patterns"), } diff --git a/src/infer.rs b/src/infer.rs index f321a42e12..935363d22f 100644 --- a/src/infer.rs +++ b/src/infer.rs @@ -9,11 +9,12 @@ use constrain::constrain; pub fn infer_expr(subs: &mut Subs, loc_expr: Located, procedures: MutMap) -> Content { let bound_vars = ImMap::default(); + let env = ImMap::default(); let variable = subs.mk_flex_var(); let expected = NoExpectation(Variable(variable)); let constraint = constrain(bound_vars, subs, loc_expr, expected); - solve(subs, constraint); + solve(&env, subs, constraint); subs.get(variable).content } diff --git a/src/solve.rs b/src/solve.rs index 07817939dc..2bf40c5f23 100644 --- a/src/solve.rs +++ b/src/solve.rs @@ -15,10 +15,11 @@ use subs::{Subs, Variable, Descriptor, Content, FlatType}; use collections::ImMap; +use canonicalize::Symbol; use types::Constraint::{self, *}; use types::Type::{self, *}; -type Env = ImMap; +type Env = ImMap; pub fn solve(env: &Env, subs: &mut Subs, constraint: Constraint) { println!("\nSolving:\n\n\t{:?}\n\n", constraint); @@ -37,48 +38,31 @@ pub fn solve(env: &Env, subs: &mut Subs, constraint: Constraint) { }, Let(box_let_constraint) => { let let_con = *box_let_constraint; - let no_rigid_vars = let_con.rigid_vars.is_empty(); match let_con.ret_constraint { - True if no_rigid_vars => { + True => { // If the return expression is guaranteed to solve, - // and there are no rigid vars to worry about, // solve the assignments themselves and move on. solve(env, subs, let_con.assignments_constraint) }, - body_con => { - if no_rigid_vars && let_con.flex_vars.is_empty() { - // Solve the assignments' constraints first. - solve(env, subs, let_con.assignments_constraint); + ret_con => { + // Solve the assignments' constraints first. + solve(env, subs, let_con.assignments_constraint); - // Add a variable for each assignment to the env. - let new_env = env.clone(); + // Add a variable for each assignment to the env. + let mut new_env = env.clone(); - for (name, loc_type) in let_con.assignment_types { - let var = type_to_variable(subs, loc_type.value); + for (name, loc_type) in let_con.assignment_types { + let var = type_to_variable(subs, loc_type.value); - new_env.insert(name, var); - } - - // Now solve the body, using the new env which includes - // the assignments' name-to-variable mappings. - solve(&new_env, subs, let_con.ret_constraint); - - // TODO do an occurs check for each of the assignments! - } else { - let vars = let_con.rigid_vars; - - vars.extend(let_con.flex_vars); - - // Add a variable for each assignment to the env. - let new_env = env.clone(); - - for (name, loc_type) in let_con.assignment_types { - let var = type_to_variable(subs, loc_type.value); - - new_env.insert(name, var); - } + new_env.insert(name, var); } + + // Now solve the body, using the new env which includes + // the assignments' name-to-variable mappings. + solve(&new_env, subs, ret_con); + + // TODO do an occurs check for each of the assignments! } } }, diff --git a/src/types.rs b/src/types.rs index 5d0b43f164..92a3e8e8f3 100644 --- a/src/types.rs +++ b/src/types.rs @@ -2,6 +2,7 @@ use subs::Variable; use region::Region; use operator::Operator; use region::Located; +use canonicalize::Symbol; use collections::ImMap; type ModuleName = String; @@ -55,7 +56,7 @@ pub enum Constraint { pub struct LetConstraint { pub rigid_vars: Vec, pub flex_vars: Vec, - pub assignment_types: ImMap>, + pub assignment_types: ImMap>, pub assignments_constraint: Constraint, pub ret_constraint: Constraint, }