Add Layout::Erased

This commit is contained in:
Ayaz Hafiz 2023-07-02 12:16:14 -05:00
parent 283b9d53d6
commit 7ea85e44d2
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
18 changed files with 58 additions and 14 deletions

View file

@ -1640,6 +1640,7 @@ fn layout_spec_help<'a>(
}, },
FunctionPointer(_) => todo_lambda_erasure!(), FunctionPointer(_) => todo_lambda_erasure!(),
Erased(_) => todo_lambda_erasure!(),
} }
} }

View file

@ -5,7 +5,7 @@ use crate::{
use bumpalo::collections::{CollectIn, Vec}; use bumpalo::collections::{CollectIn, Vec};
use roc_builtins::bitcode::{self, FloatWidth, IntWidth}; use roc_builtins::bitcode::{self, FloatWidth, IntWidth};
use roc_collections::all::MutMap; use roc_collections::all::MutMap;
use roc_error_macros::internal_error; use roc_error_macros::{internal_error, todo_lambda_erasure};
use roc_module::symbol::{Interns, ModuleId, Symbol}; use roc_module::symbol::{Interns, ModuleId, Symbol};
use roc_mono::code_gen_help::{CallerProc, CodeGenHelp, HelperOp}; use roc_mono::code_gen_help::{CallerProc, CodeGenHelp, HelperOp};
use roc_mono::ir::{ use roc_mono::ir::{
@ -3630,7 +3630,8 @@ impl<
} }
LayoutRepr::Union(UnionLayout::NonRecursive(_)) LayoutRepr::Union(UnionLayout::NonRecursive(_))
| LayoutRepr::Builtin(_) | LayoutRepr::Builtin(_)
| LayoutRepr::Struct(_) => { | LayoutRepr::Struct(_)
| LayoutRepr::Erased(_) => {
internal_error!("All primitive values should fit in a single register"); internal_error!("All primitive values should fit in a single register");
} }
} }
@ -4306,6 +4307,8 @@ impl<
dst, dst,
); );
} }
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
} }
} }

View file

@ -6,7 +6,7 @@ use crate::{
use bumpalo::collections::Vec; use bumpalo::collections::Vec;
use roc_builtins::bitcode::{FloatWidth, IntWidth}; use roc_builtins::bitcode::{FloatWidth, IntWidth};
use roc_collections::all::{MutMap, MutSet}; use roc_collections::all::{MutMap, MutSet};
use roc_error_macros::internal_error; use roc_error_macros::{internal_error, todo_lambda_erasure};
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use roc_mono::{ use roc_mono::{
ir::{JoinPointId, Param}, ir::{JoinPointId, Param},
@ -830,6 +830,7 @@ impl<
self.copy_to_stack_offset(buf, size, from_offset, to_offset) self.copy_to_stack_offset(buf, size, from_offset, to_offset)
} }
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
pointer_layouts!() => { pointer_layouts!() => {
// like a 64-bit integer // like a 64-bit integer
debug_assert_eq!(to_offset % 8, 0); debug_assert_eq!(to_offset % 8, 0);

View file

@ -119,7 +119,7 @@ impl<'a> LlvmAlignment<'a> for LayoutRepr<'a> {
.runtime_representation() .runtime_representation()
.llvm_alignment_bytes(interner), .llvm_alignment_bytes(interner),
Builtin(builtin) => builtin.llvm_alignment_bytes(interner), Builtin(builtin) => builtin.llvm_alignment_bytes(interner),
RecursivePointer(_) | Ptr(_) | FunctionPointer(_) => { RecursivePointer(_) | Ptr(_) | FunctionPointer(_) | Erased(_) => {
interner.target_info().ptr_width() as u32 interner.target_info().ptr_width() as u32
} }
} }

View file

@ -8,7 +8,7 @@ use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, Str
use inkwell::{AddressSpace, FloatPredicate, IntPredicate}; use inkwell::{AddressSpace, FloatPredicate, IntPredicate};
use roc_builtins::bitcode; use roc_builtins::bitcode;
use roc_builtins::bitcode::{FloatWidth, IntWidth}; use roc_builtins::bitcode::{FloatWidth, IntWidth};
use roc_error_macros::{internal_error, todo_lambda_erasure}; use roc_error_macros::internal_error;
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use roc_mono::layout::{ use roc_mono::layout::{
Builtin, InLayout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout, Builtin, InLayout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
@ -168,6 +168,8 @@ fn build_eq<'a, 'ctx>(
), ),
LayoutRepr::LambdaSet(_) => unreachable!("cannot compare closures"), LayoutRepr::LambdaSet(_) => unreachable!("cannot compare closures"),
LayoutRepr::FunctionPointer(_) => unreachable!("cannot compare function pointers"),
LayoutRepr::Erased(_) => unreachable!("cannot compare erased types"),
LayoutRepr::Union(union_layout) => build_tag_eq( LayoutRepr::Union(union_layout) => build_tag_eq(
env, env,
@ -225,8 +227,6 @@ fn build_eq<'a, 'ctx>(
field2_cast.into(), field2_cast.into(),
) )
} }
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
} }
} }
@ -401,8 +401,8 @@ fn build_neq<'a, 'ctx>(
unreachable!("recursion pointers should never be compared directly") unreachable!("recursion pointers should never be compared directly")
} }
LayoutRepr::LambdaSet(_) => unreachable!("cannot compare closure"), LayoutRepr::LambdaSet(_) => unreachable!("cannot compare closure"),
LayoutRepr::FunctionPointer(_) => unreachable!("cannot compare function pointers"),
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(), LayoutRepr::Erased(_) => unreachable!("cannot compare erased types"),
} }
} }

View file

@ -50,6 +50,7 @@ pub fn basic_type_from_layout<'a, 'ctx>(
.as_basic_type_enum(), .as_basic_type_enum(),
FunctionPointer(_) => todo_lambda_erasure!(), FunctionPointer(_) => todo_lambda_erasure!(),
Erased(_) => todo_lambda_erasure!(),
Builtin(builtin) => basic_type_from_builtin(env, &builtin), Builtin(builtin) => basic_type_from_builtin(env, &builtin),
} }

View file

@ -388,6 +388,7 @@ fn build_clone<'a, 'ctx>(
) )
} }
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(), LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
} }
} }

View file

@ -626,6 +626,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx>(
lambda_set.runtime_representation(), lambda_set.runtime_representation(),
), ),
FunctionPointer(_) => todo_lambda_erasure!(), FunctionPointer(_) => todo_lambda_erasure!(),
Erased(_) => todo_lambda_erasure!(),
} }
} }

View file

@ -101,6 +101,7 @@ impl WasmLayout {
| LayoutRepr::Ptr(_) | LayoutRepr::Ptr(_)
| LayoutRepr::RecursivePointer(_) => Self::Primitive(PTR_TYPE, PTR_SIZE), | LayoutRepr::RecursivePointer(_) => Self::Primitive(PTR_TYPE, PTR_SIZE),
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(), LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
} }
} }

View file

@ -2122,6 +2122,7 @@ impl<'a> LowLevelCall<'a> {
} }
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(), LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
} }
} }

View file

@ -39,6 +39,7 @@ pub fn eq_generic<'a>(
Union(union_layout) => eq_tag_union(root, ident_ids, ctx, layout_interner, union_layout), Union(union_layout) => eq_tag_union(root, ident_ids, ctx, layout_interner, union_layout),
Ptr(inner_layout) => eq_boxed(root, ident_ids, ctx, layout_interner, inner_layout), Ptr(inner_layout) => eq_boxed(root, ident_ids, ctx, layout_interner, inner_layout),
LambdaSet(_) => unreachable!("`==` is not defined on functions"), LambdaSet(_) => unreachable!("`==` is not defined on functions"),
Erased(_) => unreachable!("`==` is not defined on erased types"),
RecursivePointer(_) => { RecursivePointer(_) => {
unreachable!( unreachable!(
"Can't perform `==` on RecursivePointer. Should have been replaced by a tag union." "Can't perform `==` on RecursivePointer. Should have been replaced by a tag union."

View file

@ -584,6 +584,8 @@ impl<'a> CodeGenHelp<'a> {
LayoutRepr::RecursivePointer(_) => LayoutRepr::Union(ctx.recursive_union.unwrap()), LayoutRepr::RecursivePointer(_) => LayoutRepr::Union(ctx.recursive_union.unwrap()),
LayoutRepr::FunctionPointer(_) => return layout, LayoutRepr::FunctionPointer(_) => return layout,
LayoutRepr::Erased(_) => return layout,
}; };
layout_interner.insert(Layout::new(LayoutWrapper::Direct(repr), semantic)) layout_interner.insert(Layout::new(LayoutWrapper::Direct(repr), semantic))
@ -841,5 +843,6 @@ fn layout_needs_helper_proc<'a>(
LayoutRepr::RecursivePointer(_) => false, LayoutRepr::RecursivePointer(_) => false,
LayoutRepr::Ptr(_) => false, LayoutRepr::Ptr(_) => false,
LayoutRepr::FunctionPointer(_) => false, LayoutRepr::FunctionPointer(_) => false,
LayoutRepr::Erased(_) => true,
} }
} }

View file

@ -2,6 +2,7 @@
use bumpalo::collections::vec::Vec; use bumpalo::collections::vec::Vec;
use bumpalo::collections::CollectIn; use bumpalo::collections::CollectIn;
use roc_error_macros::todo_lambda_erasure;
use roc_module::low_level::{LowLevel, LowLevel::*}; use roc_module::low_level::{LowLevel, LowLevel::*};
use roc_module::symbol::{IdentIds, Symbol}; use roc_module::symbol::{IdentIds, Symbol};
use roc_target::PtrWidth; use roc_target::PtrWidth;
@ -231,6 +232,9 @@ pub fn refcount_generic<'a>(
structure, structure,
) )
} }
LayoutRepr::Erased(_) => {
todo_lambda_erasure!()
}
LayoutRepr::RecursivePointer(_) => unreachable!( LayoutRepr::RecursivePointer(_) => unreachable!(
"We should never call a refcounting helper on a RecursivePointer layout directly" "We should never call a refcounting helper on a RecursivePointer layout directly"
), ),

View file

@ -10225,6 +10225,7 @@ where
/* do nothing, we've already generated for this type through the Union(_) */ /* do nothing, we've already generated for this type through the Union(_) */
} }
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(), LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
} }
} }

View file

@ -26,8 +26,11 @@ use std::collections::HashMap;
use std::hash::Hash; use std::hash::Hash;
use ven_pretty::{DocAllocator, DocBuilder}; use ven_pretty::{DocAllocator, DocBuilder};
mod erased;
mod intern; mod intern;
mod semantic; mod semantic;
pub use erased::Erased;
pub use intern::{ pub use intern::{
GlobalLayoutInterner, InLayout, LayoutInterner, STLayoutInterner, TLLayoutInterner, GlobalLayoutInterner, InLayout, LayoutInterner, STLayoutInterner, TLLayoutInterner,
}; };
@ -684,8 +687,10 @@ pub enum LayoutRepr<'a> {
Union(UnionLayout<'a>), Union(UnionLayout<'a>),
LambdaSet(LambdaSet<'a>), LambdaSet(LambdaSet<'a>),
RecursivePointer(InLayout<'a>), RecursivePointer(InLayout<'a>),
/// Only used for erased functions. /// Only used in erased functions.
FunctionPointer(FunctionPointer<'a>), FunctionPointer(FunctionPointer<'a>),
/// The layout of an erasure.
Erased(Erased),
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
@ -2623,6 +2628,7 @@ impl<'a> LayoutRepr<'a> {
pub const F64: Self = LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)); pub const F64: Self = LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64));
pub const DEC: Self = LayoutRepr::Builtin(Builtin::Decimal); pub const DEC: Self = LayoutRepr::Builtin(Builtin::Decimal);
pub const STR: Self = LayoutRepr::Builtin(Builtin::Str); pub const STR: Self = LayoutRepr::Builtin(Builtin::Str);
<<<<<<< HEAD
pub const OPAQUE_PTR: Self = LayoutRepr::Ptr(Layout::VOID); pub const OPAQUE_PTR: Self = LayoutRepr::Ptr(Layout::VOID);
pub const ERASED: Self = Self::struct_(&[ pub const ERASED: Self = Self::struct_(&[
// .value // .value
@ -2632,6 +2638,10 @@ impl<'a> LayoutRepr<'a> {
// .refcounter // .refcounter
Layout::OPAQUE_PTR, Layout::OPAQUE_PTR,
]); ]);
=======
pub const OPAQUE_PTR: Self = LayoutRepr::Boxed(Layout::VOID);
pub const ERASED: Self = LayoutRepr::Erased(Erased);
>>>>>>> 0ff7ccbb9 (Add Layout::Erased)
pub const fn struct_(field_layouts: &'a [InLayout<'a>]) -> Self { pub const fn struct_(field_layouts: &'a [InLayout<'a>]) -> Self {
Self::Struct(field_layouts) Self::Struct(field_layouts)
@ -2677,6 +2687,7 @@ impl<'a> LayoutRepr<'a> {
// We cannot memcpy pointers, because then we would have the same pointer in multiple places! // We cannot memcpy pointers, because then we would have the same pointer in multiple places!
false false
} }
Erased(e) => e.safe_to_memcpy(),
FunctionPointer(..) => true, FunctionPointer(..) => true,
} }
} }
@ -2766,6 +2777,7 @@ impl<'a> LayoutRepr<'a> {
RecursivePointer(_) | Ptr(_) | FunctionPointer(_) => { RecursivePointer(_) | Ptr(_) | FunctionPointer(_) => {
interner.target_info().ptr_width() as u32 interner.target_info().ptr_width() as u32
} }
Erased(e) => e.stack_size_without_alignment(interner.target_info()),
} }
} }
@ -2820,6 +2832,7 @@ impl<'a> LayoutRepr<'a> {
RecursivePointer(_) | Ptr(_) | FunctionPointer(_) => { RecursivePointer(_) | Ptr(_) | FunctionPointer(_) => {
interner.target_info().ptr_width() as u32 interner.target_info().ptr_width() as u32
} }
Erased(e) => e.alignment_bytes(interner.target_info()),
} }
} }
@ -2842,6 +2855,7 @@ impl<'a> LayoutRepr<'a> {
} }
Ptr(inner) => interner.get_repr(*inner).alignment_bytes(interner), Ptr(inner) => interner.get_repr(*inner).alignment_bytes(interner),
FunctionPointer(_) => ptr_width, FunctionPointer(_) => ptr_width,
Erased(e) => e.allocation_alignment_bytes(interner.target_info()),
} }
} }
@ -2916,6 +2930,7 @@ impl<'a> LayoutRepr<'a> {
false false
} }
FunctionPointer(_) => false, FunctionPointer(_) => false,
Erased(e) => e.is_refcounted(),
} }
} }
@ -2980,6 +2995,9 @@ impl<'a> LayoutRepr<'a> {
FunctionPointer(_) => { FunctionPointer(_) => {
// drop through // drop through
} }
Erased(_) => {
// erasures are just pointers, so they do not vary
}
} }
} }

View file

