Move DeriveBuiltin to derive_key

This commit is contained in:
Ayaz Hafiz 2022-08-01 14:03:47 -05:00
parent 6f06a59cdf
commit 05d8bca0fb
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
4 changed files with 99 additions and 92 deletions

View file

@ -57,11 +57,23 @@ pub enum Derived {
Key(DeriveKey),
}
/// The builtin ability member to derive.
#[derive(Clone, Copy)]
pub enum DeriveBuiltin {
ToEncoder,
}
impl Derived {
pub fn encoding(subs: &Subs, var: Variable) -> Result<Self, DeriveError> {
match encoding::FlatEncodable::from_var(subs, var)? {
pub fn builtin(
builtin: DeriveBuiltin,
subs: &Subs,
var: Variable,
) -> Result<Self, DeriveError> {
match builtin {
DeriveBuiltin::ToEncoder => match encoding::FlatEncodable::from_var(subs, var)? {
FlatEncodable::Immediate(imm) => Ok(Derived::Immediate(imm)),
FlatEncodable::Key(repr) => Ok(Derived::Key(DeriveKey::ToEncoder(repr))),
},
}
}
}

View file

@ -12,7 +12,7 @@ use roc_debug_flags::dbg_do;
#[cfg(debug_assertions)]
use roc_debug_flags::ROC_TRACE_COMPACTION;
use roc_derive::SharedDerivedModule;
use roc_derive_key::{DeriveError, DeriveKey};
use roc_derive_key::{DeriveBuiltin, DeriveError, DeriveKey};
use roc_error_macros::{internal_error, todo_abilities};
use roc_module::symbol::{ModuleId, Symbol};
use roc_types::{
@ -657,7 +657,7 @@ fn make_specialization_decision<P: Phase>(
Structure(_) | Alias(_, _, _, _) => {
// This is a structural type, find the name of the derived ability function it
// should use.
match roc_derive_key::Derived::encoding(subs, var) {
match roc_derive_key::Derived::builtin(DeriveBuiltin::ToEncoder, subs, var) {
Ok(derived) => match derived {
roc_derive_key::Derived::Immediate(imm) => {
SpecializeDecision::Specialize(Immediate(imm))

View file

@ -5,11 +5,14 @@
#![allow(non_snake_case)]
use insta::assert_snapshot;
use pretty_assertions::assert_eq;
use crate::{test_hash_eq, test_hash_neq, util::derive_test, v};
use crate::{
test_hash_eq, test_hash_neq,
util::{check_immediate, derive_test},
v,
};
use roc_derive::synth_var;
use roc_derive_key::Derived;
use roc_derive_key::DeriveBuiltin::ToEncoder;
use roc_module::{ident::TagName, symbol::Symbol};
use roc_types::{
subs::{
@ -19,40 +22,11 @@ use roc_types::{
types::{AliasKind, RecordField},
};
fn check_key<S1, S2>(eq: bool, synth1: S1, synth2: S2)
where
S1: FnOnce(&mut Subs) -> Variable,
S2: FnOnce(&mut Subs) -> Variable,
{
let mut subs = Subs::new();
let var1 = synth1(&mut subs);
let var2 = synth2(&mut subs);
let key1 = Derived::encoding(&subs, var1);
let key2 = Derived::encoding(&subs, var2);
if eq {
assert_eq!(key1, key2);
} else {
assert_ne!(key1, key2);
}
}
fn check_immediate<S>(synth: S, immediate: Symbol)
where
S: FnOnce(&mut Subs) -> Variable,
{
let mut subs = Subs::new();
let var = synth(&mut subs);
let key = Derived::encoding(&subs, var);
assert_eq!(key, Ok(Derived::Immediate(immediate)));
}
// {{{ hash tests
test_hash_eq! {
ToEncoder,
same_record:
v!({ a: v!(U8), }), v!({ a: v!(U8), })
same_record_fields_diff_types:
@ -104,6 +78,8 @@ test_hash_eq! {
}
test_hash_neq! {
ToEncoder,
different_record_fields:
v!({ a: v!(U8), }), v!({ b: v!(U8), })
record_empty_vs_nonempty:
@ -133,24 +109,22 @@ test_hash_neq! {
#[test]
fn immediates() {
check_immediate(v!(U8), Symbol::ENCODE_U8);
check_immediate(v!(U16), Symbol::ENCODE_U16);
check_immediate(v!(U32), Symbol::ENCODE_U32);
check_immediate(v!(U64), Symbol::ENCODE_U64);
check_immediate(v!(U128), Symbol::ENCODE_U128);
check_immediate(v!(I8), Symbol::ENCODE_I8);
check_immediate(v!(I16), Symbol::ENCODE_I16);
check_immediate(v!(I32), Symbol::ENCODE_I32);
check_immediate(v!(I64), Symbol::ENCODE_I64);
check_immediate(v!(I128), Symbol::ENCODE_I128);
check_immediate(v!(DEC), Symbol::ENCODE_DEC);
check_immediate(v!(F32), Symbol::ENCODE_F32);
check_immediate(v!(F64), Symbol::ENCODE_F64);
check_immediate(v!(STR), Symbol::ENCODE_STRING);
check_immediate(ToEncoder, v!(U8), Symbol::ENCODE_U8);
check_immediate(ToEncoder, v!(U16), Symbol::ENCODE_U16);
check_immediate(ToEncoder, v!(U32), Symbol::ENCODE_U32);
check_immediate(ToEncoder, v!(U64), Symbol::ENCODE_U64);
check_immediate(ToEncoder, v!(U128), Symbol::ENCODE_U128);
check_immediate(ToEncoder, v!(I8), Symbol::ENCODE_I8);
check_immediate(ToEncoder, v!(I16), Symbol::ENCODE_I16);
check_immediate(ToEncoder, v!(I32), Symbol::ENCODE_I32);
check_immediate(ToEncoder, v!(I64), Symbol::ENCODE_I64);
check_immediate(ToEncoder, v!(I128), Symbol::ENCODE_I128);
check_immediate(ToEncoder, v!(DEC), Symbol::ENCODE_DEC);
check_immediate(ToEncoder, v!(F32), Symbol::ENCODE_F32);
check_immediate(ToEncoder, v!(F64), Symbol::ENCODE_F64);
check_immediate(ToEncoder, v!(STR), Symbol::ENCODE_STRING);
}
use crate::util::DeriveBuiltin::ToEncoder;
#[test]
fn empty_record() {
derive_test(ToEncoder, v!(EMPTY_RECORD), |golden| {

View file

@ -18,9 +18,9 @@ use roc_collections::VecSet;
use roc_constrain::expr::constrain_decls;
use roc_debug_flags::dbg_do;
use roc_derive::DerivedModule;
use roc_derive_key::{DeriveKey, Derived};
use roc_derive_key::{DeriveBuiltin, DeriveKey, Derived};
use roc_load_internal::file::{add_imports, default_aliases, LoadedModule, Threading};
use roc_module::symbol::{IdentIds, Interns, ModuleId};
use roc_module::symbol::{IdentIds, Interns, ModuleId, Symbol};
use roc_region::all::LineInfo;
use roc_reporting::report::{type_problem, RocDocAllocator};
use roc_types::{
@ -30,30 +30,22 @@ use roc_types::{
const DERIVED_MODULE: ModuleId = ModuleId::DERIVED_SYNTH;
#[derive(Clone, Copy)]
pub(crate) enum DeriveBuiltin {
ToEncoder,
}
impl DeriveBuiltin {
fn module_source_and_path(&self) -> (ModuleId, &'static str, PathBuf) {
fn module_source_and_path(builtin: DeriveBuiltin) -> (ModuleId, &'static str, PathBuf) {
use roc_builtins::roc::module_source;
let repo_root =
std::env::var("ROC_WORKSPACE_DIR").expect("are you running with `cargo test`?");
let repo_root = std::env::var("ROC_WORKSPACE_DIR").expect("are you running with `cargo test`?");
let builtins_path = PathBuf::from(repo_root)
.join("compiler")
.join("builtins")
.join("roc");
match self {
match builtin {
DeriveBuiltin::ToEncoder => (
ModuleId::ENCODE,
module_source(ModuleId::ENCODE),
builtins_path.join("Encode.roc"),
),
}
}
}
/// Writing out the types into content is inconvenient, so we use a DSL for testing.
@ -133,26 +125,57 @@ macro_rules! v {
};
}
pub(crate) fn check_key<S1, S2>(builtin: DeriveBuiltin, eq: bool, synth1: S1, synth2: S2)
where
S1: FnOnce(&mut Subs) -> Variable,
S2: FnOnce(&mut Subs) -> Variable,
{
let mut subs = Subs::new();
let var1 = synth1(&mut subs);
let var2 = synth2(&mut subs);
let key1 = Derived::builtin(builtin, &subs, var1);
let key2 = Derived::builtin(builtin, &subs, var2);
if eq {
assert_eq!(key1, key2);
} else {
assert_ne!(key1, key2);
}
}
#[macro_export]
macro_rules! test_hash_eq {
($($name:ident: $synth1:expr, $synth2:expr)*) => {$(
($builtin:expr, $($name:ident: $synth1:expr, $synth2:expr)*) => {$(
#[test]
fn $name() {
check_key(true, $synth1, $synth2)
$crate::util::check_key($builtin,true, $synth1, $synth2)
}
)*};
}
#[macro_export]
macro_rules! test_hash_neq {
($($name:ident: $synth1:expr, $synth2:expr)*) => {$(
($builtin:expr, $($name:ident: $synth1:expr, $synth2:expr)*) => {$(
#[test]
fn $name() {
check_key(false, $synth1, $synth2)
$crate::util::check_key($builtin, false, $synth1, $synth2)
}
)*};
}
pub(crate) fn check_immediate<S>(builtin: DeriveBuiltin, synth: S, immediate: Symbol)
where
S: FnOnce(&mut Subs) -> Variable,
{
let mut subs = Subs::new();
let var = synth(&mut subs);
let key = Derived::builtin(builtin, &subs, var);
assert_eq!(key, Ok(Derived::Immediate(immediate)));
}
#[allow(clippy::too_many_arguments)]
fn assemble_derived_golden(
subs: &mut Subs,
@ -331,21 +354,19 @@ fn check_derived_typechecks_and_golden(
check_golden(&golden)
}
fn get_key(derive: DeriveBuiltin, subs: &Subs, var: Variable) -> DeriveKey {
match derive {
DeriveBuiltin::ToEncoder => match Derived::encoding(subs, var) {
fn get_key(builtin: DeriveBuiltin, subs: &Subs, var: Variable) -> DeriveKey {
match Derived::builtin(builtin, subs, var) {
Ok(Derived::Key(key)) => key,
_ => unreachable!(),
},
}
}
pub(crate) fn derive_test<S>(derive: DeriveBuiltin, synth_input: S, check_golden: impl Fn(&str))
pub(crate) fn derive_test<S>(builtin: DeriveBuiltin, synth_input: S, check_golden: impl Fn(&str))
where
S: FnOnce(&mut Subs) -> Variable,
{
let arena = Bump::new();
let (builtin_module, source, path) = derive.module_source_and_path();
let (builtin_module, source, path) = module_source_and_path(builtin);
let target_info = roc_target::TargetInfo::default_x86_64();
let LoadedModule {
@ -369,7 +390,7 @@ where
let mut subs = Subs::new();
let ident_ids = IdentIds::default();
let source_var = synth_input(&mut subs);
let key = get_key(derive, &subs, source_var);
let key = get_key(builtin, &subs, source_var);
let mut derived_module = unsafe { DerivedModule::from_components(subs, ident_ids) };