Opportunistically resolve specializations during solving

This commit is contained in:
Ayaz Hafiz 2022-05-09 12:53:46 -04:00
parent f07c56a25d
commit da00c47102
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
10 changed files with 185 additions and 57 deletions

View file

@ -1,8 +1,11 @@
use crate::ability::{type_implementing_member, AbilityImplError, DeferredMustImplementAbility};
use crate::ability::{
resolve_ability_specialization, type_implementing_member, AbilityImplError,
DeferredMustImplementAbility,
};
use bumpalo::Bump;
use roc_can::abilities::{AbilitiesStore, MemberSpecialization};
use roc_can::constraint::Constraint::{self, *};
use roc_can::constraint::{Constraints, LetConstraint};
use roc_can::constraint::{Constraints, LetConstraint, OpportunisticResolve};
use roc_can::expected::{Expected, PExpected};
use roc_collections::all::MutMap;
use roc_debug_flags::{dbg_do, ROC_VERIFY_RIGID_LET_GENERALIZED};
@ -1361,6 +1364,35 @@ fn solve(
problems.extend(errors.into_iter().map(TypeError::Exhaustive));
}
state
}
&Resolve(OpportunisticResolve {
specialization_variable,
specialization_expectation,
member,
specialization_id,
}) => {
if let Some(specialization) = resolve_ability_specialization(
subs,
abilities_store,
member,
specialization_variable,
) {
abilities_store.insert_resolved(specialization_id, specialization);
// We must now refine the current type state to account for this specialization.
let lookup_constr = arena.alloc(Constraint::Lookup(
specialization,
specialization_expectation,
Region::zero(),
));
stack.push(Work::Constraint {
env,
rank,
constraint: lookup_constr,
});
}
state
}
};
@ -1473,7 +1505,8 @@ fn check_ability_specialization(
// First, figure out and register for what type does this symbol specialize
// the ability member.
let specialization_type =
type_implementing_member(&must_implement_ability, root_data.parent_ability);
type_implementing_member(&must_implement_ability, root_data.parent_ability)
.expect("checked in previous branch");
let specialization = MemberSpecialization {
symbol,
region: symbol_loc_var.region,