mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
specialize rigids
This commit is contained in:
parent
973a632c25
commit
edc0717a7d
3 changed files with 117 additions and 21 deletions
|
@ -1326,12 +1326,8 @@ pub fn specialize_all<'a>(
|
|||
pending.clone(),
|
||||
partial_proc,
|
||||
) {
|
||||
Ok((proc, layout)) if outside_layout != layout => {
|
||||
println!("Layouts don't match for function {:?}", proc.name,);
|
||||
dbg!(outside_layout, layout, &pending.solved_type);
|
||||
panic!();
|
||||
}
|
||||
Ok((proc, layout)) => {
|
||||
debug_assert_eq!(outside_layout, layout);
|
||||
procs.specialized.remove(&(name, outside_layout));
|
||||
procs.specialized.insert((name, layout), Done(proc));
|
||||
}
|
||||
|
@ -1490,7 +1486,7 @@ fn specialize_solved_type<'a>(
|
|||
) -> Result<(Proc<'a>, Layout<'a>), LayoutProblem> {
|
||||
// add the specializations that other modules require of us
|
||||
use roc_constrain::module::{to_type, FreeVars};
|
||||
use roc_solve::solve::insert_type_into_subs;
|
||||
use roc_solve::solve::{insert_type_into_subs, instantiate_rigids};
|
||||
use roc_types::subs::VarStore;
|
||||
|
||||
let snapshot = env.subs.snapshot();
|
||||
|
@ -1509,6 +1505,9 @@ fn specialize_solved_type<'a>(
|
|||
|
||||
let fn_var = insert_type_into_subs(env.subs, &normal_type);
|
||||
|
||||
// make sure rigid variables in the annotation are converted to flex variables
|
||||
instantiate_rigids(env.subs, partial_proc.annotation);
|
||||
|
||||
match specialize_external(env, procs, proc_name, layout_cache, fn_var, partial_proc) {
|
||||
Ok(proc) => {
|
||||
let layout = layout_cache
|
||||
|
@ -2726,7 +2725,15 @@ pub fn from_can<'a>(
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
let rest = from_can(env, cont.value, procs, layout_cache);
|
||||
|
||||
let mut rest = from_can(env, cont.value, procs, layout_cache);
|
||||
|
||||
// a variable is aliased
|
||||
if let roc_can::expr::Expr::Var(original) = def.loc_expr.value {
|
||||
substitute_in_exprs(env.arena, &mut rest, *symbol, original);
|
||||
|
||||
return rest;
|
||||
} else {
|
||||
return with_hole(
|
||||
env,
|
||||
def.loc_expr.value,
|
||||
|
@ -2736,6 +2743,7 @@ pub fn from_can<'a>(
|
|||
env.arena.alloc(rest),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// this may be a destructure pattern
|
||||
let mono_pattern = from_can_pattern(env, layout_cache, &def.loc_pattern.value);
|
||||
|
@ -2744,6 +2752,7 @@ pub fn from_can<'a>(
|
|||
let hole = env
|
||||
.arena
|
||||
.alloc(from_can(env, cont.value, procs, layout_cache));
|
||||
|
||||
with_hole(env, def.loc_expr.value, procs, layout_cache, symbol, hole)
|
||||
} else {
|
||||
let context = crate::exhaustive::Context::BadDestruct;
|
||||
|
|
|
@ -875,7 +875,8 @@ mod test_mono {
|
|||
indoc!(
|
||||
r#"
|
||||
let Test.0 = 5i64;
|
||||
ret Test.0;
|
||||
let Test.2 = 3i64;
|
||||
ret Test.2;
|
||||
"#
|
||||
),
|
||||
);
|
||||
|
@ -1920,4 +1921,89 @@ mod test_mono {
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rigids() {
|
||||
compiles_to_ir(
|
||||
indoc!(
|
||||
r#"
|
||||
swap : Int, Int, List a -> List a
|
||||
swap = \i, j, list ->
|
||||
when Pair (List.get list i) (List.get list j) is
|
||||
Pair (Ok atI) (Ok atJ) ->
|
||||
foo = atJ
|
||||
|
||||
list
|
||||
|> List.set i foo
|
||||
|> List.set j atI
|
||||
|
||||
_ ->
|
||||
[]
|
||||
|
||||
swap 0 0 [0x1]
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
procedure List.3 (#Attr.2, #Attr.3):
|
||||
let Test.43 = lowlevel ListLen #Attr.2;
|
||||
let Test.39 = lowlevel NumLt #Attr.3 Test.43;
|
||||
if Test.39 then
|
||||
let Test.41 = 1i64;
|
||||
let Test.42 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
let Test.40 = Ok Test.41 Test.42;
|
||||
ret Test.40;
|
||||
else
|
||||
let Test.37 = 0i64;
|
||||
let Test.38 = Struct {};
|
||||
let Test.36 = Err Test.37 Test.38;
|
||||
ret Test.36;
|
||||
|
||||
procedure List.4 (#Attr.2, #Attr.3, #Attr.4):
|
||||
let Test.19 = lowlevel ListLen #Attr.2;
|
||||
let Test.17 = lowlevel NumLt #Attr.3 Test.19;
|
||||
if Test.17 then
|
||||
let Test.18 = lowlevel ListSet #Attr.2 #Attr.3 #Attr.4;
|
||||
ret Test.18;
|
||||
else
|
||||
ret #Attr.2;
|
||||
|
||||
procedure Test.0 (Test.2, Test.3, Test.4):
|
||||
let Test.34 = CallByName List.3 Test.4 Test.2;
|
||||
let Test.35 = CallByName List.3 Test.4 Test.3;
|
||||
let Test.13 = Struct {Test.34, Test.35};
|
||||
let Test.24 = true;
|
||||
let Test.26 = 1i64;
|
||||
let Test.25 = Index 0 Test.13;
|
||||
let Test.27 = Index 0 Test.25;
|
||||
let Test.33 = lowlevel Eq Test.26 Test.27;
|
||||
let Test.31 = lowlevel And Test.33 Test.24;
|
||||
let Test.29 = 1i64;
|
||||
let Test.28 = Index 1 Test.13;
|
||||
let Test.30 = Index 0 Test.28;
|
||||
let Test.32 = lowlevel Eq Test.29 Test.30;
|
||||
let Test.23 = lowlevel And Test.32 Test.31;
|
||||
if Test.23 then
|
||||
let Test.21 = Index 0 Test.13;
|
||||
let Test.5 = Index 1 Test.21;
|
||||
let Test.20 = Index 1 Test.13;
|
||||
let Test.6 = Index 1 Test.20;
|
||||
let Test.15 = CallByName List.4 Test.4 Test.2 Test.6;
|
||||
let Test.14 = CallByName List.4 Test.15 Test.3 Test.5;
|
||||
ret Test.14;
|
||||
else
|
||||
dec Test.4;
|
||||
let Test.22 = Array [];
|
||||
ret Test.22;
|
||||
|
||||
let Test.9 = 0i64;
|
||||
let Test.10 = 0i64;
|
||||
let Test.12 = 1i64;
|
||||
let Test.11 = Array [Test.12];
|
||||
let Test.8 = CallByName Test.0 Test.9 Test.10 Test.11;
|
||||
ret Test.8;
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
interface Utils exposes [ swap ] imports []
|
||||
|
||||
swap : Int, Int, List a -> List a
|
||||
swap = \i, j, list ->
|
||||
when Pair (List.get list i) (List.get list j) is
|
||||
Pair (Ok atI) (Ok atJ) ->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue