Cleanup abilities_in_scope and rename to pending_abilities_in_scope

`abilities_in_scope` is a buffer we use to keep track of locally-defined
abilities before we've fully resolved them. We do this because we
canonicalize ability members signatures before we've registered an
ability to the abilities store, and canonicalization of signatures must
report `has` bounds that don't reference abilities.

So, this buffer is more appropriately named `pending_abilities_in_scope`.
There is also no reason to export it, because it is only relevant
during canonicalization of type defs in a module.
This commit is contained in:
Ayaz Hafiz 2022-05-20 09:57:31 -04:00
parent eb706d2863
commit 22bf650685
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
4 changed files with 19 additions and 21 deletions

View file

@ -267,7 +267,7 @@ pub fn canonicalize_annotation(
annotation: &TypeAnnotation,
region: Region,
var_store: &mut VarStore,
abilities_in_scope: &[Symbol],
pending_abilities_in_scope: &[Symbol],
) -> Annotation {
let mut introduced_variables = IntroducedVariables::default();
let mut references = VecSet::default();
@ -284,7 +284,7 @@ pub fn canonicalize_annotation(
var_store,
&mut introduced_variables,
clause,
abilities_in_scope,
pending_abilities_in_scope,
&mut references,
);
if let Err(err_type) = opt_err {
@ -908,7 +908,7 @@ fn canonicalize_has_clause(
var_store: &mut VarStore,
introduced_variables: &mut IntroducedVariables,
clause: &Loc<roc_parse::ast::HasClause<'_>>,
abilities_in_local_scope: &[Symbol],
pending_abilities_in_scope: &[Symbol],
references: &mut VecSet<Symbol>,
) -> Result<(), Type> {
let Loc {
@ -929,7 +929,7 @@ fn canonicalize_has_clause(
let symbol = make_apply_symbol(env, ability.region, scope, module_name, ident)?;
// Ability defined locally, whose members we are constructing right now...
if !abilities_in_local_scope.contains(&symbol)
if !pending_abilities_in_scope.contains(&symbol)
// or an ability that was imported from elsewhere
&& !scope.abilities_store.is_ability(symbol)
{

View file

@ -59,7 +59,6 @@ pub struct Annotation {
pub(crate) struct CanDefs {
defs: Vec<Option<Def>>,
def_ordering: DefOrdering,
pub(crate) abilities_in_scope: Vec<Symbol>,
aliases: VecMap<Symbol, Alias>,
}
@ -261,7 +260,7 @@ pub(crate) fn canonicalize_defs<'a>(
}
let mut type_defs = MutMap::default();
let mut abilities_in_scope = Vec::new();
let mut pending_abilities_in_scope = Vec::new();
let mut referenced_type_symbols = VecMap::default();
@ -298,7 +297,7 @@ pub(crate) fn canonicalize_defs<'a>(
referenced_type_symbols.insert(name.value, referenced_symbols);
type_defs.insert(name.value, TypeDef::Ability(name, members));
abilities_in_scope.push(name.value);
pending_abilities_in_scope.push(name.value);
}
PendingTypeDef::InvalidAlias { .. }
| PendingTypeDef::InvalidAbility { .. }
@ -322,7 +321,7 @@ pub(crate) fn canonicalize_defs<'a>(
&ann.value,
ann.region,
var_store,
&abilities_in_scope,
&pending_abilities_in_scope,
);
// Record all the annotation's references in output.references.lookups
@ -444,7 +443,7 @@ pub(crate) fn canonicalize_defs<'a>(
var_store,
scope,
abilities,
&abilities_in_scope,
&pending_abilities_in_scope,
pattern_type,
);
@ -512,7 +511,6 @@ pub(crate) fn canonicalize_defs<'a>(
var_store,
pattern_type,
&mut aliases,
&abilities_in_scope,
);
output = temp_output.output;
@ -526,7 +524,6 @@ pub(crate) fn canonicalize_defs<'a>(
CanDefs {
defs,
def_ordering,
abilities_in_scope,
// The result needs a thread-safe `SendMap`
aliases,
},
@ -543,7 +540,7 @@ fn resolve_abilities<'a>(
var_store: &mut VarStore,
scope: &mut Scope,
abilities: MutMap<Symbol, (Loc<Symbol>, &[AbilityMember])>,
abilities_in_scope: &[Symbol],
pending_abilities_in_scope: &[Symbol],
pattern_type: PatternType,
) {
for (loc_ability_name, members) in abilities.into_values() {
@ -556,7 +553,7 @@ fn resolve_abilities<'a>(
&member.typ.value,
member.typ.region,
var_store,
abilities_in_scope,
pending_abilities_in_scope,
);
// Record all the annotation's references in output.references.lookups
@ -766,11 +763,8 @@ pub(crate) fn sort_can_defs(
mut defs,
def_ordering,
aliases,
abilities_in_scope,
} = defs;
output.abilities_in_scope = abilities_in_scope;
for (symbol, alias) in aliases.into_iter() {
output.aliases.insert(symbol, alias);
}
@ -1007,10 +1001,12 @@ fn canonicalize_pending_value_def<'a>(
var_store: &mut VarStore,
pattern_type: PatternType,
aliases: &mut VecMap<Symbol, Alias>,
abilities_in_scope: &[Symbol],
) -> DefOutput {
use PendingValueDef::*;
// All abilities should be resolved by the time we're canonicalizing value defs.
let pending_abilities_in_scope = &[];
let output = match pending_def {
AnnotationOnly(_, loc_can_pattern, loc_ann) => {
// Make types for the body expr, even if we won't end up having a body.
@ -1025,7 +1021,7 @@ fn canonicalize_pending_value_def<'a>(
&loc_ann.value,
loc_ann.region,
var_store,
abilities_in_scope,
pending_abilities_in_scope,
);
// Record all the annotation's references in output.references.lookups
@ -1122,7 +1118,7 @@ fn canonicalize_pending_value_def<'a>(
&loc_ann.value,
loc_ann.region,
var_store,
abilities_in_scope,
pending_abilities_in_scope,
);
// Record all the annotation's references in output.references.lookups

View file

@ -31,7 +31,6 @@ pub struct Output {
pub introduced_variables: IntroducedVariables,
pub aliases: VecMap<Symbol, Alias>,
pub non_closures: VecSet<Symbol>,
pub abilities_in_scope: Vec<Symbol>,
}
impl Output {

View file

@ -357,13 +357,16 @@ pub fn canonicalize_module_defs<'a>(
let symbols_from_requires = symbols_from_requires
.iter()
.map(|(symbol, loc_ann)| {
// We've already canonicalized the module, so there are no pending abilities.
let pending_abilities_in_scope = &[];
let ann = canonicalize_annotation(
&mut env,
&mut scope,
&loc_ann.value,
loc_ann.region,
var_store,
&output.abilities_in_scope,
pending_abilities_in_scope,
);
ann.add_to(