Constraining ability members is the same as a usual def

This commit is contained in:
Ayaz Hafiz 2022-05-04 17:15:34 -04:00 committed by ayazhafiz
parent 45134a547d
commit 01af970b49
2 changed files with 44 additions and 25 deletions

View file

@ -1771,7 +1771,7 @@ pub struct InstantiateRigids {
pub new_infer_variables: Vec<Variable>, pub new_infer_variables: Vec<Variable>,
} }
fn instantiate_rigids( pub fn instantiate_rigids(
annotation: &Type, annotation: &Type,
introduced_vars: &IntroducedVariables, introduced_vars: &IntroducedVariables,
loc_pattern: &Loc<Pattern>, loc_pattern: &Loc<Pattern>,

View file

@ -1,3 +1,7 @@
use crate::expr::{
constrain_def_make_constraint, constrain_def_pattern, instantiate_rigids, Env,
InstantiateRigids,
};
use roc_builtins::std::StdLib; use roc_builtins::std::StdLib;
use roc_can::abilities::AbilitiesStore; use roc_can::abilities::AbilitiesStore;
use roc_can::constraint::{Constraint, Constraints}; use roc_can::constraint::{Constraint, Constraints};
@ -171,38 +175,53 @@ pub fn frontload_ability_constraints(
constraints: &mut Constraints, constraints: &mut Constraints,
abilities_store: &AbilitiesStore, abilities_store: &AbilitiesStore,
mut constraint: Constraint, mut constraint: Constraint,
home: ModuleId,
) -> Constraint { ) -> Constraint {
for (member_name, member_data) in abilities_store.root_ability_members().iter() { for (member_name, member_data) in abilities_store.root_ability_members().iter() {
// 1. Attach the type of member signature to the reserved signature_var. This is let rigids = Default::default();
// infallible. let env = Env { home, rigids };
let unify_with_signature_var = constraints.equal_types_var( let pattern = Loc::at_zero(roc_can::pattern::Pattern::Identifier(*member_name));
member_data.signature_var,
Expected::NoExpectation(member_data.signature.clone()), let mut def_pattern_state = constrain_def_pattern(
Category::Storage(std::file!(), std::column!()), constraints,
Region::zero(), &env,
&pattern,
Type::Variable(member_data.signature_var),
); );
// 2. Store the member signature on the member symbol. This makes sure we generalize it on def_pattern_state.vars.push(member_data.signature_var);
// the toplevel, as appropriate.
let vars = &member_data.variables;
let rigids = (vars.rigid_vars.iter())
// For our purposes, in the let constraint, able vars are treated like rigids.
.chain(vars.able_vars.iter())
.copied();
let flex = vars.flex_vars.iter().copied();
let let_constr = constraints.let_constraint( let mut ftv = env.rigids;
rigids,
flex, let InstantiateRigids {
[( signature,
*member_name, new_rigid_variables,
Loc::at_zero(Type::Variable(member_data.signature_var)), new_infer_variables,
)], } = instantiate_rigids(
&member_data.signature,
&member_data.introduced_variables,
&pattern,
&mut ftv,
&mut def_pattern_state.headers,
);
def_pattern_state
.constraints
.push(constraints.equal_types_var(
member_data.signature_var,
Expected::NoExpectation(signature.clone()),
Category::Storage(file!(), line!()),
Region::zero(),
));
constraint = constrain_def_make_constraint(
constraints,
new_rigid_variables,
new_infer_variables,
Constraint::True, Constraint::True,
constraint, constraint,
def_pattern_state,
); );
constraint = constraints.and_constraint([unify_with_signature_var, let_constr]);
} }
constraint constraint
} }