Store declared implementations, both custom and derived, in abilities store

This commit is contained in:
Ayaz Hafiz 2022-07-19 18:23:42 -04:00
parent 6035e45f25
commit e2454f497f
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
10 changed files with 249 additions and 171 deletions

View file

@ -394,7 +394,7 @@ impl ObligationCache<'_> {
for &member in members_of_ability {
if self
.abilities_store
.get_specialization(member, opaque)
.get_implementation(member, opaque)
.is_none()
{
let root_data = self.abilities_store.member_def(member).unwrap();
@ -671,9 +671,15 @@ pub fn resolve_ability_specialization(
let resolved = match obligated {
Obligated::Opaque(symbol) => {
let specialization = abilities_store.get_specialization(ability_member, symbol)?;
Resolved::Specialization(specialization.symbol)
match abilities_store.get_implementation(ability_member, symbol)? {
roc_types::types::MemberImpl::Impl(spec_symbol) => {
Resolved::Specialization(*spec_symbol)
}
roc_types::types::MemberImpl::Derived => Resolved::NeedsGenerated,
// TODO this is not correct. We can replace `Resolved` with `MemberImpl` entirely,
// which will make this simpler.
roc_types::types::MemberImpl::Error => Resolved::Specialization(Symbol::UNDERSCORE),
}
}
Obligated::Adhoc(_) => {
// TODO: more rules need to be validated here, like is this a builtin ability?

View file

@ -1,8 +1,8 @@
use crate::solve::{self, Aliases};
use roc_can::abilities::{AbilitiesStore, ResolvedSpecializations};
use roc_can::abilities::AbilitiesStore;
use roc_can::constraint::{Constraint as ConstraintSoa, Constraints};
use roc_can::expr::PendingDerives;
use roc_can::module::{ExposedByModule, RigidVariables};
use roc_can::module::{ExposedByModule, ResolvedSpecializations, RigidVariables};
use roc_collections::all::MutMap;
use roc_collections::VecMap;
use roc_derive::SharedDerivedModule;

View file

@ -4,7 +4,7 @@ use crate::ability::{
};
use crate::module::Solved;
use bumpalo::Bump;
use roc_can::abilities::{AbilitiesStore, MemberSpecialization};
use roc_can::abilities::{AbilitiesStore, MemberSpecializationInfo};
use roc_can::constraint::Constraint::{self, *};
use roc_can::constraint::{Constraints, Cycle, LetConstraint, OpportunisticResolve};
use roc_can::expected::{Expected, PExpected};
@ -16,7 +16,7 @@ use roc_debug_flags::dbg_do;
use roc_debug_flags::{ROC_TRACE_COMPACTION, ROC_VERIFY_RIGID_LET_GENERALIZED};
use roc_derive::SharedDerivedModule;
use roc_derive_key::{DeriveError, DeriveKey};
use roc_error_macros::internal_error;
use roc_error_macros::{internal_error, todo_abilities};
use roc_module::ident::TagName;
use roc_module::symbol::{ModuleId, Symbol};
use roc_problem::can::CycleEntry;
@ -28,8 +28,8 @@ use roc_types::subs::{
};
use roc_types::types::Type::{self, *};
use roc_types::types::{
gather_fields_unsorted_iter, AliasCommon, AliasKind, Category, ErrorType, OptAbleType,
OptAbleVar, PatternCategory, Reason, TypeExtension, Uls,
gather_fields_unsorted_iter, AliasCommon, AliasKind, Category, ErrorType, MemberImpl,
OptAbleType, OptAbleVar, PatternCategory, Reason, TypeExtension, Uls,
};
use roc_unify::unify::{
unify, unify_introduced_ability_specialization, Mode, MustImplementConstraints, Obligated,
@ -1755,12 +1755,11 @@ fn check_ability_specialization(
let specialization_region = symbol_loc_var.region;
let specialization =
MemberSpecialization::new(symbol, specialization_lambda_sets);
abilities_store.register_specialization_for_type(
ability_member,
opaque,
specialization,
);
MemberSpecializationInfo::new(symbol, specialization_lambda_sets);
abilities_store
.mark_implementation(ability_member, opaque, Ok(specialization))
.expect("marked as a custom implementation, but not recorded as such");
// Make sure we check that the opaque has specialized all members of the
// ability, after we finish solving the module.
@ -2301,7 +2300,7 @@ fn get_specialization_lambda_set_ambient_function<P: Phase>(
let external_specialized_lset =
phase.with_module_abilities_store(opaque_home, |abilities_store| {
let opt_specialization =
abilities_store.get_specialization(ability_member, opaque);
abilities_store.get_implementation(ability_member, opaque);
match (P::IS_LATE, opt_specialization) {
(false, None) => {
// doesn't specialize, we'll have reported an error for this
@ -2314,13 +2313,20 @@ fn get_specialization_lambda_set_ambient_function<P: Phase>(
ability_member,
);
}
(_, Some(specialization)) => {
let specialized_lambda_set = *specialization
.specialization_lambda_sets
.get(&lset_region)
.expect("lambda set region not resolved");
Ok(specialized_lambda_set)
}
(_, Some(member_impl)) => match member_impl {
MemberImpl::Impl(spec_symbol) => {
let specialization =
abilities_store.specialization_info(*spec_symbol).expect("expected custom implementations to always have complete specialization info by this point");
let specialized_lambda_set = *specialization
.specialization_lambda_sets
.get(&lset_region)
.expect("lambda set region not resolved");
Ok(specialized_lambda_set)
}
MemberImpl::Derived => todo_abilities!(),
MemberImpl::Error => todo_abilities!(),
},
}
})?;

View file

@ -361,7 +361,7 @@ mod solve_expr {
if !type_problems.is_empty() {
eprintln!("{:?}", type_problems);
panic!();
}
}iter_declared_impls
let known_specializations = abilities_store.iter_specializations();
use std::collections::HashSet;