hook up size inference, WIP

This commit is contained in:
Folkert 2020-10-14 22:55:25 +02:00
parent ed592d3d10
commit 7f1dd80392
5 changed files with 129 additions and 41 deletions

View File

@ -287,9 +287,9 @@ mod gen_list {
indoc!(
r#"
alwaysTrue : Int -> Bool
alwaysTrue = \_ ->
alwaysTrue = \_ ->
True
List.keepIf [] alwaysTrue
"#
@ -307,11 +307,11 @@ mod gen_list {
alwaysTrue : Int -> Bool
alwaysTrue = \i ->
True
oneThroughEight : List Int
oneThroughEight =
[1,2,3,4,5,6,7,8]
List.keepIf oneThroughEight alwaysTrue
"#
),
@ -328,7 +328,7 @@ mod gen_list {
alwaysFalse : Int -> Bool
alwaysFalse = \i ->
False
List.keepIf [1,2,3,4,5,6,7,8] alwaysFalse
"#
),
@ -345,8 +345,8 @@ mod gen_list {
intIsLessThanThree : Int -> Bool
intIsLessThanThree = \i ->
i < 3
List.keepIf [1,2,3,4,5,6,7,8] intIsLessThanThree
List.keepIf [1,2,3,4,5,6,7,8] intIsLessThanThree
"#
),
RocList::from_slice(&[1, 2]),
@ -433,7 +433,7 @@ mod gen_list {
nonEmpty : List Int
nonEmpty =
[ 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 ]
List.map nonEmpty (\x -> x * 2)
"#
),
@ -453,7 +453,7 @@ mod gen_list {
nonEmpty =
[ 1, 1, -4, 1, 2 ]
List.map nonEmpty (\x -> x > 0)
"#
),
@ -1159,7 +1159,7 @@ mod gen_list {
_ ->
[]
main =
main =
swap 0 1 [ 1, 2 ]
"#
),
@ -1339,8 +1339,8 @@ mod gen_list {
quicksort : List (Num a) -> List (Num a)
quicksort = \list ->
quicksortHelp list 0 (List.len list - 1)
quicksortHelp : List (Num a), Int, Int -> List (Num a)
quicksortHelp = \list, low, high ->
if low < high then
@ -1351,8 +1351,8 @@ mod gen_list {
|> quicksortHelp (partitionIndex + 1) high
else
list
swap : Int, Int, List a -> List a
swap = \i, j, list ->
when Pair (List.get list i) (List.get list j) is
@ -1360,10 +1360,10 @@ mod gen_list {
list
|> List.set i atJ
|> List.set j atI
_ ->
[]
partition : Int, Int, List (Num a) -> [ Pair Int (List (Num a)) ]
partition = \low, high, initialList ->
when List.get initialList high is
@ -1371,11 +1371,11 @@ mod gen_list {
when partitionHelp (low - 1) low initialList high pivot is
Pair newI newList ->
Pair (newI + 1) (swap (newI + 1) high newList)
Err _ ->
Pair (low - 1) initialList
partitionHelp : Int, Int, List (Num a), Int, Int -> [ Pair Int (List (Num a)) ]
partitionHelp = \i, j, list, high, pivot ->
# if j < high then
@ -1386,14 +1386,14 @@ mod gen_list {
partitionHelp (i + 1) (j + 1) (swap (i + 1) j list) high pivot
else
partitionHelp i (j + 1) list high pivot
Err _ ->
Pair i list
else
Pair i list
quicksort [ 7, 4, 21, 19 ]
"#
),
@ -1412,8 +1412,8 @@ mod gen_list {
quicksort : List (Num a) -> List (Num a)
quicksort = \list ->
quicksortHelp list 0 (List.len list - 1)
quicksortHelp : List (Num a), Int, Int -> List (Num a)
quicksortHelp = \list, low, high ->
if low < high then
@ -1424,8 +1424,8 @@ mod gen_list {
|> quicksortHelp (partitionIndex + 1) high
else
list
swap : Int, Int, List a -> List a
swap = \i, j, list ->
when Pair (List.get list i) (List.get list j) is
@ -1433,10 +1433,10 @@ mod gen_list {
list
|> List.set i atJ
|> List.set j atI
_ ->
[]
partition : Int, Int, List (Num a) -> [ Pair Int (List (Num a)) ]
partition = \low, high, initialList ->
when List.get initialList high is
@ -1444,11 +1444,11 @@ mod gen_list {
when partitionHelp (low - 1) low initialList high pivot is
Pair newI newList ->
Pair (newI + 1) (swap (newI + 1) high newList)
Err _ ->
Pair (low - 1) initialList
partitionHelp : Int, Int, List (Num a), Int, Int -> [ Pair Int (List (Num a)) ]
partitionHelp = \i, j, list, high, pivot ->
if j < high then
@ -1458,14 +1458,14 @@ mod gen_list {
partitionHelp (i + 1) (j + 1) (swap (i + 1) j list) high pivot
else
partitionHelp i (j + 1) list high pivot
Err _ ->
Pair i list
else
Pair i list
when List.first (quicksort [0x1]) is
_ -> 4
"#

View File

@ -900,4 +900,45 @@ mod gen_primitives {
i64
);
}
#[test]
fn closure() {
assert_evals_to!(
indoc!(
r#"
app Test provides [ main ] imports []
x = 42
f = \{} -> x
main =
f {}
"#
),
42,
i64
);
}
#[test]
fn nested_closure() {
assert_evals_to!(
indoc!(
r#"
app Test provides [ main ] imports []
x = 42
main =
f = \{} -> x
f {}
"#
),
42,
i64
);
}
}

View File

@ -1926,8 +1926,49 @@ fn run_solve<'a>(
let constrain_end = SystemTime::now();
let module_id = module.module_id;
let (solved_subs, solved_module) =
roc_solve::module::solve_module(module, constraint, var_store);
let Module {
exposed_vars_by_symbol,
aliases,
rigid_variables,
..
} = module;
let (mut solved_subs, solved_env, problems) =
roc_solve::module::run_solve(aliases, rigid_variables, constraint, var_store);
// determine the size of closures BEFORE converting to solved types
// this is separate from type inference so we can maybe do optimizations between type inference
// and closure size inference (those optimizations could shrink the closure size)
use Declaration::*;
let subs = solved_subs.inner_mut();
for decl in decls.iter() {
match decl {
Declare(def) => {
roc_mono::closures::infer_closure_size(def, subs, &solved_env);
}
Builtin(_) => {
// builtins should never have anything in their closure, so not determining their
// size _should_ be OK. We'll need to verify this in practice though
}
InvalidCycle(_, _) => {}
DeclareRec(defs) => {
for def in defs {
roc_mono::closures::infer_closure_size(def, subs, &solved_env);
}
}
}
}
let solved_types =
roc_solve::module::make_solved_types(&solved_env, &solved_subs, &exposed_vars_by_symbol);
let solved_module = SolvedModule {
exposed_vars_by_symbol,
solved_types,
problems,
aliases: solved_env.aliases,
};
// Record the final timings
let solve_end = SystemTime::now();

View File

@ -1,4 +1,5 @@
use roc_can::constraint::Constraint;
use roc_can::def::Def;
use roc_can::expected::Expected;
use roc_can::expr::Expr;
use roc_can::pattern::symbols_from_pattern;
@ -10,7 +11,12 @@ use roc_solve::solve;
use roc_types::subs::{Subs, VarStore};
use roc_types::types::{Category, Type};
pub fn infer_closure_size(expr: &Expr, subs: &mut Subs, solve_env: &solve::Env) {
pub fn infer_closure_size(def: &Def, subs: &mut Subs, solve_env: &solve::Env) {
infer_closure_size_expr(&def.loc_expr.value, subs, solve_env);
}
/// NOTE this is only safe to run on a top-level definition
fn infer_closure_size_expr(expr: &Expr, subs: &mut Subs, solve_env: &solve::Env) {
let mut var_store = VarStore::new_from_subs(subs);
let mut problems = Vec::new();
@ -153,7 +159,7 @@ pub fn free_variables(expr: &Expr) -> MutSet<Symbol> {
used
}
pub fn generate_constraint(expr: &Expr, var_store: &mut VarStore) -> Constraint {
fn generate_constraint(expr: &Expr, var_store: &mut VarStore) -> Constraint {
let mut constraints = Vec::new();
generate_constraints_help(expr, var_store, &mut constraints);
Constraint::And(constraints)

View File

@ -70,7 +70,7 @@ pub fn run_solve(
(solved_subs, solved_env, problems)
}
fn make_solved_types(
pub fn make_solved_types(
solved_env: &solve::Env,
solved_subs: &Solved<Subs>,
exposed_vars_by_symbol: &[(Symbol, Variable)],