mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-20 15:27:45 +03:00
Intern the lambda set representation
This commit is contained in:
parent
1e49622b61
commit
95765bcb1e
@ -2,8 +2,8 @@
|
||||
|
||||
use crate::layout::{
|
||||
self, Builtin, CapturesNiche, ClosureCallOptions, ClosureRepresentation, EnumDispatch,
|
||||
LambdaName, LambdaSet, Layout, LayoutCache, LayoutProblem, RawFunctionLayout, STLayoutInterner,
|
||||
TagIdIntType, UnionLayout, WrappedVariant,
|
||||
LambdaName, LambdaSet, Layout, LayoutCache, LayoutInterner, LayoutProblem, RawFunctionLayout,
|
||||
STLayoutInterner, TagIdIntType, UnionLayout, WrappedVariant,
|
||||
};
|
||||
use bumpalo::collections::{CollectIn, Vec};
|
||||
use bumpalo::Bump;
|
||||
@ -1097,7 +1097,12 @@ impl<'a> Procs<'a> {
|
||||
.raw_from_var(env.arena, annotation, env.subs)
|
||||
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
||||
|
||||
let top_level = ProcLayout::from_raw(env.arena, raw_layout, name.captures_niche());
|
||||
let top_level = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
raw_layout,
|
||||
name.captures_niche(),
|
||||
);
|
||||
|
||||
// anonymous functions cannot reference themselves, therefore cannot be tail-recursive
|
||||
// EXCEPT when the closure conversion makes it tail-recursive.
|
||||
@ -2829,10 +2834,19 @@ fn specialize_suspended<'a>(
|
||||
Err(SpecializeFailure {
|
||||
attempted_layout, ..
|
||||
}) => {
|
||||
let proc = generate_runtime_error_function(env, name.name(), attempted_layout);
|
||||
let proc = generate_runtime_error_function(
|
||||
env,
|
||||
layout_cache,
|
||||
name.name(),
|
||||
attempted_layout,
|
||||
);
|
||||
|
||||
let top_level =
|
||||
ProcLayout::from_raw(env.arena, attempted_layout, CapturesNiche::no_niche());
|
||||
let top_level = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
attempted_layout,
|
||||
CapturesNiche::no_niche(),
|
||||
);
|
||||
|
||||
procs
|
||||
.specialized
|
||||
@ -2978,7 +2992,12 @@ fn specialize_external_help<'a>(
|
||||
|
||||
match specialization_result {
|
||||
Ok((proc, layout)) => {
|
||||
let top_level = ProcLayout::from_raw(env.arena, layout, proc.name.captures_niche());
|
||||
let top_level = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
layout,
|
||||
proc.name.captures_niche(),
|
||||
);
|
||||
|
||||
if procs.is_module_thunk(name.name()) {
|
||||
debug_assert!(top_level.arguments.is_empty());
|
||||
@ -2989,10 +3008,15 @@ fn specialize_external_help<'a>(
|
||||
.insert_specialized(name.name(), top_level, proc);
|
||||
}
|
||||
Err(SpecializeFailure { attempted_layout }) => {
|
||||
let proc = generate_runtime_error_function(env, name.name(), attempted_layout);
|
||||
let proc =
|
||||
generate_runtime_error_function(env, layout_cache, name.name(), attempted_layout);
|
||||
|
||||
let top_level =
|
||||
ProcLayout::from_raw(env.arena, attempted_layout, proc.name.captures_niche());
|
||||
let top_level = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
attempted_layout,
|
||||
proc.name.captures_niche(),
|
||||
);
|
||||
|
||||
procs
|
||||
.specialized
|
||||
@ -3003,6 +3027,7 @@ fn specialize_external_help<'a>(
|
||||
|
||||
fn generate_runtime_error_function<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
layout_cache: &LayoutCache<'a>,
|
||||
name: Symbol,
|
||||
layout: RawFunctionLayout<'a>,
|
||||
) -> Proc<'a> {
|
||||
@ -3026,7 +3051,8 @@ fn generate_runtime_error_function<'a>(
|
||||
|
||||
let (args, ret_layout) = match layout {
|
||||
RawFunctionLayout::Function(arg_layouts, lambda_set, ret_layout) => {
|
||||
let real_arg_layouts = lambda_set.extend_argument_list(env.arena, arg_layouts);
|
||||
let real_arg_layouts =
|
||||
lambda_set.extend_argument_list(env.arena, &layout_cache.interner, arg_layouts);
|
||||
let mut args = Vec::with_capacity_in(real_arg_layouts.len(), env.arena);
|
||||
|
||||
for arg in arg_layouts {
|
||||
@ -3177,6 +3203,7 @@ fn specialize_proc_help<'a>(
|
||||
|
||||
let body = match_on_lambda_set(
|
||||
env,
|
||||
layout_cache,
|
||||
procs,
|
||||
lambda_set,
|
||||
Symbol::ARG_CLOSURE,
|
||||
@ -3225,8 +3252,12 @@ fn specialize_proc_help<'a>(
|
||||
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
||||
};
|
||||
|
||||
let top_level =
|
||||
ProcLayout::from_raw(env.arena, layout, CapturesNiche::no_niche());
|
||||
let top_level = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
layout,
|
||||
CapturesNiche::no_niche(),
|
||||
);
|
||||
|
||||
procs.specialized.insert_specialized(name, top_level, proc);
|
||||
|
||||
@ -3304,7 +3335,9 @@ fn specialize_proc_help<'a>(
|
||||
.unwrap_or(symbol)
|
||||
};
|
||||
|
||||
match closure_layout.layout_for_member_with_lambda_name(lambda_name) {
|
||||
match closure_layout
|
||||
.layout_for_member_with_lambda_name(&layout_cache.interner, lambda_name)
|
||||
{
|
||||
ClosureRepresentation::Union {
|
||||
alphabetic_order_fields: field_layouts,
|
||||
union_layout,
|
||||
@ -3775,12 +3808,13 @@ impl<'a> ProcLayout<'a> {
|
||||
|
||||
pub fn from_raw(
|
||||
arena: &'a Bump,
|
||||
interner: &LayoutInterner<'a>,
|
||||
raw: RawFunctionLayout<'a>,
|
||||
captures_niche: CapturesNiche<'a>,
|
||||
) -> Self {
|
||||
match raw {
|
||||
RawFunctionLayout::Function(arguments, lambda_set, result) => {
|
||||
let arguments = lambda_set.extend_argument_list(arena, arguments);
|
||||
let arguments = lambda_set.extend_argument_list(arena, interner, arguments);
|
||||
ProcLayout::new(arena, arguments, captures_niche, *result)
|
||||
}
|
||||
RawFunctionLayout::ZeroArgumentThunk(result) => {
|
||||
@ -5036,6 +5070,7 @@ pub fn with_hole<'a>(
|
||||
|
||||
result = match_on_lambda_set(
|
||||
env,
|
||||
layout_cache,
|
||||
procs,
|
||||
lambda_set,
|
||||
closure_data_symbol,
|
||||
@ -5077,6 +5112,7 @@ pub fn with_hole<'a>(
|
||||
|
||||
result = match_on_lambda_set(
|
||||
env,
|
||||
layout_cache,
|
||||
procs,
|
||||
lambda_set,
|
||||
closure_data_symbol,
|
||||
@ -5133,6 +5169,7 @@ pub fn with_hole<'a>(
|
||||
|
||||
result = match_on_lambda_set(
|
||||
env,
|
||||
layout_cache,
|
||||
procs,
|
||||
lambda_set,
|
||||
closure_data_symbol,
|
||||
@ -5246,7 +5283,7 @@ pub fn with_hole<'a>(
|
||||
|
||||
// NB: I don't think the top_level here can have a captures niche?
|
||||
let top_level_capture_niche = CapturesNiche::no_niche();
|
||||
let top_level = ProcLayout::from_raw(env.arena, closure_data_layout, top_level_capture_niche);
|
||||
let top_level = ProcLayout::from_raw(env.arena, &layout_cache.interner, closure_data_layout, top_level_capture_niche);
|
||||
|
||||
let arena = env.arena;
|
||||
|
||||
@ -5487,7 +5524,7 @@ where
|
||||
let lambda_set_layout = Layout::LambdaSet(lambda_set);
|
||||
let symbols = symbols.into_iter();
|
||||
|
||||
let result = match lambda_set.layout_for_member_with_lambda_name(name) {
|
||||
let result = match lambda_set.layout_for_member_with_lambda_name(&layout_cache.interner, name) {
|
||||
ClosureRepresentation::Union {
|
||||
tag_id,
|
||||
alphabetic_order_fields: field_layouts,
|
||||
@ -7548,8 +7585,12 @@ fn specialize_symbol<'a>(
|
||||
};
|
||||
|
||||
let raw = RawFunctionLayout::ZeroArgumentThunk(layout);
|
||||
let top_level =
|
||||
ProcLayout::from_raw(env.arena, raw, CapturesNiche::no_niche());
|
||||
let top_level = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
raw,
|
||||
CapturesNiche::no_niche(),
|
||||
);
|
||||
|
||||
procs.insert_passed_by_name(
|
||||
env,
|
||||
@ -7563,8 +7604,12 @@ fn specialize_symbol<'a>(
|
||||
} else {
|
||||
// Imported symbol, so it must have no captures niche (since
|
||||
// top-levels can't capture)
|
||||
let top_level =
|
||||
ProcLayout::from_raw(env.arena, raw, CapturesNiche::no_niche());
|
||||
let top_level = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
raw,
|
||||
CapturesNiche::no_niche(),
|
||||
);
|
||||
procs.insert_passed_by_name(
|
||||
env,
|
||||
arg_var,
|
||||
@ -7629,6 +7674,7 @@ fn specialize_symbol<'a>(
|
||||
// define the function pointer
|
||||
let function_ptr_layout = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
res_layout,
|
||||
lambda_name.captures_niche(),
|
||||
);
|
||||
@ -7682,6 +7728,7 @@ fn specialize_symbol<'a>(
|
||||
// define the function pointer
|
||||
let function_ptr_layout = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
res_layout,
|
||||
lambda_name.captures_niche(),
|
||||
);
|
||||
@ -7911,6 +7958,7 @@ fn call_by_name<'a>(
|
||||
|
||||
let result = match_on_lambda_set(
|
||||
env,
|
||||
layout_cache,
|
||||
procs,
|
||||
lambda_set,
|
||||
closure_data_symbol,
|
||||
@ -8027,7 +8075,8 @@ fn call_by_name_help<'a>(
|
||||
// afterwards, we MUST make sure the number of arguments in the layout matches the
|
||||
// number of arguments actually passed.
|
||||
let top_level_layout = {
|
||||
let argument_layouts = lambda_set.extend_argument_list(env.arena, argument_layouts);
|
||||
let argument_layouts =
|
||||
lambda_set.extend_argument_list(env.arena, &layout_cache.interner, argument_layouts);
|
||||
ProcLayout::new(
|
||||
env.arena,
|
||||
argument_layouts,
|
||||
@ -8210,6 +8259,7 @@ fn call_by_name_help<'a>(
|
||||
let proc_name = proc.name;
|
||||
let function_layout = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
layout,
|
||||
proc_name.captures_niche(),
|
||||
);
|
||||
@ -8237,6 +8287,7 @@ fn call_by_name_help<'a>(
|
||||
Err(SpecializeFailure { attempted_layout }) => {
|
||||
let proc = generate_runtime_error_function(
|
||||
env,
|
||||
layout_cache,
|
||||
proc_name.name(),
|
||||
attempted_layout,
|
||||
);
|
||||
@ -8244,6 +8295,7 @@ fn call_by_name_help<'a>(
|
||||
let proc_name = proc.name;
|
||||
let function_layout = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
attempted_layout,
|
||||
proc_name.captures_niche(),
|
||||
);
|
||||
@ -8380,6 +8432,7 @@ fn call_by_name_module_thunk<'a>(
|
||||
Err(SpecializeFailure { attempted_layout }) => {
|
||||
let proc = generate_runtime_error_function(
|
||||
env,
|
||||
layout_cache,
|
||||
proc_name,
|
||||
attempted_layout,
|
||||
);
|
||||
@ -8478,6 +8531,7 @@ fn call_specialized_proc<'a>(
|
||||
|
||||
let new_hole = match_on_lambda_set(
|
||||
env,
|
||||
layout_cache,
|
||||
procs,
|
||||
lambda_set,
|
||||
closure_data_symbol,
|
||||
@ -9405,7 +9459,7 @@ fn lowlevel_match_on_lambda_set<'a, ToLowLevelCall>(
|
||||
where
|
||||
ToLowLevelCall: Fn(ToLowLevelCallArguments<'a>) -> Call<'a> + Copy,
|
||||
{
|
||||
match lambda_set.call_by_name_options() {
|
||||
match lambda_set.call_by_name_options(&layout_cache.interner) {
|
||||
ClosureCallOptions::Void => empty_lambda_set_error(),
|
||||
ClosureCallOptions::Union(union_layout) => {
|
||||
let closure_tag_id_symbol = env.unique_symbol();
|
||||
@ -9594,6 +9648,7 @@ fn empty_lambda_set_error() -> Stmt<'static> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn match_on_lambda_set<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
layout_cache: &LayoutCache<'a>,
|
||||
procs: &mut Procs<'a>,
|
||||
lambda_set: LambdaSet<'a>,
|
||||
closure_data_symbol: Symbol,
|
||||
@ -9603,13 +9658,14 @@ fn match_on_lambda_set<'a>(
|
||||
assigned: Symbol,
|
||||
hole: &'a Stmt<'a>,
|
||||
) -> Stmt<'a> {
|
||||
match lambda_set.call_by_name_options() {
|
||||
match lambda_set.call_by_name_options(&layout_cache.interner) {
|
||||
ClosureCallOptions::Void => empty_lambda_set_error(),
|
||||
ClosureCallOptions::Union(union_layout) => {
|
||||
let closure_tag_id_symbol = env.unique_symbol();
|
||||
|
||||
let result = union_lambda_set_to_switch(
|
||||
env,
|
||||
layout_cache,
|
||||
lambda_set,
|
||||
closure_tag_id_symbol,
|
||||
union_layout.tag_id_layout(),
|
||||
@ -9646,9 +9702,14 @@ fn match_on_lambda_set<'a>(
|
||||
let name = env.unique_symbol();
|
||||
let function_layout =
|
||||
RawFunctionLayout::Function(argument_layouts, lambda_set, return_layout);
|
||||
let proc = generate_runtime_error_function(env, name, function_layout);
|
||||
let top_level =
|
||||
ProcLayout::from_raw(env.arena, function_layout, CapturesNiche::no_niche());
|
||||
let proc =
|
||||
generate_runtime_error_function(env, layout_cache, name, function_layout);
|
||||
let top_level = ProcLayout::from_raw(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
function_layout,
|
||||
CapturesNiche::no_niche(),
|
||||
);
|
||||
|
||||
procs.specialized.insert_specialized(name, top_level, proc);
|
||||
LambdaName::no_niche(name)
|
||||
@ -9665,6 +9726,7 @@ fn match_on_lambda_set<'a>(
|
||||
|
||||
union_lambda_set_branch_help(
|
||||
env,
|
||||
layout_cache,
|
||||
function_symbol,
|
||||
closure_info,
|
||||
argument_symbols,
|
||||
@ -9687,6 +9749,7 @@ fn match_on_lambda_set<'a>(
|
||||
|
||||
union_lambda_set_branch_help(
|
||||
env,
|
||||
layout_cache,
|
||||
function_symbol,
|
||||
closure_info,
|
||||
argument_symbols,
|
||||
@ -9734,6 +9797,7 @@ fn match_on_lambda_set<'a>(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn union_lambda_set_to_switch<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
layout_cache: &LayoutCache<'a>,
|
||||
lambda_set: LambdaSet<'a>,
|
||||
closure_tag_id_symbol: Symbol,
|
||||
closure_tag_id_layout: Layout<'a>,
|
||||
@ -9768,6 +9832,7 @@ fn union_lambda_set_to_switch<'a>(
|
||||
|
||||
let stmt = union_lambda_set_branch(
|
||||
env,
|
||||
layout_cache,
|
||||
join_point_id,
|
||||
lambda_name,
|
||||
closure_info,
|
||||
@ -9809,6 +9874,7 @@ fn union_lambda_set_to_switch<'a>(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn union_lambda_set_branch<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
layout_cache: &LayoutCache<'a>,
|
||||
join_point_id: JoinPointId,
|
||||
lambda_name: LambdaName<'a>,
|
||||
closure_info: ClosureInfo<'a>,
|
||||
@ -9822,6 +9888,7 @@ fn union_lambda_set_branch<'a>(
|
||||
|
||||
union_lambda_set_branch_help(
|
||||
env,
|
||||
layout_cache,
|
||||
lambda_name,
|
||||
closure_info,
|
||||
argument_symbols_slice,
|
||||
@ -9845,6 +9912,7 @@ enum ClosureInfo<'a> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn union_lambda_set_branch_help<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
layout_cache: &LayoutCache<'a>,
|
||||
lambda_name: LambdaName<'a>,
|
||||
closure_info: ClosureInfo<'a>,
|
||||
argument_symbols_slice: &'a [Symbol],
|
||||
@ -9858,8 +9926,11 @@ fn union_lambda_set_branch_help<'a>(
|
||||
lambda_set,
|
||||
closure_data_symbol,
|
||||
} => {
|
||||
let argument_layouts =
|
||||
lambda_set.extend_argument_list(env.arena, argument_layouts_slice);
|
||||
let argument_layouts = lambda_set.extend_argument_list(
|
||||
env.arena,
|
||||
&layout_cache.interner,
|
||||
argument_layouts_slice,
|
||||
);
|
||||
let argument_symbols = if argument_layouts.len() > argument_layouts_slice.len() {
|
||||
// extend symbols with the symbol of the closure environment
|
||||
let mut argument_symbols =
|
||||
|
@ -4,7 +4,7 @@ use bumpalo::Bump;
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
use roc_collections::all::{default_hasher, FnvMap, MutMap};
|
||||
use roc_error_macros::{internal_error, todo_abilities};
|
||||
use roc_intern::{Interner, SingleThreadedInterner, ThreadLocalInterner};
|
||||
use roc_intern::{Interned, Interner, SingleThreadedInterner, ThreadLocalInterner};
|
||||
use roc_module::ident::{Lowercase, TagName};
|
||||
use roc_module::symbol::{Interns, Symbol};
|
||||
use roc_problem::can::RuntimeError;
|
||||
@ -1251,7 +1251,7 @@ pub struct LambdaSet<'a> {
|
||||
/// collection of function names and their closure arguments
|
||||
set: &'a [(Symbol, &'a [Layout<'a>])],
|
||||
/// how the closure will be represented at runtime
|
||||
representation: &'a Layout<'a>,
|
||||
representation: Interned<Layout<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -1302,11 +1302,11 @@ pub enum ClosureCallOptions<'a> {
|
||||
}
|
||||
|
||||
impl<'a> LambdaSet<'a> {
|
||||
pub fn runtime_representation<I>(&self, _interner: &I) -> Layout<'a>
|
||||
pub fn runtime_representation<I>(&self, interner: &I) -> Layout<'a>
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
{
|
||||
*self.representation
|
||||
*interner.get(self.representation)
|
||||
}
|
||||
|
||||
/// Does the lambda set contain the given symbol?
|
||||
@ -1314,16 +1314,18 @@ impl<'a> LambdaSet<'a> {
|
||||
self.set.iter().any(|(s, _)| *s == symbol)
|
||||
}
|
||||
|
||||
pub fn is_represented<I>(&self, _interner: &I) -> Option<Layout<'a>>
|
||||
pub fn is_represented<I>(&self, interner: &I) -> Option<Layout<'a>>
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
{
|
||||
if self.has_unwrapped_capture_repr() {
|
||||
Some(*self.representation)
|
||||
let repr = interner.get(self.representation);
|
||||
Some(*repr)
|
||||
} else if self.has_enum_dispatch_repr() {
|
||||
None
|
||||
} else {
|
||||
match self.representation {
|
||||
let repr = interner.get(self.representation);
|
||||
match repr {
|
||||
Layout::Struct {
|
||||
field_layouts: &[], ..
|
||||
} => None,
|
||||
@ -1349,10 +1351,14 @@ impl<'a> LambdaSet<'a> {
|
||||
self.set.is_empty()
|
||||
}
|
||||
|
||||
pub fn layout_for_member_with_lambda_name(
|
||||
pub fn layout_for_member_with_lambda_name<I>(
|
||||
&self,
|
||||
interner: &I,
|
||||
lambda_name: LambdaName,
|
||||
) -> ClosureRepresentation<'a> {
|
||||
) -> ClosureRepresentation<'a>
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
{
|
||||
debug_assert!(self.contains(lambda_name.name));
|
||||
|
||||
let comparator = |other_name: Symbol, other_captures_layouts: &[Layout]| {
|
||||
@ -1363,7 +1369,7 @@ impl<'a> LambdaSet<'a> {
|
||||
.eq(lambda_name.captures_niche.0)
|
||||
};
|
||||
|
||||
self.layout_for_member(comparator)
|
||||
self.layout_for_member(interner, comparator)
|
||||
}
|
||||
|
||||
/// Finds an alias name for a possible-multimorphic lambda variant in the lambda set.
|
||||
@ -1441,16 +1447,19 @@ impl<'a> LambdaSet<'a> {
|
||||
left == right
|
||||
}
|
||||
|
||||
fn layout_for_member<F>(&self, comparator: F) -> ClosureRepresentation<'a>
|
||||
fn layout_for_member<I, F>(&self, interner: &I, comparator: F) -> ClosureRepresentation<'a>
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
F: Fn(Symbol, &[Layout]) -> bool,
|
||||
{
|
||||
let repr = interner.get(self.representation);
|
||||
|
||||
if self.has_unwrapped_capture_repr() {
|
||||
// Only one function, that captures one identifier.
|
||||
return ClosureRepresentation::UnwrappedCapture(*self.representation);
|
||||
return ClosureRepresentation::UnwrappedCapture(*repr);
|
||||
}
|
||||
|
||||
match self.representation {
|
||||
match repr {
|
||||
Layout::Union(union) => {
|
||||
// here we rely on the fact that a union in a closure would be stored in a one-element record.
|
||||
// a closure representation that is itself union must be a of the shape `Closure1 ... | Closure2 ...`
|
||||
@ -1551,14 +1560,19 @@ impl<'a> LambdaSet<'a> {
|
||||
self.set.len() > 1 && self.set.iter().all(|(_, captures)| captures.is_empty())
|
||||
}
|
||||
|
||||
pub fn call_by_name_options(&self) -> ClosureCallOptions<'a> {
|
||||
pub fn call_by_name_options<I>(&self, interner: &I) -> ClosureCallOptions<'a>
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
{
|
||||
let repr = interner.get(self.representation);
|
||||
|
||||
if self.has_unwrapped_capture_repr() {
|
||||
return ClosureCallOptions::UnwrappedCapture(*self.representation);
|
||||
return ClosureCallOptions::UnwrappedCapture(*repr);
|
||||
}
|
||||
|
||||
match self.representation {
|
||||
match repr {
|
||||
Layout::Union(union_layout) => {
|
||||
if self.representation == &Layout::VOID {
|
||||
if repr == &Layout::VOID {
|
||||
debug_assert!(self.set.is_empty());
|
||||
return ClosureCallOptions::Void;
|
||||
}
|
||||
@ -1586,12 +1600,16 @@ impl<'a> LambdaSet<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extend_argument_list(
|
||||
pub fn extend_argument_list<I>(
|
||||
&self,
|
||||
arena: &'a Bump,
|
||||
interner: &I,
|
||||
argument_layouts: &'a [Layout<'a>],
|
||||
) -> &'a [Layout<'a>] {
|
||||
match self.call_by_name_options() {
|
||||
) -> &'a [Layout<'a>]
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
{
|
||||
match self.call_by_name_options(interner) {
|
||||
ClosureCallOptions::Void => argument_layouts,
|
||||
ClosureCallOptions::Struct {
|
||||
field_layouts: &[], ..
|
||||
@ -1741,7 +1759,7 @@ impl<'a> LambdaSet<'a> {
|
||||
set_with_variables,
|
||||
opt_recursion_var.into_variable(),
|
||||
);
|
||||
let representation = env.arena.alloc(representation);
|
||||
let representation = env.cache.interner.insert(env.arena.alloc(representation));
|
||||
|
||||
Cacheable(
|
||||
Ok(LambdaSet {
|
||||
@ -1756,7 +1774,7 @@ impl<'a> LambdaSet<'a> {
|
||||
// See also https://github.com/roc-lang/roc/issues/3163.
|
||||
cacheable(Ok(LambdaSet {
|
||||
set: &[],
|
||||
representation: env.arena.alloc(Layout::UNIT),
|
||||
representation: env.cache.interner.insert(env.arena.alloc(Layout::UNIT)),
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -1785,26 +1803,32 @@ impl<'a> LambdaSet<'a> {
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
{
|
||||
self.representation.stack_size(interner, target_info)
|
||||
interner
|
||||
.get(self.representation)
|
||||
.stack_size(interner, target_info)
|
||||
}
|
||||
pub fn contains_refcounted<I>(&self, interner: &I) -> bool
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
{
|
||||
self.representation.contains_refcounted(interner)
|
||||
interner
|
||||
.get(self.representation)
|
||||
.contains_refcounted(interner)
|
||||
}
|
||||
pub fn safe_to_memcpy<I>(&self, interner: &I) -> bool
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
{
|
||||
self.representation.safe_to_memcpy(interner)
|
||||
interner.get(self.representation).safe_to_memcpy(interner)
|
||||
}
|
||||
|
||||
pub fn alignment_bytes<I>(&self, interner: &I, target_info: TargetInfo) -> u32
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
{
|
||||
self.representation.alignment_bytes(interner, target_info)
|
||||
interner
|
||||
.get(self.representation)
|
||||
.alignment_bytes(interner, target_info)
|
||||
}
|
||||
}
|
||||
|
||||
@ -4275,7 +4299,7 @@ mod test {
|
||||
|
||||
let lambda_set = LambdaSet {
|
||||
set: &[(Symbol::LIST_MAP, &[])],
|
||||
representation: &Layout::UNIT,
|
||||
representation: interner.insert(&Layout::UNIT),
|
||||
};
|
||||
|
||||
let a = &[Layout::UNIT] as &[_];
|
||||
|
Loading…
Reference in New Issue
Block a user