mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
Remove all box references
This commit is contained in:
parent
b5db3f68e1
commit
a8d821bf87
9 changed files with 39 additions and 148 deletions
|
@ -708,22 +708,6 @@ impl<'a> BorrowInfState<'a> {
|
|||
self.own_args_if_param(xs);
|
||||
}
|
||||
|
||||
ExprBox { symbol: x } => {
|
||||
self.own_var(z);
|
||||
|
||||
// if the used symbol is an argument to the current function,
|
||||
// the function must take it as an owned parameter
|
||||
self.own_args_if_param(&[*x]);
|
||||
}
|
||||
|
||||
ExprUnbox { symbol: x } => {
|
||||
// if the boxed value is owned, the box is
|
||||
self.if_is_owned_then_own(*x, z);
|
||||
|
||||
// if the extracted value is owned, the structure must be too
|
||||
self.if_is_owned_then_own(z, *x);
|
||||
}
|
||||
|
||||
ErasedMake { value, callee } => {
|
||||
value.map(|v| {
|
||||
// if the value is owned, the erasure is
|
||||
|
|
|
@ -488,23 +488,6 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
// TODO don't know what the element layout is
|
||||
None
|
||||
}
|
||||
&Expr::ExprBox { symbol } => self.with_sym_layout(symbol, |ctx, _def_line, layout| {
|
||||
let inner = layout;
|
||||
Some(
|
||||
ctx.interner
|
||||
.insert_direct_no_semantic(LayoutRepr::Boxed(inner)),
|
||||
)
|
||||
}),
|
||||
&Expr::ExprUnbox { symbol } => self.with_sym_layout(symbol, |ctx, def_line, layout| {
|
||||
let layout = ctx.resolve(layout);
|
||||
match ctx.interner.get_repr(layout) {
|
||||
LayoutRepr::Boxed(inner) => Some(inner),
|
||||
_ => {
|
||||
ctx.problem(ProblemKind::UnboxNotABox { symbol, def_line });
|
||||
None
|
||||
}
|
||||
}
|
||||
}),
|
||||
&Expr::ErasedMake { value, callee } => Some(self.check_erased_make(value, callee)),
|
||||
&Expr::ErasedLoad { symbol, field } => {
|
||||
Some(self.check_erased_load(symbol, field, target_layout))
|
||||
|
@ -797,7 +780,10 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
if let Some(value) = value {
|
||||
self.with_sym_layout(value, |this, def_line, layout| {
|
||||
let repr = this.interner.get_repr(layout);
|
||||
if !matches!(repr, LayoutRepr::Boxed(_)) {
|
||||
if !matches!(
|
||||
repr,
|
||||
LayoutRepr::Union(UnionLayout::NullableUnwrapped { .. })
|
||||
) {
|
||||
this.problem(ProblemKind::ErasedMakeValueNotBoxed {
|
||||
symbol: value,
|
||||
def_layout: layout,
|
||||
|
@ -835,7 +821,10 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
match field {
|
||||
ErasedField::Value => {
|
||||
let repr = self.interner.get_repr(target_layout);
|
||||
if !matches!(repr, LayoutRepr::Boxed(_)) {
|
||||
if !matches!(
|
||||
repr,
|
||||
LayoutRepr::Union(UnionLayout::NullableUnwrapped { .. })
|
||||
) {
|
||||
self.problem(ProblemKind::ErasedLoadValueNotBoxed {
|
||||
symbol,
|
||||
target_layout,
|
||||
|
|
|
@ -238,7 +238,7 @@ fn specialize_drops_stmt<'a, 'i>(
|
|||
ErasedField::Value => {
|
||||
environment.add_struct_child(*symbol, *binding, 0);
|
||||
}
|
||||
ErasedField::Callee => {
|
||||
ErasedField::Callee | ErasedField::ValuePtr => {
|
||||
// nothing to own
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ use pattern::{from_can_pattern, store_pattern, Pattern};
|
|||
|
||||
pub use literal::{ListLiteralElement, Literal};
|
||||
|
||||
mod boxed;
|
||||
mod decision_tree;
|
||||
mod erased;
|
||||
mod literal;
|
||||
|
@ -1897,14 +1898,6 @@ pub enum Expr<'a> {
|
|||
},
|
||||
EmptyArray,
|
||||
|
||||
ExprBox {
|
||||
symbol: Symbol,
|
||||
},
|
||||
|
||||
ExprUnbox {
|
||||
symbol: Symbol,
|
||||
},
|
||||
|
||||
/// Creates a type-erased value.
|
||||
ErasedMake {
|
||||
/// The erased value. If this is an erased function, the value are the function captures,
|
||||
|
@ -2108,14 +2101,6 @@ impl<'a> Expr<'a> {
|
|||
.text("GetTagId ")
|
||||
.append(symbol_to_doc(alloc, *structure, pretty)),
|
||||
|
||||
ExprBox { symbol, .. } => alloc
|
||||
.text("Box ")
|
||||
.append(symbol_to_doc(alloc, *symbol, pretty)),
|
||||
|
||||
ExprUnbox { symbol, .. } => alloc
|
||||
.text("Unbox ")
|
||||
.append(symbol_to_doc(alloc, *symbol, pretty)),
|
||||
|
||||
ErasedMake { value, callee } => {
|
||||
let value = match value {
|
||||
Some(v) => symbol_to_doc(alloc, *v, pretty),
|
||||
|
@ -2191,24 +2176,6 @@ impl<'a> Expr<'a> {
|
|||
arguments: std::slice::from_ref(symbol),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn expr_box(symbol: &'a Symbol, element_layout: &'a InLayout<'a>) -> Expr<'a> {
|
||||
Expr::Tag {
|
||||
tag_layout: UnionLayout::NonNullableUnwrapped(std::slice::from_ref(element_layout)),
|
||||
tag_id: 0,
|
||||
arguments: std::slice::from_ref(symbol),
|
||||
reuse: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn expr_unbox(symbol: Symbol, element_layout: &'a InLayout<'a>) -> Expr<'a> {
|
||||
Expr::UnionAtIndex {
|
||||
structure: symbol,
|
||||
tag_id: 0,
|
||||
union_layout: UnionLayout::NonNullableUnwrapped(std::slice::from_ref(element_layout)),
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Stmt<'a> {
|
||||
|
@ -5816,7 +5783,7 @@ pub fn with_hole<'a>(
|
|||
_ => unreachable!("invalid layout for a box expression"),
|
||||
};
|
||||
|
||||
let expr = Expr::expr_box(arena.alloc(x), element_layout);
|
||||
let expr = boxed::expr_box(arena.alloc(x), element_layout);
|
||||
|
||||
Stmt::Let(assigned, expr, layout, hole)
|
||||
}
|
||||
|
@ -5824,7 +5791,7 @@ pub fn with_hole<'a>(
|
|||
debug_assert_eq!(arg_symbols.len(), 1);
|
||||
let x = arg_symbols[0];
|
||||
|
||||
let expr = Expr::expr_unbox(x, arena.alloc(layout));
|
||||
let expr = boxed::expr_unbox(x, arena.alloc(layout));
|
||||
|
||||
Stmt::Let(assigned, expr, layout, hole)
|
||||
}
|
||||
|
@ -7867,14 +7834,6 @@ fn substitute_in_expr<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
ExprBox { symbol } => {
|
||||
substitute(subs, *symbol).map(|new_symbol| ExprBox { symbol: new_symbol })
|
||||
}
|
||||
|
||||
ExprUnbox { symbol } => {
|
||||
substitute(subs, *symbol).map(|new_symbol| ExprUnbox { symbol: new_symbol })
|
||||
}
|
||||
|
||||
ErasedMake { value, callee } => {
|
||||
match (
|
||||
value.and_then(|v| substitute(subs, v)),
|
||||
|
@ -10325,7 +10284,7 @@ where
|
|||
|
||||
let field_get_stmt = Stmt::Let(result, field_get_expr, *field, ret_stmt);
|
||||
|
||||
let unbox_expr = Expr::expr_unbox(argument, arena.alloc(interned_unboxed_struct_layout));
|
||||
let unbox_expr = boxed::expr_unbox(argument, arena.alloc(interned_unboxed_struct_layout));
|
||||
|
||||
let unbox_stmt = Stmt::Let(
|
||||
unboxed,
|
||||
|
@ -10427,7 +10386,7 @@ where
|
|||
|
||||
let field_get_stmt = Stmt::Let(result, field_get_expr, *field, ret_stmt);
|
||||
|
||||
let unbox_expr = Expr::expr_unbox(argument, arena.alloc(interned));
|
||||
let unbox_expr = boxed::expr_unbox(argument, arena.alloc(interned));
|
||||
let unbox_stmt = Stmt::Let(unboxed, unbox_expr, interned, arena.alloc(field_get_stmt));
|
||||
|
||||
let proc = Proc {
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::{
|
|||
};
|
||||
|
||||
use super::{
|
||||
boxed::{self, expr_unbox},
|
||||
with_hole, BranchInfo, Call, CallType, CapturedSymbols, Env, ErasedField, Expr, JoinPointId,
|
||||
Param, Procs, Stmt, UpdateModeId,
|
||||
};
|
||||
|
@ -164,13 +165,8 @@ pub fn call_erased_function<'a>(
|
|||
|
||||
// f_value = ErasedLoad(f, .value)
|
||||
let f_value = env.unique_symbol();
|
||||
let let_f_value = index_erased_function(
|
||||
arena,
|
||||
f_value,
|
||||
f,
|
||||
ErasedField::ValuePtr,
|
||||
Layout::OPAQUE_STACK_PTR,
|
||||
);
|
||||
let let_f_value =
|
||||
index_erased_function(arena, f_value, f, ErasedField::ValuePtr, Layout::OPAQUE_PTR);
|
||||
|
||||
let mut build_closure_data_branch = |env: &mut Env, pass_closure| {
|
||||
// f_callee = Cast(f_callee, (..params) -> ret);
|
||||
|
@ -216,7 +212,7 @@ pub fn call_erased_function<'a>(
|
|||
};
|
||||
|
||||
let value_is_null = env.unique_symbol();
|
||||
let let_value_is_null = is_null(env, arena, value_is_null, f_value, Layout::OPAQUE_STACK_PTR);
|
||||
let let_value_is_null = is_null(env, arena, value_is_null, f_value, Layout::OPAQUE_PTR);
|
||||
|
||||
let call_and_jump_on_value = let_value_is_null(
|
||||
//
|
||||
|
@ -348,15 +344,14 @@ pub fn build_erased_function<'a>(
|
|||
let stack_captures = env.unique_symbol();
|
||||
let stack_captures_layout =
|
||||
layout_cache.put_in_direct_no_semantic(LayoutRepr::Struct(layouts));
|
||||
let stack_captures_layout = env.arena.alloc(stack_captures_layout);
|
||||
|
||||
let boxed_captures_layout =
|
||||
layout_cache.put_in_direct_no_semantic(LayoutRepr::Boxed(stack_captures_layout));
|
||||
let boxed_captures_layout = layout_cache
|
||||
.put_in_direct_no_semantic(LayoutRepr::boxed_erased_value(stack_captures_layout));
|
||||
|
||||
let result = Stmt::Let(
|
||||
value.unwrap(),
|
||||
Expr::ExprBox {
|
||||
symbol: stack_captures,
|
||||
},
|
||||
boxed::expr_box(env.arena.alloc(stack_captures), stack_captures_layout),
|
||||
boxed_captures_layout,
|
||||
env.arena.alloc(result),
|
||||
);
|
||||
|
@ -364,7 +359,7 @@ pub fn build_erased_function<'a>(
|
|||
let result = Stmt::Let(
|
||||
stack_captures,
|
||||
Expr::Struct(symbols),
|
||||
stack_captures_layout,
|
||||
*stack_captures_layout,
|
||||
env.arena.alloc(result),
|
||||
);
|
||||
|
||||
|
@ -469,8 +464,9 @@ pub fn unpack_closure_data<'a>(
|
|||
|
||||
let stack_captures_layout =
|
||||
layout_cache.put_in_direct_no_semantic(LayoutRepr::Struct(captures_layouts));
|
||||
let heap_captures_layout =
|
||||
layout_cache.put_in_direct_no_semantic(LayoutRepr::Boxed(stack_captures_layout));
|
||||
let stack_captures_layout = env.arena.alloc(stack_captures_layout);
|
||||
let heap_captures_layout = layout_cache
|
||||
.put_in_direct_no_semantic(LayoutRepr::boxed_erased_value(stack_captures_layout));
|
||||
|
||||
for (i, ((capture, _capture_var), &capture_layout)) in
|
||||
captures.iter().zip(captures_layouts).enumerate().rev()
|
||||
|
@ -489,10 +485,8 @@ pub fn unpack_closure_data<'a>(
|
|||
|
||||
hole = Stmt::Let(
|
||||
stack_captures,
|
||||
Expr::ExprUnbox {
|
||||
symbol: heap_captures,
|
||||
},
|
||||
stack_captures_layout,
|
||||
expr_unbox(heap_captures, stack_captures_layout),
|
||||
*stack_captures_layout,
|
||||
env.arena.alloc(hole),
|
||||
);
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use roc_target::TargetInfo;
|
||||
|
||||
use super::{InLayout, LayoutRepr};
|
||||
|
||||
/// The layout of an erasure.
|
||||
///
|
||||
/// A type-erased value consists of three fields at runtime:
|
||||
|
@ -53,3 +55,12 @@ impl Erased {
|
|||
alloc.text("?Erased")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> LayoutRepr<'a> {
|
||||
pub fn boxed_erased_value(value: &'a InLayout<'a>) -> Self {
|
||||
Self::Union(super::UnionLayout::NullableUnwrapped {
|
||||
nullable_id: true,
|
||||
other_fields: std::slice::from_ref(value),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue