Solve and gen ability members that bind other able variables

This commit is contained in:
Ayaz Hafiz 2022-04-21 14:11:32 -04:00 committed by ayazhafiz
parent 5fe902b8d3
commit b5efd830e5
6 changed files with 110 additions and 28 deletions

View file

@ -578,12 +578,14 @@ fn resolve_abilities<'a>(
// What variables in the annotation are bound to the parent ability, and what variables
// are bound to some other ability?
let (variables_bound_to_ability, variables_bound_to_other_abilities): (Vec<_>, Vec<_>) =
member_annot
.introduced_variables
.able
.iter()
.partition(|av| av.ability == loc_ability_name.value);
let (variables_bound_to_ability, _variables_bound_to_other_abilities): (
Vec<_>,
Vec<_>,
) = member_annot
.introduced_variables
.able
.iter()
.partition(|av| av.ability == loc_ability_name.value);
let mut bad_has_clauses = false;
@ -618,18 +620,6 @@ fn resolve_abilities<'a>(
bad_has_clauses = true;
}
if !variables_bound_to_other_abilities.is_empty() {
// Disallow variables bound to other abilities, for now.
for bad_variable in variables_bound_to_other_abilities.iter() {
env.problem(Problem::AbilityMemberBindsExternalAbility {
member: member_sym,
ability: loc_ability_name.value,
region: bad_variable.first_seen,
});
}
bad_has_clauses = true;
}
if bad_has_clauses {
// Pretend the member isn't a part of the ability
continue;

View file

@ -45,11 +45,12 @@ fn walk_def<V: Visitor>(visitor: &mut V, def: &Def) {
..
} = def;
visitor.visit_pattern(
&loc_pattern.value,
loc_pattern.region,
loc_pattern.value.opt_var(),
);
let opt_var = match loc_pattern.value {
Pattern::Identifier(..) | Pattern::AbilityMemberSpecialization { .. } => Some(*expr_var),
_ => loc_pattern.value.opt_var(),
};
visitor.visit_pattern(&loc_pattern.value, loc_pattern.region, opt_var);
visitor.visit_expr(&loc_expr.value, loc_expr.region, *expr_var);
if let Some(annot) = &annotation {
visitor.visit_annotation(annot);
@ -70,6 +71,9 @@ fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr) {
} => {
walk_when(visitor, *cond_var, *expr_var, loc_cond, branches);
}
Expr::Call(f, loc_args, _) => {
walk_call(visitor, f, loc_args);
}
e => todo!("{:?}", e),
}
}
@ -120,6 +124,18 @@ fn walk_when_branch<V: Visitor>(visitor: &mut V, branch: &WhenBranch, expr_var:
}
}
fn walk_call<V: Visitor>(
visitor: &mut V,
f: &(Variable, Loc<Expr>, Variable, Variable),
loc_args: &[(Variable, Loc<Expr>)],
) {
let (fn_var, loc_fn_expr, _lambda_set, _ret) = f;
visitor.visit_expr(&loc_fn_expr.value, loc_fn_expr.region, *fn_var);
loc_args
.iter()
.for_each(|(v, e)| visitor.visit_expr(&e.value, e.region, *v));
}
fn walk_pattern<V: Visitor>(_visitor: &mut V, _pat: &Pattern) {
todo!()
}