mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-23 06:25:10 +00:00
Canonicalize multiple abilities bound to a type variable
This commit is contained in:
parent
97dbac1631
commit
6bb97c92b9
9 changed files with 84 additions and 77 deletions
|
@ -70,8 +70,9 @@ pub fn run_solve(
|
|||
subs.rigid_var(var, name);
|
||||
}
|
||||
|
||||
for (var, (name, ability)) in rigid_variables.able {
|
||||
subs.rigid_able_var(var, name, ability);
|
||||
for (var, (name, abilities)) in rigid_variables.able {
|
||||
// TODO(abilities)
|
||||
subs.rigid_able_var(var, name, abilities[0]);
|
||||
}
|
||||
|
||||
for var in rigid_variables.wildcards {
|
||||
|
|
|
@ -345,12 +345,12 @@ impl Aliases {
|
|||
|
||||
for OptAbleVar {
|
||||
var: rec_var,
|
||||
opt_ability,
|
||||
opt_abilities,
|
||||
} in delayed_variables
|
||||
.recursion_variables(&mut self.variables)
|
||||
.iter_mut()
|
||||
{
|
||||
debug_assert!(opt_ability.is_none());
|
||||
debug_assert!(opt_abilities.is_none());
|
||||
let new_var = subs.fresh_unnamed_flex_var();
|
||||
substitutions.insert(*rec_var, new_var);
|
||||
|
||||
|
@ -367,7 +367,7 @@ impl Aliases {
|
|||
.iter_mut()
|
||||
.zip(new_lambda_set_variables)
|
||||
{
|
||||
debug_assert!(old.opt_ability.is_none());
|
||||
debug_assert!(old.opt_abilities.is_none());
|
||||
if old.var != *new {
|
||||
substitutions.insert(old.var, *new);
|
||||
|
||||
|
@ -2291,7 +2291,7 @@ fn type_to_variable<'a>(
|
|||
use bumpalo::collections::Vec;
|
||||
|
||||
let mut stack = Vec::with_capacity_in(8, arena);
|
||||
let mut bind_to_ability = Vec::new_in(arena);
|
||||
let mut bind_to_abilities = Vec::new_in(arena);
|
||||
|
||||
macro_rules! helper {
|
||||
($typ:expr, $ambient_function_policy:expr) => {{
|
||||
|
@ -2533,8 +2533,8 @@ fn type_to_variable<'a>(
|
|||
for (target_index, arg_type) in (new_variables.indices()).zip(type_arguments) {
|
||||
let copy_var = helper!(&arg_type.value.typ);
|
||||
subs.variables[target_index] = copy_var;
|
||||
if let Some(ability) = arg_type.value.opt_ability {
|
||||
bind_to_ability.push((Loc::at(arg_type.region, copy_var), ability));
|
||||
if let Some(abilities) = arg_type.value.opt_abilities.as_ref() {
|
||||
bind_to_abilities.push((Loc::at(arg_type.region, copy_var), abilities));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2595,12 +2595,15 @@ fn type_to_variable<'a>(
|
|||
let length = type_arguments.len() + lambda_set_variables.len();
|
||||
let new_variables = VariableSubsSlice::reserve_into_subs(subs, length);
|
||||
|
||||
for (target_index, OptAbleType { typ, opt_ability }) in
|
||||
for (target_index, OptAbleType { typ, opt_abilities }) in
|
||||
(new_variables.indices()).zip(type_arguments)
|
||||
{
|
||||
let copy_var = match opt_ability {
|
||||
let copy_var = match opt_abilities {
|
||||
None => helper!(typ),
|
||||
Some(ability) => {
|
||||
Some(abilities) => {
|
||||
// TODO(abilities)
|
||||
let ability = abilities[0];
|
||||
|
||||
// If this type argument is marked as being bound to an ability, we must
|
||||
// now correctly instantiate it as so.
|
||||
match RegisterVariable::from_type(subs, rank, pools, arena, typ) {
|
||||
|
@ -2608,7 +2611,7 @@ fn type_to_variable<'a>(
|
|||
use Content::*;
|
||||
match *subs.get_content_without_compacting(var) {
|
||||
FlexVar(opt_name) => subs
|
||||
.set_content(var, FlexAbleVar(opt_name, *ability)),
|
||||
.set_content(var, FlexAbleVar(opt_name, ability)),
|
||||
RigidVar(..) => internal_error!("Rigid var in type arg for {:?} - this is a bug in the solver, or our understanding", actual),
|
||||
RigidAbleVar(..) | FlexAbleVar(..) => internal_error!("Able var in type arg for {:?} - this is a bug in the solver, or our understanding", actual),
|
||||
_ => {
|
||||
|
@ -2744,17 +2747,20 @@ fn type_to_variable<'a>(
|
|||
};
|
||||
}
|
||||
|
||||
for (Loc { value: var, region }, ability) in bind_to_ability {
|
||||
for (Loc { value: var, region }, abilities) in bind_to_abilities {
|
||||
match *subs.get_content_unchecked(var) {
|
||||
Content::RigidVar(a) => {
|
||||
subs.set_content(var, Content::RigidAbleVar(a, ability));
|
||||
// TODO(multi-abilities)
|
||||
subs.set_content(var, Content::RigidAbleVar(a, abilities[0]));
|
||||
}
|
||||
Content::RigidAbleVar(_, ab) if ab == ability => {
|
||||
// TODO(multi-abilities)
|
||||
Content::RigidAbleVar(_, ab) if ab == abilities[0] => {
|
||||
// pass, already bound
|
||||
}
|
||||
_ => {
|
||||
// TODO(multi-abilities)
|
||||
let flex_ability = subs.fresh(Descriptor {
|
||||
content: Content::FlexAbleVar(None, ability),
|
||||
content: Content::FlexAbleVar(None, abilities[0]),
|
||||
rank,
|
||||
mark: Mark::NONE,
|
||||
copy: OptVariable::NONE,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue