mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Explicitly disallow ability definitions in nested scopes
Abilities can only be defined on the toplevel of a module. There is a technical reason to this, which is that during type solving we must introduce all abilities at the very beginning, and we need to make sure ranks are correct. But there is a practical reason as well, which is that nested ability definitions don't seem to be very useful. Note that specializations can be nested, and are allowed to be. Also, we can revisit this in the future. I just don't want experiments to break right now because someone uses an ability in a nested scope where we don't expect. Closes #2878
This commit is contained in:
parent
340f6b7c88
commit
f129777115
5 changed files with 89 additions and 31 deletions
|
@ -241,10 +241,12 @@ pub fn canonicalize_defs<'a>(
|
|||
let pending_type_defs = type_defs
|
||||
.into_iter()
|
||||
.filter_map(|loc_def| {
|
||||
to_pending_type_def(env, loc_def.value, &mut scope).map(|(new_output, pending_def)| {
|
||||
output.union(new_output);
|
||||
pending_def
|
||||
})
|
||||
to_pending_type_def(env, loc_def.value, &mut scope, pattern_type).map(
|
||||
|(new_output, pending_def)| {
|
||||
output.union(new_output);
|
||||
pending_def
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -1679,6 +1681,7 @@ fn to_pending_type_def<'a>(
|
|||
env: &mut Env<'a>,
|
||||
def: &'a ast::TypeDef<'a>,
|
||||
scope: &mut Scope,
|
||||
pattern_type: PatternType,
|
||||
) -> Option<(Output, PendingTypeDef<'a>)> {
|
||||
use ast::TypeDef::*;
|
||||
|
||||
|
@ -1762,6 +1765,19 @@ fn to_pending_type_def<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
Ability {
|
||||
header, members, ..
|
||||
} if pattern_type != PatternType::TopLevelDef => {
|
||||
let header_region = header.region();
|
||||
let region = Region::span_across(
|
||||
&header_region,
|
||||
&members.last().map(|m| m.region()).unwrap_or(header_region),
|
||||
);
|
||||
env.problem(Problem::AbilityNotOnToplevel { region });
|
||||
|
||||
Some((Output::default(), PendingTypeDef::InvalidAbility))
|
||||
}
|
||||
|
||||
Ability {
|
||||
header: TypeHeader { name, vars },
|
||||
members,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue