instantiate rigids more intelligently

This commit is contained in:
Folkert 2021-07-31 22:38:11 +02:00
parent aee23d02fd
commit e1a36ea712

View file

@ -1219,144 +1219,87 @@ fn instantiate_rigids_help(
// will not repeat this work or crawl this variable again. // will not repeat this work or crawl this variable again.
match content { match content {
Structure(flat_type) => { Structure(flat_type) => {
let new_flat_type = match flat_type { match flat_type {
Apply(symbol, args) => { Apply(_, args) => {
let args = args for var in args.into_iter() {
.into_iter() instantiate_rigids_help(subs, max_rank, pools, var);
.map(|var| instantiate_rigids_help(subs, max_rank, pools, var)) }
.collect();
Apply(symbol, args)
} }
Func(arg_vars, closure_var, ret_var) => { Func(arg_vars, closure_var, ret_var) => {
let new_ret_var = instantiate_rigids_help(subs, max_rank, pools, ret_var); instantiate_rigids_help(subs, max_rank, pools, ret_var);
let new_closure_var =
instantiate_rigids_help(subs, max_rank, pools, closure_var); instantiate_rigids_help(subs, max_rank, pools, closure_var);
let arg_vars = arg_vars
.into_iter()
.map(|var| instantiate_rigids_help(subs, max_rank, pools, var))
.collect();
Func(arg_vars, new_closure_var, new_ret_var) for var in arg_vars.into_iter() {
instantiate_rigids_help(subs, max_rank, pools, var);
}
} }
same @ EmptyRecord | same @ EmptyTagUnion | same @ Erroneous(_) => same, EmptyRecord | EmptyTagUnion | Erroneous(_) => {}
Record(fields, ext_var) => { Record(fields, ext_var) => {
let mut new_fields = MutMap::default(); for (_, field) in fields {
for (label, field) in fields {
use RecordField::*; use RecordField::*;
let new_field = match field { match field {
Demanded(var) => { Demanded(var) => instantiate_rigids_help(subs, max_rank, pools, var),
Demanded(instantiate_rigids_help(subs, max_rank, pools, var)) Required(var) => instantiate_rigids_help(subs, max_rank, pools, var),
} Optional(var) => instantiate_rigids_help(subs, max_rank, pools, var),
Required(var) => {
Required(instantiate_rigids_help(subs, max_rank, pools, var))
}
Optional(var) => {
Optional(instantiate_rigids_help(subs, max_rank, pools, var))
}
}; };
new_fields.insert(label, new_field);
} }
Record( instantiate_rigids_help(subs, max_rank, pools, ext_var);
new_fields,
instantiate_rigids_help(subs, max_rank, pools, ext_var),
)
} }
TagUnion(tags, ext_var) => { TagUnion(tags, ext_var) => {
let mut new_tags = MutMap::default(); for (_, vars) in tags {
for var in vars.into_iter() {
for (tag, vars) in tags { instantiate_rigids_help(subs, max_rank, pools, var);
let new_vars: Vec<Variable> = vars }
.into_iter()
.map(|var| instantiate_rigids_help(subs, max_rank, pools, var))
.collect();
new_tags.insert(tag, new_vars);
} }
TagUnion( instantiate_rigids_help(subs, max_rank, pools, ext_var);
new_tags,
instantiate_rigids_help(subs, max_rank, pools, ext_var),
)
} }
FunctionOrTagUnion(tag_name, symbol, ext_var) => FunctionOrTagUnion( FunctionOrTagUnion(_tag_name, _symbol, ext_var) => {
tag_name, instantiate_rigids_help(subs, max_rank, pools, ext_var);
symbol, }
instantiate_rigids_help(subs, max_rank, pools, ext_var),
),
RecursiveTagUnion(rec_var, tags, ext_var) => { RecursiveTagUnion(rec_var, tags, ext_var) => {
let mut new_tags = MutMap::default(); instantiate_rigids_help(subs, max_rank, pools, rec_var);
let new_rec_var = instantiate_rigids_help(subs, max_rank, pools, rec_var); for (_, vars) in tags {
for var in vars.into_iter() {
for (tag, vars) in tags { instantiate_rigids_help(subs, max_rank, pools, var);
let new_vars: Vec<Variable> = vars }
.into_iter()
.map(|var| instantiate_rigids_help(subs, max_rank, pools, var))
.collect();
new_tags.insert(tag, new_vars);
} }
RecursiveTagUnion( instantiate_rigids_help(subs, max_rank, pools, ext_var);
new_rec_var,
new_tags,
instantiate_rigids_help(subs, max_rank, pools, ext_var),
)
} }
}; };
subs.set(copy, make_descriptor(Structure(new_flat_type)));
copy
} }
FlexVar(_) | Error => copy, FlexVar(_) | Error => {}
RecursionVar { RecursionVar { structure, .. } => {
opt_name, instantiate_rigids_help(subs, max_rank, pools, structure);
structure,
} => {
let new_structure = instantiate_rigids_help(subs, max_rank, pools, structure);
subs.set(
copy,
make_descriptor(RecursionVar {
opt_name,
structure: new_structure,
}),
);
copy
} }
RigidVar(name) => { RigidVar(name) => {
// what it's all about: convert the rigid var into a flex var
subs.set(copy, make_descriptor(FlexVar(Some(name)))); subs.set(copy, make_descriptor(FlexVar(Some(name))));
copy
} }
Alias(symbol, args, real_type_var) => { Alias(_, args, real_type_var) => {
let new_args = args for (_, var) in args.into_iter() {
.into_iter() instantiate_rigids_help(subs, max_rank, pools, var);
.map(|(name, var)| (name, instantiate_rigids_help(subs, max_rank, pools, var))) }
.collect();
let new_real_type_var = instantiate_rigids_help(subs, max_rank, pools, real_type_var);
let new_content = Alias(symbol, new_args, new_real_type_var);
subs.set(copy, make_descriptor(new_content)); instantiate_rigids_help(subs, max_rank, pools, real_type_var);
copy
} }
} }
var
} }
fn deep_copy_var(subs: &mut Subs, rank: Rank, pools: &mut Pools, var: Variable) -> Variable { fn deep_copy_var(subs: &mut Subs, rank: Rank, pools: &mut Pools, var: Variable) -> Variable {