@ -356,6 +356,7 @@ pub trait LayoutInterner<'a>: Sized {
.append(self.to_doc(inner, alloc, seen_rec, parens)) .append(self.to_doc(inner, alloc, seen_rec, parens))
.append(")"), .append(")"),
FunctionPointer(fp) => fp.to_doc(alloc, self, seen_rec, parens), FunctionPointer(fp) => fp.to_doc(alloc, self, seen_rec, parens),
Erased(e) => e.to_doc(alloc),
} }
} }
@ -1131,6 +1132,7 @@ mod reify {
ret: reify_layout(arena, interner, slot, ret), ret: reify_layout(arena, interner, slot, ret),
}) })
} }
LayoutRepr::Erased(e) => LayoutRepr::Erased(e),
} }
} }
@ -1404,7 +1406,7 @@ mod equiv {
pub mod dbg_deep { pub mod dbg_deep {
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use crate::layout::{Builtin, LambdaSet, LayoutRepr, UnionLayout}; use crate::layout::{Builtin, Erased, LambdaSet, LayoutRepr, UnionLayout};
use super::{InLayout, LayoutInterner}; use super::{InLayout, LayoutInterner};
@ -1462,6 +1464,7 @@ pub mod dbg_deep {
.field("args", &fp.args) .field("args", &fp.args)
.field("ret", &fp.ret) .field("ret", &fp.ret)
.finish(), .finish(),
LayoutRepr::Erased(Erased) => f.debug_struct("?Erased").finish(),
} }
} }
} }
@ -1574,7 +1577,7 @@ pub mod dbg_deep {
pub mod dbg_stable { pub mod dbg_stable {
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use crate::layout::{Builtin, LambdaSet, LayoutRepr, SemanticRepr, UnionLayout}; use crate::layout::{Builtin, Erased, LambdaSet, LayoutRepr, SemanticRepr, UnionLayout};
use super::{InLayout, LayoutInterner}; use super::{InLayout, LayoutInterner};
@ -1640,6 +1643,7 @@ pub mod dbg_stable {
.field("args", &fp.args) .field("args", &fp.args)
.field("ret", &fp.ret) .field("ret", &fp.ret)
.finish(), .finish(),
LayoutRepr::Erased(Erased) => f.debug_struct("?Erased").finish(),
} }
} }
} }

View file

@ -2101,6 +2101,7 @@ fn tag_union_type_from_layout<'a>(
unreachable!(); unreachable!();
} }
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(), LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
} }
} }

View file

@ -537,7 +537,9 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
LayoutRepr::Ptr(_) => { LayoutRepr::Ptr(_) => {
unreachable!("Ptr will never be visible to users") unreachable!("Ptr will never be visible to users")
} }
LayoutRepr::LambdaSet(_) | LayoutRepr::FunctionPointer(_) => OPAQUE_FUNCTION, LayoutRepr::LambdaSet(_) | LayoutRepr::FunctionPointer(_) | LayoutRepr::Erased(_) => {
OPAQUE_FUNCTION
}
}; };
apply_newtypes(env, newtype_containers.into_bump_slice(), expr) apply_newtypes(env, newtype_containers.into_bump_slice(), expr)
@ -575,7 +577,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
let raw_content = env.subs.get_content_without_compacting(raw_var); let raw_content = env.subs.get_content_without_compacting(raw_var);
let expr = match (raw_content, layout) { let expr = match (raw_content, layout) {
(Content::Structure(FlatType::Func(_, _, _)), _) | (_, LayoutRepr::LambdaSet(_) | LayoutRepr::FunctionPointer(_)) => { (Content::Structure(FlatType::Func(_, _, _)), _) | (_, LayoutRepr::LambdaSet(_) | LayoutRepr::FunctionPointer(_) | LayoutRepr::Erased(_)) => {
OPAQUE_FUNCTION OPAQUE_FUNCTION
} }
(_, LayoutRepr::Builtin(Builtin::Bool)) => { (_, LayoutRepr::Builtin(Builtin::Bool)) => {