mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-13 09:49:11 +03:00
hook up size inference, WIP
This commit is contained in:
parent
ed592d3d10
commit
7f1dd80392
@ -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
|
||||
"#
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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)],
|
||||
|
Loading…
Reference in New Issue
Block a user