mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
Handle symbols that shadow ability member definitions
Just add the shadowing symbol for now. We'll handle checking that a specialization's type matches the member's type definition in a later pass, during typechecking.
This commit is contained in:
parent
884d07344e
commit
73bfff699f
7 changed files with 193 additions and 40 deletions
|
@ -6,6 +6,8 @@ use roc_region::all::{Loc, Region};
|
|||
use roc_types::subs::{VarStore, Variable};
|
||||
use roc_types::types::{Alias, AliasKind, Type};
|
||||
|
||||
use crate::abilities::AbilitiesStore;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Scope {
|
||||
/// All the identifiers in scope, mapped to were they were defined and
|
||||
|
@ -232,6 +234,50 @@ impl Scope {
|
|||
}
|
||||
}
|
||||
|
||||
/// Like [Self::introduce], but handles the case of when an ident matches an ability member
|
||||
/// name. In such cases a new symbol is created for the ident (since it's expected to be a
|
||||
/// specialization of the ability member), but the ident is not added to the ident->symbol map.
|
||||
///
|
||||
/// If the ident does not match an ability name, the behavior of this function is exactly that
|
||||
/// of `introduce`.
|
||||
pub fn introduce_or_shadow_ability_member(
|
||||
&mut self,
|
||||
ident: Ident,
|
||||
exposed_ident_ids: &IdentIds,
|
||||
all_ident_ids: &mut IdentIds,
|
||||
region: Region,
|
||||
abilities_store: &AbilitiesStore,
|
||||
) -> Result<(Symbol, Option<Symbol>), (Region, Loc<Ident>, Symbol)> {
|
||||
match self.idents.get(&ident) {
|
||||
Some(&(original_symbol, original_region)) => {
|
||||
let shadow_ident_id = all_ident_ids.add(ident.clone());
|
||||
let shadow_symbol = Symbol::new(self.home, shadow_ident_id);
|
||||
|
||||
self.symbols.insert(shadow_symbol, region);
|
||||
|
||||
if abilities_store.is_ability_member_name(original_symbol) {
|
||||
// Add a symbol for the shadow, but don't re-associate the member name.
|
||||
Ok((shadow_symbol, Some(original_symbol)))
|
||||
} else {
|
||||
// This is an illegal shadow.
|
||||
let shadow = Loc {
|
||||
value: ident.clone(),
|
||||
region,
|
||||
};
|
||||
|
||||
self.idents.insert(ident, (shadow_symbol, region));
|
||||
|
||||
Err((original_region, shadow, shadow_symbol))
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let new_symbol =
|
||||
self.commit_introduction(ident, exposed_ident_ids, all_ident_ids, region);
|
||||
Ok((new_symbol, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn commit_introduction(
|
||||
&mut self,
|
||||
ident: Ident,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue