mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Represent "able" variables with slices of abilities
This commit is contained in:
parent
0f0678ce73
commit
229548571b
10 changed files with 163 additions and 85 deletions
|
@ -105,7 +105,7 @@ impl OwnedNamedOrAble {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn opt_abilities(&self) -> Option<&[Symbol]> {
|
||||
pub fn opt_abilities(&self) -> Option<&VecSet<Symbol>> {
|
||||
match self {
|
||||
OwnedNamedOrAble::Named(_) => None,
|
||||
OwnedNamedOrAble::Able(av) => Some(&av.abilities),
|
||||
|
@ -127,6 +127,8 @@ pub struct NamedVariable {
|
|||
pub struct AbleVariable {
|
||||
pub variable: Variable,
|
||||
pub name: Lowercase,
|
||||
/// Abilities bound to this type variable.
|
||||
/// INVARIANT: sorted and de-duplicated.
|
||||
pub abilities: VecSet<Symbol>,
|
||||
// NB: there may be multiple occurrences of a variable
|
||||
pub first_seen: Region,
|
||||
|
@ -984,6 +986,11 @@ fn canonicalize_has_clause(
|
|||
|
||||
let var = var_store.fresh();
|
||||
|
||||
let can_abilities = {
|
||||
let mut vec = can_abilities.into_vec();
|
||||
vec.sort();
|
||||
VecSet::from_iter(vec)
|
||||
};
|
||||
introduced_variables.insert_able(var_name, Loc::at(region, var), can_abilities);
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -1044,8 +1044,8 @@ mod test {
|
|||
use roc_region::all::Loc;
|
||||
use roc_types::{
|
||||
subs::{
|
||||
self, Content, Content::*, Descriptor, FlatType, Mark, OptVariable, Rank, Subs,
|
||||
SubsIndex, SubsSlice, Variable,
|
||||
self, Content, Content::*, Descriptor, FlatType, GetSubsSlice, Mark, OptVariable, Rank,
|
||||
Subs, SubsIndex, SubsSlice, Variable,
|
||||
},
|
||||
types::Uls,
|
||||
};
|
||||
|
@ -1107,7 +1107,8 @@ mod test {
|
|||
let mut subs = Subs::new();
|
||||
|
||||
let field_name = SubsIndex::push_new(&mut subs.field_names, "a".into());
|
||||
let var = new_var(&mut subs, FlexAbleVar(Some(field_name), Symbol::UNDERSCORE));
|
||||
let abilities = SubsSlice::extend_new(&mut subs.symbol_names, [Symbol::UNDERSCORE]);
|
||||
let var = new_var(&mut subs, FlexAbleVar(Some(field_name), abilities));
|
||||
|
||||
let mut copied = vec![];
|
||||
|
||||
|
@ -1116,8 +1117,9 @@ mod test {
|
|||
assert_ne!(var, copy);
|
||||
|
||||
match subs.get_content_without_compacting(var) {
|
||||
FlexAbleVar(Some(name), Symbol::UNDERSCORE) => {
|
||||
FlexAbleVar(Some(name), abilities) => {
|
||||
assert_eq!(subs[*name].as_str(), "a");
|
||||
assert_eq!(subs.get_subs_slice(*abilities), [Symbol::UNDERSCORE]);
|
||||
}
|
||||
it => unreachable!("{:?}", it),
|
||||
}
|
||||
|
@ -1128,7 +1130,8 @@ mod test {
|
|||
let mut subs = Subs::new();
|
||||
|
||||
let field_name = SubsIndex::push_new(&mut subs.field_names, "a".into());
|
||||
let var = new_var(&mut subs, RigidAbleVar(field_name, Symbol::UNDERSCORE));
|
||||
let abilities = SubsSlice::extend_new(&mut subs.symbol_names, [Symbol::UNDERSCORE]);
|
||||
let var = new_var(&mut subs, RigidAbleVar(field_name, abilities));
|
||||
|
||||
let mut copied = vec![];
|
||||
|
||||
|
@ -1136,8 +1139,9 @@ mod test {
|
|||
|
||||
assert_ne!(var, copy);
|
||||
match subs.get_content_without_compacting(var) {
|
||||
RigidAbleVar(name, Symbol::UNDERSCORE) => {
|
||||
RigidAbleVar(name, abilities) => {
|
||||
assert_eq!(subs[*name].as_str(), "a");
|
||||
assert_eq!(subs.get_subs_slice(*abilities), [Symbol::UNDERSCORE]);
|
||||
}
|
||||
it => internal_error!("{:?}", it),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue