Fast-path for determining ability member impls for builtin opaques

This commit is contained in:
Ayaz Hafiz 2023-03-20 16:05:10 -04:00
parent 297a571b34
commit e6094df69b
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
8 changed files with 182 additions and 60 deletions

View file

@ -78,24 +78,11 @@ impl FlatDecodable {
//
FlatType::Func(..) => Err(Underivable),
},
Content::Alias(sym, _, real_var, _) => match sym {
Symbol::BOOL_BOOL => Ok(Immediate(Symbol::DECODE_BOOL)),
Symbol::NUM_U8 | Symbol::NUM_UNSIGNED8 => Ok(Immediate(Symbol::DECODE_U8)),
Symbol::NUM_U16 | Symbol::NUM_UNSIGNED16 => Ok(Immediate(Symbol::DECODE_U16)),
Symbol::NUM_U32 | Symbol::NUM_UNSIGNED32 => Ok(Immediate(Symbol::DECODE_U32)),
Symbol::NUM_U64 | Symbol::NUM_UNSIGNED64 => Ok(Immediate(Symbol::DECODE_U64)),
Symbol::NUM_U128 | Symbol::NUM_UNSIGNED128 => Ok(Immediate(Symbol::DECODE_U128)),
Symbol::NUM_I8 | Symbol::NUM_SIGNED8 => Ok(Immediate(Symbol::DECODE_I8)),
Symbol::NUM_I16 | Symbol::NUM_SIGNED16 => Ok(Immediate(Symbol::DECODE_I16)),
Symbol::NUM_I32 | Symbol::NUM_SIGNED32 => Ok(Immediate(Symbol::DECODE_I32)),
Symbol::NUM_I64 | Symbol::NUM_SIGNED64 => Ok(Immediate(Symbol::DECODE_I64)),
Symbol::NUM_I128 | Symbol::NUM_SIGNED128 => Ok(Immediate(Symbol::DECODE_I128)),
Symbol::NUM_DEC | Symbol::NUM_DECIMAL => Ok(Immediate(Symbol::DECODE_DEC)),
Symbol::NUM_F32 | Symbol::NUM_BINARY32 => Ok(Immediate(Symbol::DECODE_F32)),
Symbol::NUM_F64 | Symbol::NUM_BINARY64 => Ok(Immediate(Symbol::DECODE_F64)),
Content::Alias(sym, _, real_var, _) => match from_builtin_symbol(sym) {
Some(lambda) => Ok(lambda),
// NB: I believe it is okay to unwrap opaques here because derivers are only used
// by the backend, and the backend treats opaques like structural aliases.
_ => Self::from_var(subs, real_var),
None => Self::from_var(subs, real_var),
},
Content::RangedNumber(range) => {
Self::from_var(subs, range.default_compilation_variable())
@ -110,4 +97,29 @@ impl FlatDecodable {
Content::LambdaSet(_) => Err(Underivable),
}
}
pub(crate) fn from_builtin_symbol(symbol: Symbol) -> Result<FlatDecodable, DeriveError> {
from_builtin_symbol(symbol).ok_or(DeriveError::Underivable)
}
}
const fn from_builtin_symbol(symbol: Symbol) -> Option<FlatDecodable> {
use FlatDecodable::*;
match symbol {
Symbol::BOOL_BOOL => Some(Immediate(Symbol::DECODE_BOOL)),
Symbol::NUM_U8 | Symbol::NUM_UNSIGNED8 => Some(Immediate(Symbol::DECODE_U8)),
Symbol::NUM_U16 | Symbol::NUM_UNSIGNED16 => Some(Immediate(Symbol::DECODE_U16)),
Symbol::NUM_U32 | Symbol::NUM_UNSIGNED32 => Some(Immediate(Symbol::DECODE_U32)),
Symbol::NUM_U64 | Symbol::NUM_UNSIGNED64 => Some(Immediate(Symbol::DECODE_U64)),
Symbol::NUM_U128 | Symbol::NUM_UNSIGNED128 => Some(Immediate(Symbol::DECODE_U128)),
Symbol::NUM_I8 | Symbol::NUM_SIGNED8 => Some(Immediate(Symbol::DECODE_I8)),
Symbol::NUM_I16 | Symbol::NUM_SIGNED16 => Some(Immediate(Symbol::DECODE_I16)),
Symbol::NUM_I32 | Symbol::NUM_SIGNED32 => Some(Immediate(Symbol::DECODE_I32)),
Symbol::NUM_I64 | Symbol::NUM_SIGNED64 => Some(Immediate(Symbol::DECODE_I64)),
Symbol::NUM_I128 | Symbol::NUM_SIGNED128 => Some(Immediate(Symbol::DECODE_I128)),
Symbol::NUM_DEC | Symbol::NUM_DECIMAL => Some(Immediate(Symbol::DECODE_DEC)),
Symbol::NUM_F32 | Symbol::NUM_BINARY32 => Some(Immediate(Symbol::DECODE_F32)),
Symbol::NUM_F64 | Symbol::NUM_BINARY64 => Some(Immediate(Symbol::DECODE_F64)),
_ => None,
}
}

View file

@ -112,22 +112,8 @@ impl FlatEncodable {
//
FlatType::Func(..) => Err(Underivable),
},
Content::Alias(sym, _, real_var, _) => match sym {
Symbol::BOOL_BOOL => Ok(Immediate(Symbol::ENCODE_BOOL)),
Symbol::NUM_U8 | Symbol::NUM_UNSIGNED8 => Ok(Immediate(Symbol::ENCODE_U8)),
Symbol::NUM_U16 | Symbol::NUM_UNSIGNED16 => Ok(Immediate(Symbol::ENCODE_U16)),
Symbol::NUM_U32 | Symbol::NUM_UNSIGNED32 => Ok(Immediate(Symbol::ENCODE_U32)),
Symbol::NUM_U64 | Symbol::NUM_UNSIGNED64 => Ok(Immediate(Symbol::ENCODE_U64)),
Symbol::NUM_U128 | Symbol::NUM_UNSIGNED128 => Ok(Immediate(Symbol::ENCODE_U128)),
Symbol::NUM_I8 | Symbol::NUM_SIGNED8 => Ok(Immediate(Symbol::ENCODE_I8)),
Symbol::NUM_I16 | Symbol::NUM_SIGNED16 => Ok(Immediate(Symbol::ENCODE_I16)),
Symbol::NUM_I32 | Symbol::NUM_SIGNED32 => Ok(Immediate(Symbol::ENCODE_I32)),
Symbol::NUM_I64 | Symbol::NUM_SIGNED64 => Ok(Immediate(Symbol::ENCODE_I64)),
Symbol::NUM_I128 | Symbol::NUM_SIGNED128 => Ok(Immediate(Symbol::ENCODE_I128)),
Symbol::NUM_DEC | Symbol::NUM_DECIMAL => Ok(Immediate(Symbol::ENCODE_DEC)),
Symbol::NUM_F32 | Symbol::NUM_BINARY32 => Ok(Immediate(Symbol::ENCODE_F32)),
Symbol::NUM_F64 | Symbol::NUM_BINARY64 => Ok(Immediate(Symbol::ENCODE_F64)),
Symbol::NUM_NAT | Symbol::NUM_NATURAL => Err(Underivable),
Content::Alias(sym, _, real_var, _) => match from_builtin_symbol(sym) {
Some(lambda) => Ok(lambda),
// TODO: I believe it is okay to unwrap opaques here because derivers are only used
// by the backend, and the backend treats opaques like structural aliases.
_ => Self::from_var(subs, real_var),
@ -145,4 +131,30 @@ impl FlatEncodable {
Content::LambdaSet(_) => Err(Underivable),
}
}
pub(crate) fn from_builtin_symbol(symbol: Symbol) -> Result<FlatEncodable, DeriveError> {
from_builtin_symbol(symbol).ok_or(DeriveError::Underivable)
}
}
const fn from_builtin_symbol(symbol: Symbol) -> Option<FlatEncodable> {
use FlatEncodable::*;
match symbol {
Symbol::BOOL_BOOL => Some(Immediate(Symbol::ENCODE_BOOL)),
Symbol::NUM_U8 | Symbol::NUM_UNSIGNED8 => Some(Immediate(Symbol::ENCODE_U8)),
Symbol::NUM_U16 | Symbol::NUM_UNSIGNED16 => Some(Immediate(Symbol::ENCODE_U16)),
Symbol::NUM_U32 | Symbol::NUM_UNSIGNED32 => Some(Immediate(Symbol::ENCODE_U32)),
Symbol::NUM_U64 | Symbol::NUM_UNSIGNED64 => Some(Immediate(Symbol::ENCODE_U64)),
Symbol::NUM_U128 | Symbol::NUM_UNSIGNED128 => Some(Immediate(Symbol::ENCODE_U128)),
Symbol::NUM_I8 | Symbol::NUM_SIGNED8 => Some(Immediate(Symbol::ENCODE_I8)),
Symbol::NUM_I16 | Symbol::NUM_SIGNED16 => Some(Immediate(Symbol::ENCODE_I16)),
Symbol::NUM_I32 | Symbol::NUM_SIGNED32 => Some(Immediate(Symbol::ENCODE_I32)),
Symbol::NUM_I64 | Symbol::NUM_SIGNED64 => Some(Immediate(Symbol::ENCODE_I64)),
Symbol::NUM_I128 | Symbol::NUM_SIGNED128 => Some(Immediate(Symbol::ENCODE_I128)),
Symbol::NUM_DEC | Symbol::NUM_DECIMAL => Some(Immediate(Symbol::ENCODE_DEC)),
Symbol::NUM_F32 | Symbol::NUM_BINARY32 => Some(Immediate(Symbol::ENCODE_F32)),
Symbol::NUM_F64 | Symbol::NUM_BINARY64 => Some(Immediate(Symbol::ENCODE_F64)),
Symbol::NUM_NAT | Symbol::NUM_NATURAL => None,
_ => None,
}
}

View file

@ -143,6 +143,10 @@ impl FlatHash {
Content::LambdaSet(_) => Err(Underivable),
}
}
pub fn from_builtin_symbol(symbol: Symbol) -> Result<FlatHash, DeriveError> {
builtin_symbol_to_hash_lambda(symbol).ok_or(DeriveError::Underivable)
}
}
const fn builtin_symbol_to_hash_lambda(symbol: Symbol) -> Option<FlatHash> {

View file

@ -52,7 +52,7 @@ impl DeriveKey {
}
}
#[derive(Hash, PartialEq, Eq, Debug)]
#[derive(Hash, Clone, PartialEq, Eq, Debug)]
pub enum Derived {
/// If a derived implementation name is well-known ahead-of-time, we can inline the symbol
/// directly rather than associating a key for an implementation to be made later on.
@ -123,4 +123,34 @@ impl Derived {
}
}
}
pub fn builtin_with_builtin_symbol(
builtin: DeriveBuiltin,
symbol: Symbol,
) -> Result<Self, DeriveError> {
match builtin {
DeriveBuiltin::ToEncoder => match encoding::FlatEncodable::from_builtin_symbol(symbol)?
{
FlatEncodable::Immediate(imm) => Ok(Derived::Immediate(imm)),
FlatEncodable::Key(repr) => Ok(Derived::Key(DeriveKey::ToEncoder(repr))),
},
DeriveBuiltin::Decoder => match decoding::FlatDecodable::from_builtin_symbol(symbol)? {
FlatDecodable::Immediate(imm) => Ok(Derived::Immediate(imm)),
FlatDecodable::Key(repr) => Ok(Derived::Key(DeriveKey::Decoder(repr))),
},
DeriveBuiltin::Hash => match hash::FlatHash::from_builtin_symbol(symbol)? {
FlatHash::SingleLambdaSetImmediate(imm) => {
Ok(Derived::SingleLambdaSetImmediate(imm))
}
FlatHash::Key(repr) => Ok(Derived::Key(DeriveKey::Hash(repr))),
},
DeriveBuiltin::IsEq => {
// If obligation checking passes, we always lower derived implementations of `isEq`
// to the `Eq` low-level, to be fulfilled by the backends.
Ok(Derived::SingleLambdaSetImmediate(
Symbol::BOOL_STRUCTURAL_EQ,
))
}
}
}
}