mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
check inside a lambda set for whether it is reference counted
This commit is contained in:
parent
73ffce0baa
commit
334253f47f
7 changed files with 34 additions and 31 deletions
|
@ -2872,8 +2872,7 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
|||
DecRef(symbol) => {
|
||||
let (value, layout) = scope.load_symbol_and_layout(symbol);
|
||||
|
||||
let lay = layout_interner.get_repr(layout);
|
||||
match lay {
|
||||
match layout_interner.get_repr(layout) {
|
||||
LayoutRepr::Builtin(Builtin::Str) => todo!(),
|
||||
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
||||
debug_assert!(value.is_struct_value());
|
||||
|
@ -2883,9 +2882,9 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
|||
build_list::decref(env, value.into_struct_value(), alignment);
|
||||
}
|
||||
|
||||
_ if lay.is_refcounted() => {
|
||||
other_layout if other_layout.is_refcounted(layout_interner) => {
|
||||
if value.is_pointer_value() {
|
||||
let value_ptr = match lay {
|
||||
let value_ptr = match other_layout {
|
||||
LayoutRepr::Union(union_layout)
|
||||
if union_layout
|
||||
.stores_tag_id_in_pointer(env.target_info) =>
|
||||
|
|
|
@ -1246,7 +1246,7 @@ enum DecOrReuse {
|
|||
fn fields_need_no_refcounting(interner: &STLayoutInterner, field_layouts: &[InLayout]) -> bool {
|
||||
!field_layouts.iter().any(|x| {
|
||||
let x = interner.get_repr(*x);
|
||||
x.is_refcounted() || x.contains_refcounted(interner)
|
||||
x.is_refcounted(interner) || x.contains_refcounted(interner)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1763,7 +1763,7 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
|
|||
// if none of the fields are or contain anything refcounted, just move on
|
||||
if !field_layouts.iter().any(|x| {
|
||||
let x = layout_interner.get_repr(*x);
|
||||
x.is_refcounted() || x.contains_refcounted(layout_interner)
|
||||
x.is_refcounted(layout_interner) || x.contains_refcounted(layout_interner)
|
||||
}) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -365,7 +365,7 @@ impl<'a> LowLevelCall<'a> {
|
|||
);
|
||||
|
||||
// Increment refcount
|
||||
if self.ret_layout_raw.is_refcounted() {
|
||||
if self.ret_layout_raw.is_refcounted(backend.layout_interner) {
|
||||
let inc_fn = backend.get_refcount_fn_index(self.ret_layout, HelperOp::Inc);
|
||||
backend.code_builder.get_local(elem_local);
|
||||
backend.code_builder.i32_const(1);
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::hash::Hash;
|
|||
use crate::ir::{
|
||||
Expr, HigherOrderLowLevel, JoinPointId, Param, PassedFunction, Proc, ProcLayout, Stmt,
|
||||
};
|
||||
use crate::layout::{InLayout, LayoutInterner, LayoutRepr, STLayoutInterner};
|
||||
use crate::layout::{InLayout, LayoutInterner, STLayoutInterner};
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
use roc_collections::all::{MutMap, MutSet};
|
||||
|
@ -30,8 +30,8 @@ impl Ownership {
|
|||
|
||||
/// For reference-counted types (lists, (big) strings, recursive tags), owning a value
|
||||
/// means incrementing its reference count. Hence, we prefer borrowing for these types
|
||||
fn from_layout(layout: &LayoutRepr) -> Self {
|
||||
match layout.is_refcounted() {
|
||||
fn from_layout(interner: &STLayoutInterner<'_>, layout: InLayout<'_>) -> Self {
|
||||
match interner.is_refcounted(layout) {
|
||||
true => Ownership::Borrowed,
|
||||
false => Ownership::Owned,
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ impl<'a> ParamMap<'a> {
|
|||
) -> &'a [Param<'a>] {
|
||||
Vec::from_iter_in(
|
||||
ps.iter().map(|p| Param {
|
||||
ownership: Ownership::from_layout(&interner.get_repr(p.layout)),
|
||||
ownership: Ownership::from_layout(interner, p.layout),
|
||||
layout: p.layout,
|
||||
symbol: p.symbol,
|
||||
}),
|
||||
|
@ -282,7 +282,7 @@ impl<'a> ParamMap<'a> {
|
|||
) -> &'a [Param<'a>] {
|
||||
Vec::from_iter_in(
|
||||
ps.iter().map(|(layout, symbol)| Param {
|
||||
ownership: Ownership::from_layout(&interner.get_repr(*layout)),
|
||||
ownership: Ownership::from_layout(interner, *layout),
|
||||
layout: *layout,
|
||||
symbol: *symbol,
|
||||
}),
|
||||
|
|
|
@ -1046,23 +1046,22 @@ fn refcount_list<'a>(
|
|||
let modify_list = modify_refcount_stmt(Pointer::ToData(data_pointer));
|
||||
|
||||
let is_relevant_op = ctx.op.is_dec() || ctx.op.is_inc();
|
||||
let modify_elems_and_list =
|
||||
if is_relevant_op && layout_interner.get_repr(elem_layout).is_refcounted() {
|
||||
refcount_list_elems(
|
||||
root,
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
elem_layout,
|
||||
LAYOUT_UNIT,
|
||||
ptr_layout,
|
||||
len,
|
||||
first_element_pointer,
|
||||
modify_list,
|
||||
)
|
||||
} else {
|
||||
modify_list
|
||||
};
|
||||
let modify_elems_and_list = if is_relevant_op && layout_interner.is_refcounted(elem_layout) {
|
||||
refcount_list_elems(
|
||||
root,
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
elem_layout,
|
||||
LAYOUT_UNIT,
|
||||
ptr_layout,
|
||||
len,
|
||||
first_element_pointer,
|
||||
modify_list,
|
||||
)
|
||||
} else {
|
||||
modify_list
|
||||
};
|
||||
|
||||
//
|
||||
// JoinPoint for slice vs list
|
||||
|
|
|
@ -2843,7 +2843,10 @@ impl<'a> LayoutRepr<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_refcounted(&self) -> bool {
|
||||
pub fn is_refcounted<I>(&self, interner: &I) -> bool
|
||||
where
|
||||
I: LayoutInterner<'a>,
|
||||
{
|
||||
use self::Builtin::*;
|
||||
use LayoutRepr::*;
|
||||
|
||||
|
@ -2858,6 +2861,8 @@ impl<'a> LayoutRepr<'a> {
|
|||
|
||||
Erased(_) => true,
|
||||
|
||||
LambdaSet(lambda_set) => interner.is_refcounted(lambda_set.runtime_representation()),
|
||||
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
}
|
||||
|
||||
fn is_refcounted(&self, layout: InLayout<'a>) -> bool {
|
||||
self.get_repr(layout).is_refcounted()
|
||||
self.get_repr(layout).is_refcounted(self)
|
||||
}
|
||||
|
||||
fn is_nullable(&self, layout: InLayout<'a>) -> bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue