Remove all box references

This commit is contained in:
Ayaz Hafiz 2023-07-12 15:50:00 -05:00
parent b5db3f68e1
commit a8d821bf87
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
9 changed files with 39 additions and 148 deletions

View file

@ -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

View file

@ -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,

View file

@ -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
}
}

View file

@ -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 {

View file

@ -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),
);

View file

@ -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),
})
}
}