mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
keep track of visited variables in deep_copy_var
This commit is contained in:
parent
0c66433373
commit
a0c9270124
1 changed files with 35 additions and 17 deletions
|
@ -1384,9 +1384,22 @@ fn instantiate_rigids_help(subs: &mut Subs, max_rank: Rank, initial: Variable) {
|
|||
}
|
||||
|
||||
fn deep_copy_var(subs: &mut Subs, rank: Rank, pools: &mut Pools, var: Variable) -> Variable {
|
||||
let copy = deep_copy_var_help(subs, rank, pools, var);
|
||||
let arena = bumpalo::Bump::with_capacity(4 * 1024);
|
||||
let mut visited = bumpalo::collections::Vec::with_capacity_in(4 * 1024, &arena);
|
||||
|
||||
subs.restore(var);
|
||||
let copy = deep_copy_var_help(subs, rank, pools, &mut visited, var);
|
||||
|
||||
// we have tracked all visited variables, and can now traverse them
|
||||
// in one go (without looking at the UnificationTable) and clear the copy field
|
||||
for var in visited {
|
||||
let descriptor = subs.get_ref_mut(var);
|
||||
|
||||
if descriptor.copy.is_some() {
|
||||
descriptor.rank = Rank::NONE;
|
||||
descriptor.mark = Mark::NONE;
|
||||
descriptor.copy = OptVariable::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
copy
|
||||
}
|
||||
|
@ -1395,6 +1408,7 @@ fn deep_copy_var_help(
|
|||
subs: &mut Subs,
|
||||
max_rank: Rank,
|
||||
pools: &mut Pools,
|
||||
visited: &mut bumpalo::collections::Vec<'_, Variable>,
|
||||
var: Variable,
|
||||
) -> Variable {
|
||||
use roc_types::subs::Content::*;
|
||||
|
@ -1408,6 +1422,8 @@ fn deep_copy_var_help(
|
|||
return var;
|
||||
}
|
||||
|
||||
visited.push(var);
|
||||
|
||||
let make_descriptor = |content| Descriptor {
|
||||
content,
|
||||
rank: max_rank,
|
||||
|
@ -1445,7 +1461,7 @@ fn deep_copy_var_help(
|
|||
|
||||
for index in args.into_iter() {
|
||||
let var = subs[index];
|
||||
let copy_var = deep_copy_var_help(subs, max_rank, pools, var);
|
||||
let copy_var = deep_copy_var_help(subs, max_rank, pools, visited, var);
|
||||
new_arg_vars.push(copy_var);
|
||||
}
|
||||
|
||||
|
@ -1455,14 +1471,15 @@ fn deep_copy_var_help(
|
|||
}
|
||||
|
||||
Func(arg_vars, closure_var, ret_var) => {
|
||||
let new_ret_var = deep_copy_var_help(subs, max_rank, pools, ret_var);
|
||||
let new_closure_var = deep_copy_var_help(subs, max_rank, pools, closure_var);
|
||||
let new_ret_var = deep_copy_var_help(subs, max_rank, pools, visited, ret_var);
|
||||
let new_closure_var =
|
||||
deep_copy_var_help(subs, max_rank, pools, visited, closure_var);
|
||||
|
||||
let mut new_arg_vars = Vec::with_capacity(arg_vars.len());
|
||||
|
||||
for index in arg_vars.into_iter() {
|
||||
let var = subs[index];
|
||||
let copy_var = deep_copy_var_help(subs, max_rank, pools, var);
|
||||
let copy_var = deep_copy_var_help(subs, max_rank, pools, visited, var);
|
||||
new_arg_vars.push(copy_var);
|
||||
}
|
||||
|
||||
|
@ -1479,7 +1496,7 @@ fn deep_copy_var_help(
|
|||
|
||||
for index in fields.iter_variables() {
|
||||
let var = subs[index];
|
||||
let copy_var = deep_copy_var_help(subs, max_rank, pools, var);
|
||||
let copy_var = deep_copy_var_help(subs, max_rank, pools, visited, var);
|
||||
|
||||
new_vars.push(copy_var);
|
||||
}
|
||||
|
@ -1510,7 +1527,7 @@ fn deep_copy_var_help(
|
|||
|
||||
Record(
|
||||
record_fields,
|
||||
deep_copy_var_help(subs, max_rank, pools, ext_var),
|
||||
deep_copy_var_help(subs, max_rank, pools, visited, ext_var),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1522,7 +1539,7 @@ fn deep_copy_var_help(
|
|||
let slice = subs[index];
|
||||
for var_index in slice {
|
||||
let var = subs[var_index];
|
||||
let new_var = deep_copy_var_help(subs, max_rank, pools, var);
|
||||
let new_var = deep_copy_var_help(subs, max_rank, pools, visited, var);
|
||||
new_variables.push(new_var);
|
||||
}
|
||||
|
||||
|
@ -1542,14 +1559,14 @@ fn deep_copy_var_help(
|
|||
|
||||
let union_tags = UnionTags::from_slices(tags.tag_names(), new_variables);
|
||||
|
||||
let new_ext = deep_copy_var_help(subs, max_rank, pools, ext_var);
|
||||
let new_ext = deep_copy_var_help(subs, max_rank, pools, visited, ext_var);
|
||||
TagUnion(union_tags, new_ext)
|
||||
}
|
||||
|
||||
FunctionOrTagUnion(tag_name, symbol, ext_var) => FunctionOrTagUnion(
|
||||
tag_name,
|
||||
symbol,
|
||||
deep_copy_var_help(subs, max_rank, pools, ext_var),
|
||||
deep_copy_var_help(subs, max_rank, pools, visited, ext_var),
|
||||
),
|
||||
|
||||
RecursiveTagUnion(rec_var, tags, ext_var) => {
|
||||
|
@ -1560,7 +1577,7 @@ fn deep_copy_var_help(
|
|||
let slice = subs[index];
|
||||
for var_index in slice {
|
||||
let var = subs[var_index];
|
||||
let new_var = deep_copy_var_help(subs, max_rank, pools, var);
|
||||
let new_var = deep_copy_var_help(subs, max_rank, pools, visited, var);
|
||||
new_variables.push(new_var);
|
||||
}
|
||||
|
||||
|
@ -1580,8 +1597,8 @@ fn deep_copy_var_help(
|
|||
|
||||
let union_tags = UnionTags::from_slices(tags.tag_names(), new_variables);
|
||||
|
||||
let new_ext = deep_copy_var_help(subs, max_rank, pools, ext_var);
|
||||
let new_rec_var = deep_copy_var_help(subs, max_rank, pools, rec_var);
|
||||
let new_ext = deep_copy_var_help(subs, max_rank, pools, visited, ext_var);
|
||||
let new_rec_var = deep_copy_var_help(subs, max_rank, pools, visited, rec_var);
|
||||
|
||||
RecursiveTagUnion(new_rec_var, union_tags, new_ext)
|
||||
}
|
||||
|
@ -1598,7 +1615,7 @@ fn deep_copy_var_help(
|
|||
opt_name,
|
||||
structure,
|
||||
} => {
|
||||
let new_structure = deep_copy_var_help(subs, max_rank, pools, structure);
|
||||
let new_structure = deep_copy_var_help(subs, max_rank, pools, visited, structure);
|
||||
|
||||
subs.set(
|
||||
copy,
|
||||
|
@ -1622,14 +1639,15 @@ fn deep_copy_var_help(
|
|||
|
||||
for var_index in args.variables() {
|
||||
let var = subs[var_index];
|
||||
let new_var = deep_copy_var_help(subs, max_rank, pools, var);
|
||||
let new_var = deep_copy_var_help(subs, max_rank, pools, visited, var);
|
||||
|
||||
new_vars.push(new_var);
|
||||
}
|
||||
|
||||
args.replace_variables(subs, new_vars);
|
||||
|
||||
let new_real_type_var = deep_copy_var_help(subs, max_rank, pools, real_type_var);
|
||||
let new_real_type_var =
|
||||
deep_copy_var_help(subs, max_rank, pools, visited, real_type_var);
|
||||
let new_content = Alias(symbol, args, new_real_type_var);
|
||||
|
||||
subs.set(copy, make_descriptor(new_content));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue