More can abilities

This commit is contained in:
Ayaz Hafiz 2022-07-15 17:49:42 -04:00
parent e798eb3037
commit d118e5afbc
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
2 changed files with 58 additions and 19 deletions

View file

@ -470,12 +470,41 @@ fn canonicalize_opaque<'a>(
// } // }
let mut impl_map: VecMap<Symbol, Symbol> = VecMap::default(); let mut impl_map: VecMap<Symbol, Symbol> = VecMap::default();
let ability_home = ability.module_id();
for loc_field in impls.extract_spaces().item.items { for loc_field in impls.extract_spaces().item.items {
match loc_field.value { match loc_field.value {
AssignedField::LabelOnly(label) => { AssignedField::LabelOnly(label) => {
let sym: Symbol = todo!(); let label_ident = label.into();
let region = label.region;
impl_map.insert(sym, sym); let member_symbol = match env.qualified_lookup_with_module_id(scope, ability_home, label_ident, region) {
Ok(symbol) => {
symbol
}
Err(_) => {
env.problem(Problem::NotAnAbilityMember {
ability,
region,
});
}
}
match scope.lookup(label.value.into(), label.region) {
Ok(symbol) => {
impl_map.insert(symbol, symbol);
}
Err(_) => {
// [Eq { eq }]
env.problem(Problem::ImplementationNotFound{
ability,
member: scope.lookup()
region: label.region,
});
}
}
} }
AssignedField::RequiredValue( AssignedField::RequiredValue(
label, label,
@ -579,7 +608,9 @@ pub(crate) fn canonicalize_defs<'a>(
// to itself won't be processed until after its def has been added to scope. // to itself won't be processed until after its def has been added to scope.
let mut pending_type_defs = Vec::with_capacity(loc_defs.type_defs.len()); let mut pending_type_defs = Vec::with_capacity(loc_defs.type_defs.len());
let mut value_defs = Vec::with_capacity(loc_defs.value_defs.len()); let mut pending_value_defs = Vec::with_capacity(loc_defs.value_defs.len());
let mut output = Output::default();
for (index, either_index) in loc_defs.tags.iter().enumerate() { for (index, either_index) in loc_defs.tags.iter().enumerate() {
match either_index.split() { match either_index.split() {
@ -590,7 +621,17 @@ pub(crate) fn canonicalize_defs<'a>(
Err(value_index) => { Err(value_index) => {
let value_def = &loc_defs.value_defs[value_index.index()]; let value_def = &loc_defs.value_defs[value_index.index()];
let region = loc_defs.regions[index]; let region = loc_defs.regions[index];
value_defs.push(Loc::at(region, value_def));
let pending = to_pending_value_def(
env,
var_store,
&value_def,
scope,
&mut output,
pattern_type,
);
pending_value_defs.push(Loc::at(region, pending));
} }
} }
} }
@ -615,7 +656,7 @@ pub(crate) fn canonicalize_defs<'a>(
output, output,
var_store, var_store,
scope, scope,
&value_defs, &pending_value_defs,
pattern_type, pattern_type,
aliases, aliases,
symbols_introduced, symbols_introduced,
@ -628,7 +669,7 @@ fn canonicalize_value_defs<'a>(
mut output: Output, mut output: Output,
var_store: &mut VarStore, var_store: &mut VarStore,
scope: &mut Scope, scope: &mut Scope,
value_defs: &[Loc<&'a roc_parse::ast::ValueDef<'a>>], value_defs: &[Loc<PendingValue<'a>>],
pattern_type: PatternType, pattern_type: PatternType,
mut aliases: VecMap<Symbol, Alias>, mut aliases: VecMap<Symbol, Alias>,
mut symbols_introduced: MutMap<Symbol, Region>, mut symbols_introduced: MutMap<Symbol, Region>,
@ -639,25 +680,14 @@ fn canonicalize_value_defs<'a>(
let mut pending_value_defs = Vec::with_capacity(value_defs.len()); let mut pending_value_defs = Vec::with_capacity(value_defs.len());
let mut pending_expects = Vec::with_capacity(value_defs.len()); let mut pending_expects = Vec::with_capacity(value_defs.len());
for loc_def in value_defs { for loc_pending_def in value_defs {
let mut new_output = Output::default(); match loc_pending_def.value {
let pending = to_pending_value_def(
env,
var_store,
loc_def.value,
scope,
&mut new_output,
pattern_type,
);
match pending {
PendingValue::Def(pending_def) => { PendingValue::Def(pending_def) => {
// Record the ast::Expr for later. We'll do another pass through these // Record the ast::Expr for later. We'll do another pass through these
// once we have the entire scope assembled. If we were to canonicalize // once we have the entire scope assembled. If we were to canonicalize
// the exprs right now, they wouldn't have symbols in scope from defs // the exprs right now, they wouldn't have symbols in scope from defs
// that get would have gotten added later in the defs list! // that get would have gotten added later in the defs list!
pending_value_defs.push(pending_def); pending_value_defs.push(pending_def);
output.union(new_output);
} }
PendingValue::SignatureDefMismatch => { /* skip */ } PendingValue::SignatureDefMismatch => { /* skip */ }
PendingValue::Expect(pending_expect) => { PendingValue::Expect(pending_expect) => {

View file

@ -131,6 +131,15 @@ pub enum Problem {
AbilityUsedAsType(Lowercase, Symbol, Region), AbilityUsedAsType(Lowercase, Symbol, Region),
NestedSpecialization(Symbol, Region), NestedSpecialization(Symbol, Region),
IllegalDerive(Region), IllegalDerive(Region),
ImplementationNotFound {
ability: Symbol,
member: Symbol,
region: Region,
},
NotAnAbilityMember {
ability: Symbol,
region: Region,
},
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]