mirror of
https://github.com/roc-lang/roc.git
synced 2025-11-25 05:33:14 +00:00
Add Layout::Erased
This commit is contained in:
parent
283b9d53d6
commit
7ea85e44d2
18 changed files with 58 additions and 14 deletions
|
|
@ -1640,6 +1640,7 @@ fn layout_spec_help<'a>(
|
|||
},
|
||||
|
||||
FunctionPointer(_) => todo_lambda_erasure!(),
|
||||
Erased(_) => todo_lambda_erasure!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
use bumpalo::collections::{CollectIn, Vec};
|
||||
use roc_builtins::bitcode::{self, FloatWidth, IntWidth};
|
||||
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_mono::code_gen_help::{CallerProc, CodeGenHelp, HelperOp};
|
||||
use roc_mono::ir::{
|
||||
|
|
@ -3630,7 +3630,8 @@ impl<
|
|||
}
|
||||
LayoutRepr::Union(UnionLayout::NonRecursive(_))
|
||||
| LayoutRepr::Builtin(_)
|
||||
| LayoutRepr::Struct(_) => {
|
||||
| LayoutRepr::Struct(_)
|
||||
| LayoutRepr::Erased(_) => {
|
||||
internal_error!("All primitive values should fit in a single register");
|
||||
}
|
||||
}
|
||||
|
|
@ -4306,6 +4307,8 @@ impl<
|
|||
dst,
|
||||
);
|
||||
}
|
||||
|
||||
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
use bumpalo::collections::Vec;
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
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_mono::{
|
||||
ir::{JoinPointId, Param},
|
||||
|
|
@ -830,6 +830,7 @@ impl<
|
|||
|
||||
self.copy_to_stack_offset(buf, size, from_offset, to_offset)
|
||||
}
|
||||
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
|
||||
pointer_layouts!() => {
|
||||
// like a 64-bit integer
|
||||
debug_assert_eq!(to_offset % 8, 0);
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ impl<'a> LlvmAlignment<'a> for LayoutRepr<'a> {
|
|||
.runtime_representation()
|
||||
.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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, Str
|
|||
use inkwell::{AddressSpace, FloatPredicate, IntPredicate};
|
||||
use roc_builtins::bitcode;
|
||||
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_mono::layout::{
|
||||
Builtin, InLayout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
|
||||
|
|
@ -168,6 +168,8 @@ fn build_eq<'a, 'ctx>(
|
|||
),
|
||||
|
||||
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(
|
||||
env,
|
||||
|
|
@ -225,8 +227,6 @@ fn build_eq<'a, 'ctx>(
|
|||
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")
|
||||
}
|
||||
LayoutRepr::LambdaSet(_) => unreachable!("cannot compare closure"),
|
||||
|
||||
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
|
||||
LayoutRepr::FunctionPointer(_) => unreachable!("cannot compare function pointers"),
|
||||
LayoutRepr::Erased(_) => unreachable!("cannot compare erased types"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ pub fn basic_type_from_layout<'a, 'ctx>(
|
|||
.as_basic_type_enum(),
|
||||
|
||||
FunctionPointer(_) => todo_lambda_erasure!(),
|
||||
Erased(_) => todo_lambda_erasure!(),
|
||||
|
||||
Builtin(builtin) => basic_type_from_builtin(env, &builtin),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -388,6 +388,7 @@ fn build_clone<'a, 'ctx>(
|
|||
)
|
||||
}
|
||||
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
|
||||
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -626,6 +626,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx>(
|
|||
lambda_set.runtime_representation(),
|
||||
),
|
||||
FunctionPointer(_) => todo_lambda_erasure!(),
|
||||
Erased(_) => todo_lambda_erasure!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ impl WasmLayout {
|
|||
| LayoutRepr::Ptr(_)
|
||||
| LayoutRepr::RecursivePointer(_) => Self::Primitive(PTR_TYPE, PTR_SIZE),
|
||||
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
|
||||
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2122,6 +2122,7 @@ impl<'a> LowLevelCall<'a> {
|
|||
}
|
||||
|
||||
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
|
||||
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ pub fn eq_generic<'a>(
|
|||
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),
|
||||
LambdaSet(_) => unreachable!("`==` is not defined on functions"),
|
||||
Erased(_) => unreachable!("`==` is not defined on erased types"),
|
||||
RecursivePointer(_) => {
|
||||
unreachable!(
|
||||
"Can't perform `==` on RecursivePointer. Should have been replaced by a tag union."
|
||||
|
|
|
|||
|
|
@ -584,6 +584,8 @@ impl<'a> CodeGenHelp<'a> {
|
|||
LayoutRepr::RecursivePointer(_) => LayoutRepr::Union(ctx.recursive_union.unwrap()),
|
||||
|
||||
LayoutRepr::FunctionPointer(_) => return layout,
|
||||
|
||||
LayoutRepr::Erased(_) => return layout,
|
||||
};
|
||||
|
||||
layout_interner.insert(Layout::new(LayoutWrapper::Direct(repr), semantic))
|
||||
|
|
@ -841,5 +843,6 @@ fn layout_needs_helper_proc<'a>(
|
|||
LayoutRepr::RecursivePointer(_) => false,
|
||||
LayoutRepr::Ptr(_) => false,
|
||||
LayoutRepr::FunctionPointer(_) => false,
|
||||
LayoutRepr::Erased(_) => true,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use bumpalo::collections::vec::Vec;
|
||||
use bumpalo::collections::CollectIn;
|
||||
use roc_error_macros::todo_lambda_erasure;
|
||||
use roc_module::low_level::{LowLevel, LowLevel::*};
|
||||
use roc_module::symbol::{IdentIds, Symbol};
|
||||
use roc_target::PtrWidth;
|
||||
|
|
@ -231,6 +232,9 @@ pub fn refcount_generic<'a>(
|
|||
structure,
|
||||
)
|
||||
}
|
||||
LayoutRepr::Erased(_) => {
|
||||
todo_lambda_erasure!()
|
||||
}
|
||||
LayoutRepr::RecursivePointer(_) => unreachable!(
|
||||
"We should never call a refcounting helper on a RecursivePointer layout directly"
|
||||
),
|
||||
|
|
|
|||
|
|
@ -10225,6 +10225,7 @@ where
|
|||
/* do nothing, we've already generated for this type through the Union(_) */
|
||||
}
|
||||
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
|
||||
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,11 @@ use std::collections::HashMap;
|
|||
use std::hash::Hash;
|
||||
use ven_pretty::{DocAllocator, DocBuilder};
|
||||
|
||||
mod erased;
|
||||
mod intern;
|
||||
mod semantic;
|
||||
|
||||
pub use erased::Erased;
|
||||
pub use intern::{
|
||||
GlobalLayoutInterner, InLayout, LayoutInterner, STLayoutInterner, TLLayoutInterner,
|
||||
};
|
||||
|
|
@ -684,8 +687,10 @@ pub enum LayoutRepr<'a> {
|
|||
Union(UnionLayout<'a>),
|
||||
LambdaSet(LambdaSet<'a>),
|
||||
RecursivePointer(InLayout<'a>),
|
||||
/// Only used for erased functions.
|
||||
/// Only used in erased functions.
|
||||
FunctionPointer(FunctionPointer<'a>),
|
||||
/// The layout of an erasure.
|
||||
Erased(Erased),
|
||||
}
|
||||
|
||||
#[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 DEC: Self = LayoutRepr::Builtin(Builtin::Decimal);
|
||||
pub const STR: Self = LayoutRepr::Builtin(Builtin::Str);
|
||||
<<<<<<< HEAD
|
||||
pub const OPAQUE_PTR: Self = LayoutRepr::Ptr(Layout::VOID);
|
||||
pub const ERASED: Self = Self::struct_(&[
|
||||
// .value
|
||||
|
|
@ -2632,6 +2638,10 @@ impl<'a> LayoutRepr<'a> {
|
|||
// .refcounter
|
||||
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 {
|
||||
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!
|
||||
false
|
||||
}
|
||||
Erased(e) => e.safe_to_memcpy(),
|
||||
FunctionPointer(..) => true,
|
||||
}
|
||||
}
|
||||
|
|
@ -2766,6 +2777,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
RecursivePointer(_) | Ptr(_) | FunctionPointer(_) => {
|
||||
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(_) => {
|
||||
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),
|
||||
FunctionPointer(_) => ptr_width,
|
||||
Erased(e) => e.allocation_alignment_bytes(interner.target_info()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2916,6 +2930,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
false
|
||||
}
|
||||
FunctionPointer(_) => false,
|
||||
Erased(e) => e.is_refcounted(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2980,6 +2995,9 @@ impl<'a> LayoutRepr<'a> {
|
|||
FunctionPointer(_) => {
|
||||
// drop through
|
||||
}
|
||||
Erased(_) => {
|
||||
// erasures are just pointers, so they do not vary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
.append(self.to_doc(inner, alloc, seen_rec, parens))
|
||||
.append(")"),
|
||||
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),
|
||||
})
|
||||
}
|
||||
LayoutRepr::Erased(e) => LayoutRepr::Erased(e),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1404,7 +1406,7 @@ mod equiv {
|
|||
pub mod dbg_deep {
|
||||
use roc_module::symbol::Symbol;
|
||||
|
||||
use crate::layout::{Builtin, LambdaSet, LayoutRepr, UnionLayout};
|
||||
use crate::layout::{Builtin, Erased, LambdaSet, LayoutRepr, UnionLayout};
|
||||
|
||||
use super::{InLayout, LayoutInterner};
|
||||
|
||||
|
|
@ -1462,6 +1464,7 @@ pub mod dbg_deep {
|
|||
.field("args", &fp.args)
|
||||
.field("ret", &fp.ret)
|
||||
.finish(),
|
||||
LayoutRepr::Erased(Erased) => f.debug_struct("?Erased").finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1574,7 +1577,7 @@ pub mod dbg_deep {
|
|||
pub mod dbg_stable {
|
||||
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};
|
||||
|
||||
|
|
@ -1640,6 +1643,7 @@ pub mod dbg_stable {
|
|||
.field("args", &fp.args)
|
||||
.field("ret", &fp.ret)
|
||||
.finish(),
|
||||
LayoutRepr::Erased(Erased) => f.debug_struct("?Erased").finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2101,6 +2101,7 @@ fn tag_union_type_from_layout<'a>(
|
|||
unreachable!();
|
||||
}
|
||||
LayoutRepr::FunctionPointer(_) => todo_lambda_erasure!(),
|
||||
LayoutRepr::Erased(_) => todo_lambda_erasure!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -537,7 +537,9 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
|||
LayoutRepr::Ptr(_) => {
|
||||
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)
|
||||
|
|
@ -575,7 +577,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
|||
let raw_content = env.subs.get_content_without_compacting(raw_var);
|
||||
|
||||
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
|
||||
}
|
||||
(_, LayoutRepr::Builtin(Builtin::Bool)) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue