mirror of
https://github.com/roc-lang/roc.git
synced 2025-11-26 13:52:15 +00:00
Work around symbol specializations not getting captured
This commit is contained in:
parent
b797e9c0c8
commit
447e1492e1
1 changed files with 25 additions and 1 deletions
|
|
@ -7537,7 +7537,31 @@ where
|
||||||
// if this is an imported symbol, then we must make sure it is
|
// if this is an imported symbol, then we must make sure it is
|
||||||
// specialized, and wrap the original in a function pointer.
|
// specialized, and wrap the original in a function pointer.
|
||||||
let mut result = result;
|
let mut result = result;
|
||||||
for (_, (variable, left)) in needed_specializations_of_left {
|
|
||||||
|
let no_specializations_needed = needed_specializations_of_left.len() == 0;
|
||||||
|
let needed_specializations_of_left = needed_specializations_of_left
|
||||||
|
.map(|(_, spec)| Some(spec))
|
||||||
|
// HACK: sometimes specializations can be lost, for example for `x` in
|
||||||
|
// x = Bool.true
|
||||||
|
// p = \_ -> x == 1
|
||||||
|
// that's because when specializing `p`, we collect specializations for `x`, but then
|
||||||
|
// drop all of them when leaving the body of `p`, because `x` is an argument of `p` in
|
||||||
|
// such a case.
|
||||||
|
// So, if we have no recorded specializations, suppose we are in a case like this, and
|
||||||
|
// generate the default implementation.
|
||||||
|
//
|
||||||
|
// TODO: we should fix this properly. I think the way to do it is to only have proc
|
||||||
|
// specialization only drop specializations of non-captured symbols. That's because
|
||||||
|
// captured symbols can only ever be specialized outside the closure.
|
||||||
|
// After that is done, remove this hack.
|
||||||
|
.chain(if no_specializations_needed {
|
||||||
|
[Some((variable, left))]
|
||||||
|
} else {
|
||||||
|
[None]
|
||||||
|
})
|
||||||
|
.filter_map(std::convert::identity);
|
||||||
|
|
||||||
|
for (variable, left) in needed_specializations_of_left {
|
||||||
add_needed_external(procs, env, variable, LambdaName::no_niche(right));
|
add_needed_external(procs, env, variable, LambdaName::no_niche(right));
|
||||||
|
|
||||||
let res_layout = layout_cache.from_var(env.arena, variable, env.subs);
|
let res_layout = layout_cache.from_var(env.arena, variable, env.subs);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue