infer closure size!

This commit is contained in:
Folkert 2020-10-14 23:26:44 +02:00
parent 7f1dd80392
commit b440ab90f6
2 changed files with 58 additions and 17 deletions

View file

@ -129,6 +129,7 @@ impl Pools {
struct State {
env: Env,
mark: Mark,
vars_by_symbol: MutMap<Symbol, Variable>,
}
pub fn run(
@ -141,9 +142,10 @@ pub fn run(
let state = State {
env: env.clone(),
mark: Mark::NONE.next(),
vars_by_symbol: MutMap::default(),
};
let rank = Rank::toplevel();
let state = solve(
let mut state = solve(
env,
state,
rank,
@ -154,6 +156,10 @@ pub fn run(
constraint,
);
// by default, state.vars_by_symbol only gives back top-level symbols and their variable
// for closure size inference, we need all of the symbols, we do that here
state.env.vars_by_symbol.extend(state.vars_by_symbol);
(Solved(subs), state.env)
}
@ -168,9 +174,10 @@ pub fn run_in_place(
let state = State {
env: env.clone(),
mark: Mark::NONE.next(),
vars_by_symbol: MutMap::default(),
};
let rank = Rank::toplevel();
let state = solve(
let mut state = solve(
env,
state,
rank,
@ -181,13 +188,17 @@ pub fn run_in_place(
constraint,
);
// by default, state.vars_by_symbol only gives back top-level symbols and their variable
// for closure size inference, we need all of the symbols, we do that here
state.env.vars_by_symbol.extend(state.vars_by_symbol);
state.env
}
#[allow(clippy::too_many_arguments)]
fn solve(
env: &Env,
state: State,
mut state: State,
rank: Rank,
pools: &mut Pools,
problems: &mut Vec<TypeError>,
@ -197,12 +208,22 @@ fn solve(
) -> State {
match constraint {
// True => state,
True | SaveTheEnvironment => {
True => {
state
.vars_by_symbol
.extend(env.vars_by_symbol.iter().map(|(x, y)| (*x, *y)));
state
}
SaveTheEnvironment => {
// NOTE deviation: elm only copies the env into the state on SaveTheEnvironment
let mut copy = state;
copy.env = env.clone();
copy.vars_by_symbol
.extend(env.vars_by_symbol.iter().map(|(x, y)| (*x, *y)));
copy
}
Eq(typ, expectation, category, region) => {
@ -389,7 +410,7 @@ fn solve(
)
}
ret_con if let_con.rigid_vars.is_empty() && let_con.flex_vars.is_empty() => {
let state = solve(
let mut state = solve(
env,
state,
rank,
@ -422,6 +443,10 @@ fn solve(
}
}
state
.vars_by_symbol
.extend(new_env.vars_by_symbol.iter().map(|(x, y)| (*x, *y)));
let new_state = solve(
&new_env,
state,
@ -480,6 +505,10 @@ fn solve(
);
}
state
.vars_by_symbol
.extend(new_env.vars_by_symbol.iter().map(|(x, y)| (*x, *y)));
// run solver in next pool
// Solve the assignments' constraints first.
@ -565,6 +594,7 @@ fn solve(
let temp_state = State {
env: new_state.env,
mark: final_mark,
vars_by_symbol: new_state.vars_by_symbol,
};
// Now solve the body, using the new vars_by_symbol which includes