mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 06:55:15 +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
|
@ -10,7 +10,8 @@ use roc_solve_problem::{
|
|||
};
|
||||
use roc_types::num::NumericRange;
|
||||
use roc_types::subs::{
|
||||
instantiate_rigids, Content, FlatType, GetSubsSlice, Rank, RecordFields, Subs, Variable,
|
||||
instantiate_rigids, Content, FlatType, GetSubsSlice, Rank, RecordFields, Subs, SubsSlice,
|
||||
Variable,
|
||||
};
|
||||
use roc_types::types::{AliasKind, Category, MemberImpl, PatternCategory};
|
||||
use roc_unify::unify::{Env, MustImplementConstraints};
|
||||
|
@ -486,6 +487,7 @@ struct Descend(bool);
|
|||
|
||||
trait DerivableVisitor {
|
||||
const ABILITY: Symbol;
|
||||
const ABILITY_SLICE: SubsSlice<Symbol>;
|
||||
|
||||
#[inline(always)]
|
||||
fn is_derivable_builtin_opaque(_symbol: Symbol) -> bool {
|
||||
|
@ -493,8 +495,9 @@ trait DerivableVisitor {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_flex_able(var: Variable, ability: Symbol) -> Result<(), NotDerivable> {
|
||||
if ability != Self::ABILITY {
|
||||
fn visit_flex_able(var: Variable, abilities: &[Symbol]) -> Result<(), NotDerivable> {
|
||||
// TODO(multi-abilities) flex-able can inherit other abilities
|
||||
if abilities != [Self::ABILITY] {
|
||||
Err(NotDerivable {
|
||||
var,
|
||||
context: NotDerivableContext::NoContext,
|
||||
|
@ -505,8 +508,8 @@ trait DerivableVisitor {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_rigid_able(var: Variable, ability: Symbol) -> Result<(), NotDerivable> {
|
||||
if ability != Self::ABILITY {
|
||||
fn visit_rigid_able(var: Variable, abilities: &[Symbol]) -> Result<(), NotDerivable> {
|
||||
if abilities != [Self::ABILITY] {
|
||||
Err(NotDerivable {
|
||||
var,
|
||||
context: NotDerivableContext::NoContext,
|
||||
|
@ -636,7 +639,7 @@ trait DerivableVisitor {
|
|||
match *content {
|
||||
FlexVar(opt_name) => {
|
||||
// Promote the flex var to be bound to the ability.
|
||||
subs.set_content(var, Content::FlexAbleVar(opt_name, Self::ABILITY));
|
||||
subs.set_content(var, Content::FlexAbleVar(opt_name, Self::ABILITY_SLICE));
|
||||
}
|
||||
RigidVar(_) => {
|
||||
return Err(NotDerivable {
|
||||
|
@ -644,8 +647,12 @@ trait DerivableVisitor {
|
|||
context: NotDerivableContext::NoContext,
|
||||
})
|
||||
}
|
||||
FlexAbleVar(_, ability) => Self::visit_flex_able(var, ability)?,
|
||||
RigidAbleVar(_, ability) => Self::visit_rigid_able(var, ability)?,
|
||||
FlexAbleVar(_, abilities) => {
|
||||
Self::visit_flex_able(var, subs.get_subs_slice(abilities))?
|
||||
}
|
||||
RigidAbleVar(_, abilities) => {
|
||||
Self::visit_rigid_able(var, subs.get_subs_slice(abilities))?
|
||||
}
|
||||
RecursionVar {
|
||||
structure,
|
||||
opt_name: _,
|
||||
|
@ -771,6 +778,7 @@ trait DerivableVisitor {
|
|||
struct DeriveEncoding;
|
||||
impl DerivableVisitor for DeriveEncoding {
|
||||
const ABILITY: Symbol = Symbol::ENCODE_ENCODING;
|
||||
const ABILITY_SLICE: SubsSlice<Symbol> = Subs::AB_ENCODING;
|
||||
|
||||
#[inline(always)]
|
||||
fn is_derivable_builtin_opaque(symbol: Symbol) -> bool {
|
||||
|
@ -849,6 +857,7 @@ impl DerivableVisitor for DeriveEncoding {
|
|||
struct DeriveDecoding;
|
||||
impl DerivableVisitor for DeriveDecoding {
|
||||
const ABILITY: Symbol = Symbol::DECODE_DECODING;
|
||||
const ABILITY_SLICE: SubsSlice<Symbol> = Subs::AB_DECODING;
|
||||
|
||||
#[inline(always)]
|
||||
fn is_derivable_builtin_opaque(symbol: Symbol) -> bool {
|
||||
|
@ -938,6 +947,7 @@ impl DerivableVisitor for DeriveDecoding {
|
|||
struct DeriveHash;
|
||||
impl DerivableVisitor for DeriveHash {
|
||||
const ABILITY: Symbol = Symbol::HASH_HASH_ABILITY;
|
||||
const ABILITY_SLICE: SubsSlice<Symbol> = Subs::AB_HASH;
|
||||
|
||||
#[inline(always)]
|
||||
fn is_derivable_builtin_opaque(symbol: Symbol) -> bool {
|
||||
|
|
|
@ -2601,17 +2601,17 @@ fn type_to_variable<'a>(
|
|||
let copy_var = match opt_abilities {
|
||||
None => helper!(typ),
|
||||
Some(abilities) => {
|
||||
// TODO(abilities)
|
||||
let ability = abilities[0];
|
||||
|
||||
// If this type argument is marked as being bound to an ability, we must
|
||||
// now correctly instantiate it as so.
|
||||
match RegisterVariable::from_type(subs, rank, pools, arena, typ) {
|
||||
RegisterVariable::Direct(var) => {
|
||||
use Content::*;
|
||||
match *subs.get_content_without_compacting(var) {
|
||||
FlexVar(opt_name) => subs
|
||||
.set_content(var, FlexAbleVar(opt_name, ability)),
|
||||
FlexVar(opt_name) => {
|
||||
// TODO(multi-abilities): check run cache
|
||||
let abilities_slice = SubsSlice::extend_new(&mut subs.symbol_names, abilities.iter().copied());
|
||||
subs.set_content(var, FlexAbleVar(opt_name, abilities_slice))
|
||||
},
|
||||
RigidVar(..) => internal_error!("Rigid var in type arg for {:?} - this is a bug in the solver, or our understanding", actual),
|
||||
RigidAbleVar(..) | FlexAbleVar(..) => internal_error!("Able var in type arg for {:?} - this is a bug in the solver, or our understanding", actual),
|
||||
_ => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue