mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
Lift Niche from just captures-niche to generic niche
This commit is contained in:
parent
ea53a50447
commit
972046445b
16 changed files with 119 additions and 140 deletions
|
@ -15,7 +15,7 @@ use roc_mono::ir::{
|
|||
Literal, ModifyRc, OptLevel, Proc, ProcLayout, SingleEntryPoint, Stmt,
|
||||
};
|
||||
use roc_mono::layout::{
|
||||
Builtin, CapturesNiche, FieldOrderHash, Layout, RawFunctionLayout, STLayoutInterner,
|
||||
Builtin, CapturesNiche, FieldOrderHash, Layout, Niche, RawFunctionLayout, STLayoutInterner,
|
||||
UnionLayout,
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@ pub fn func_name_bytes(proc: &Proc) -> [u8; SIZE] {
|
|||
let bytes = func_name_bytes_help(
|
||||
proc.name.name(),
|
||||
proc.args.iter().map(|x| x.0),
|
||||
proc.name.captures_niche(),
|
||||
proc.name.niche(),
|
||||
&proc.ret_layout,
|
||||
);
|
||||
bytes
|
||||
|
@ -75,7 +75,7 @@ impl TagUnionId {
|
|||
pub fn func_name_bytes_help<'a, I>(
|
||||
symbol: Symbol,
|
||||
argument_layouts: I,
|
||||
captures_niche: CapturesNiche<'a>,
|
||||
niche: Niche<'a>,
|
||||
return_layout: &Layout<'a>,
|
||||
) -> [u8; SIZE]
|
||||
where
|
||||
|
@ -94,7 +94,7 @@ where
|
|||
layout.hash(&mut hasher);
|
||||
}
|
||||
|
||||
captures_niche.hash(&mut hasher);
|
||||
niche.hash(&mut hasher);
|
||||
|
||||
return_layout.hash(&mut hasher);
|
||||
|
||||
|
@ -189,22 +189,14 @@ where
|
|||
match layout {
|
||||
RawFunctionLayout::Function(_, _, _) => {
|
||||
let it = top_level.arguments.iter().copied();
|
||||
let bytes = func_name_bytes_help(
|
||||
*symbol,
|
||||
it,
|
||||
CapturesNiche::no_niche(),
|
||||
&top_level.result,
|
||||
);
|
||||
let bytes =
|
||||
func_name_bytes_help(*symbol, it, Niche::NONE, &top_level.result);
|
||||
|
||||
host_exposed_functions.push((bytes, top_level.arguments));
|
||||
}
|
||||
RawFunctionLayout::ZeroArgumentThunk(_) => {
|
||||
let bytes = func_name_bytes_help(
|
||||
*symbol,
|
||||
[],
|
||||
CapturesNiche::no_niche(),
|
||||
&top_level.result,
|
||||
);
|
||||
let bytes =
|
||||
func_name_bytes_help(*symbol, [], Niche::NONE, &top_level.result);
|
||||
|
||||
host_exposed_functions.push((bytes, top_level.arguments));
|
||||
}
|
||||
|
@ -237,7 +229,7 @@ where
|
|||
let roc_main_bytes = func_name_bytes_help(
|
||||
entry_point_symbol,
|
||||
entry_point_layout.arguments.iter().copied(),
|
||||
CapturesNiche::no_niche(),
|
||||
Niche::NONE,
|
||||
&entry_point_layout.result,
|
||||
);
|
||||
let roc_main = FuncName(&roc_main_bytes);
|
||||
|
@ -265,19 +257,14 @@ where
|
|||
field_order_hash: FieldOrderHash::from_ordered_fields(&[]),
|
||||
field_layouts: &[],
|
||||
},
|
||||
captures_niche: CapturesNiche::no_niche(),
|
||||
niche: Niche::NONE,
|
||||
};
|
||||
|
||||
let host_exposed: Vec<_> = symbols
|
||||
.iter()
|
||||
.map(|symbol| {
|
||||
(
|
||||
func_name_bytes_help(
|
||||
*symbol,
|
||||
[],
|
||||
CapturesNiche::no_niche(),
|
||||
&layout.result,
|
||||
),
|
||||
func_name_bytes_help(*symbol, [], Niche::NONE, &layout.result),
|
||||
[].as_slice(),
|
||||
)
|
||||
})
|
||||
|
@ -808,7 +795,7 @@ fn call_spec<'a>(
|
|||
|
||||
let arg_value_id = build_tuple_value(builder, env, block, call.arguments)?;
|
||||
let args_it = arg_layouts.iter().copied();
|
||||
let captures_niche = name.captures_niche();
|
||||
let captures_niche = name.niche();
|
||||
let bytes = func_name_bytes_help(name.name(), args_it, captures_niche, ret_layout);
|
||||
let name = FuncName(&bytes);
|
||||
let module = MOD_APP;
|
||||
|
@ -860,7 +847,7 @@ fn call_spec<'a>(
|
|||
let update_mode_var = UpdateModeVar(&mode);
|
||||
|
||||
let args_it = passed_function.argument_layouts.iter().copied();
|
||||
let captures_niche = passed_function.name.captures_niche();
|
||||
let captures_niche = passed_function.name.niche();
|
||||
let bytes = func_name_bytes_help(
|
||||
passed_function.name.name(),
|
||||
args_it,
|
||||
|
|
|
@ -45,8 +45,8 @@ use roc_mono::ir::{
|
|||
OptLevel, ProcLayout, SingleEntryPoint,
|
||||
};
|
||||
use roc_mono::layout::{
|
||||
Builtin, CapturesNiche, LambdaName, LambdaSet, Layout, LayoutIds, RawFunctionLayout,
|
||||
STLayoutInterner, TagIdIntType, UnionLayout,
|
||||
Builtin, LambdaName, LambdaSet, Layout, LayoutIds, Niche, RawFunctionLayout, STLayoutInterner,
|
||||
TagIdIntType, UnionLayout,
|
||||
};
|
||||
use roc_std::RocDec;
|
||||
use roc_target::{PtrWidth, TargetInfo};
|
||||
|
@ -620,12 +620,8 @@ fn promote_to_main_function<'a, 'ctx, 'env>(
|
|||
top_level: ProcLayout<'a>,
|
||||
) -> (&'static str, FunctionValue<'ctx>) {
|
||||
let it = top_level.arguments.iter().copied();
|
||||
let bytes = roc_alias_analysis::func_name_bytes_help(
|
||||
symbol,
|
||||
it,
|
||||
CapturesNiche::no_niche(),
|
||||
&top_level.result,
|
||||
);
|
||||
let bytes =
|
||||
roc_alias_analysis::func_name_bytes_help(symbol, it, Niche::NONE, &top_level.result);
|
||||
let func_name = FuncName(&bytes);
|
||||
let func_solutions = mod_solutions.func_solutions(func_name).unwrap();
|
||||
|
||||
|
@ -637,14 +633,8 @@ fn promote_to_main_function<'a, 'ctx, 'env>(
|
|||
);
|
||||
|
||||
// NOTE fake layout; it is only used for debug prints
|
||||
let roc_main_fn = function_value_by_func_spec(
|
||||
env,
|
||||
*func_spec,
|
||||
symbol,
|
||||
&[],
|
||||
CapturesNiche::no_niche(),
|
||||
&Layout::UNIT,
|
||||
);
|
||||
let roc_main_fn =
|
||||
function_value_by_func_spec(env, *func_spec, symbol, &[], Niche::NONE, &Layout::UNIT);
|
||||
|
||||
let main_fn_name = "$Test.main";
|
||||
|
||||
|
@ -681,12 +671,8 @@ fn promote_to_wasm_test_wrapper<'a, 'ctx, 'env>(
|
|||
let main_fn_name = "test_wrapper";
|
||||
|
||||
let it = top_level.arguments.iter().copied();
|
||||
let bytes = roc_alias_analysis::func_name_bytes_help(
|
||||
symbol,
|
||||
it,
|
||||
CapturesNiche::no_niche(),
|
||||
&top_level.result,
|
||||
);
|
||||
let bytes =
|
||||
roc_alias_analysis::func_name_bytes_help(symbol, it, Niche::NONE, &top_level.result);
|
||||
let func_name = FuncName(&bytes);
|
||||
let func_solutions = mod_solutions.func_solutions(func_name).unwrap();
|
||||
|
||||
|
@ -698,14 +684,8 @@ fn promote_to_wasm_test_wrapper<'a, 'ctx, 'env>(
|
|||
);
|
||||
|
||||
// NOTE fake layout; it is only used for debug prints
|
||||
let roc_main_fn = function_value_by_func_spec(
|
||||
env,
|
||||
*func_spec,
|
||||
symbol,
|
||||
&[],
|
||||
CapturesNiche::no_niche(),
|
||||
&Layout::UNIT,
|
||||
);
|
||||
let roc_main_fn =
|
||||
function_value_by_func_spec(env, *func_spec, symbol, &[], Niche::NONE, &Layout::UNIT);
|
||||
|
||||
let output_type = match roc_main_fn.get_type().get_return_type() {
|
||||
Some(return_type) => {
|
||||
|
@ -3546,7 +3526,7 @@ fn expose_function_to_host<'a, 'ctx, 'env>(
|
|||
symbol: Symbol,
|
||||
roc_function: FunctionValue<'ctx>,
|
||||
arguments: &'a [Layout<'a>],
|
||||
captures_niche: CapturesNiche<'a>,
|
||||
niche: Niche<'a>,
|
||||
return_layout: Layout<'a>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
) {
|
||||
|
@ -3555,7 +3535,7 @@ fn expose_function_to_host<'a, 'ctx, 'env>(
|
|||
let proc_layout = ProcLayout {
|
||||
arguments,
|
||||
result: return_layout,
|
||||
captures_niche,
|
||||
niche,
|
||||
};
|
||||
|
||||
let c_function_name: String = layout_ids
|
||||
|
@ -4676,12 +4656,12 @@ pub fn build_procedures_expose_expects<'a, 'ctx, 'env>(
|
|||
Some(&std::env::temp_dir().join("test.ll")),
|
||||
);
|
||||
|
||||
let captures_niche = CapturesNiche::no_niche();
|
||||
let captures_niche = Niche::NONE;
|
||||
|
||||
let top_level = ProcLayout {
|
||||
arguments: &[],
|
||||
result: Layout::UNIT,
|
||||
captures_niche,
|
||||
niche: captures_niche,
|
||||
};
|
||||
|
||||
let mut expect_names = Vec::with_capacity_in(expects.len(), env.arena);
|
||||
|
@ -4904,7 +4884,7 @@ fn build_proc_header<'a, 'ctx, 'env>(
|
|||
symbol,
|
||||
fn_val,
|
||||
arguments.into_bump_slice(),
|
||||
proc.name.captures_niche(),
|
||||
proc.name.niche(),
|
||||
proc.ret_layout,
|
||||
layout_ids,
|
||||
);
|
||||
|
@ -4951,7 +4931,7 @@ fn expose_alias_to_host<'a, 'ctx, 'env>(
|
|||
let bytes = roc_alias_analysis::func_name_bytes_help(
|
||||
exposed_function_symbol,
|
||||
it,
|
||||
CapturesNiche::no_niche(),
|
||||
Niche::NONE,
|
||||
&top_level.result,
|
||||
);
|
||||
let func_name = FuncName(&bytes);
|
||||
|
@ -4970,7 +4950,7 @@ fn expose_alias_to_host<'a, 'ctx, 'env>(
|
|||
*func_spec,
|
||||
exposed_function_symbol,
|
||||
top_level.arguments,
|
||||
CapturesNiche::no_niche(),
|
||||
Niche::NONE,
|
||||
&top_level.result,
|
||||
)
|
||||
}
|
||||
|
@ -5305,19 +5285,19 @@ pub(crate) fn function_value_by_func_spec<'a, 'ctx, 'env>(
|
|||
func_spec: FuncSpec,
|
||||
symbol: Symbol,
|
||||
arguments: &[Layout<'a>],
|
||||
captures_niche: CapturesNiche<'a>,
|
||||
niche: Niche<'a>,
|
||||
result: &Layout<'a>,
|
||||
) -> FunctionValue<'ctx> {
|
||||
let fn_name = func_spec_name(env.arena, &env.interns, symbol, func_spec);
|
||||
let fn_name = fn_name.as_str();
|
||||
|
||||
function_value_by_name_help(env, arguments, captures_niche, result, symbol, fn_name)
|
||||
function_value_by_name_help(env, arguments, niche, result, symbol, fn_name)
|
||||
}
|
||||
|
||||
fn function_value_by_name_help<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
arguments: &[Layout<'a>],
|
||||
_captures_niche: CapturesNiche<'a>,
|
||||
_niche: Niche<'a>,
|
||||
result: &Layout<'a>,
|
||||
symbol: Symbol,
|
||||
fn_name: &str,
|
||||
|
@ -5368,7 +5348,7 @@ fn roc_call_with_args<'a, 'ctx, 'env>(
|
|||
func_spec,
|
||||
name.name(),
|
||||
argument_layouts,
|
||||
name.captures_niche(),
|
||||
name.niche(),
|
||||
result_layout,
|
||||
);
|
||||
|
||||
|
|
|
@ -2308,7 +2308,7 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
func_spec,
|
||||
function_name.name(),
|
||||
argument_layouts,
|
||||
function_name.captures_niche(),
|
||||
function_name.niche(),
|
||||
return_layout,
|
||||
);
|
||||
|
||||
|
|
|
@ -1249,7 +1249,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
|||
let proc_layout = ProcLayout {
|
||||
arguments: arg_layouts,
|
||||
result: **result,
|
||||
captures_niche: func_sym.captures_niche(),
|
||||
niche: func_sym.niche(),
|
||||
};
|
||||
self.expr_call_by_name(
|
||||
func_sym.name(),
|
||||
|
|
|
@ -2205,7 +2205,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
|||
let passed_proc_layout = ProcLayout {
|
||||
arguments: argument_layouts,
|
||||
result: *result_layout,
|
||||
captures_niche: fn_name.captures_niche(),
|
||||
niche: fn_name.niche(),
|
||||
};
|
||||
let passed_proc_index = backend
|
||||
.proc_lookup
|
||||
|
@ -2249,13 +2249,13 @@ pub fn call_higher_order_lowlevel<'a>(
|
|||
ProcLayout {
|
||||
arguments: wrapper_arg_layouts.into_bump_slice(),
|
||||
result: Layout::UNIT,
|
||||
captures_niche: fn_name.captures_niche(),
|
||||
niche: fn_name.niche(),
|
||||
}
|
||||
}
|
||||
ProcSource::HigherOrderCompare(_) => ProcLayout {
|
||||
arguments: wrapper_arg_layouts.into_bump_slice(),
|
||||
result: *result_layout,
|
||||
captures_niche: fn_name.captures_niche(),
|
||||
niche: fn_name.niche(),
|
||||
},
|
||||
ProcSource::Roc | ProcSource::Helper => {
|
||||
internal_error!("Should never reach here for {:?}", helper_proc_source)
|
||||
|
|
|
@ -36,7 +36,7 @@ use roc_mono::ir::{
|
|||
UpdateModeIds,
|
||||
};
|
||||
use roc_mono::layout::{
|
||||
CapturesNiche, LambdaName, Layout, LayoutCache, LayoutProblem, STLayoutInterner,
|
||||
CapturesNiche, LambdaName, Layout, LayoutCache, LayoutProblem, Niche, STLayoutInterner,
|
||||
};
|
||||
use roc_packaging::cache::{self, RocCacheDir};
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
|
@ -3426,7 +3426,7 @@ fn proc_layout_for<'a>(
|
|||
roc_mono::ir::ProcLayout {
|
||||
arguments: &[],
|
||||
result: Layout::struct_no_name_order(&[]),
|
||||
captures_niche: CapturesNiche::no_niche(),
|
||||
niche: Niche::NONE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -513,7 +513,7 @@ impl<'a> BorrowInfState<'a> {
|
|||
..
|
||||
} => {
|
||||
let top_level =
|
||||
ProcLayout::new(self.arena, arg_layouts, name.captures_niche(), **ret_layout);
|
||||
ProcLayout::new(self.arena, arg_layouts, name.niche(), **ret_layout);
|
||||
|
||||
// get the borrow signature of the applied function
|
||||
let ps = param_map
|
||||
|
@ -556,7 +556,7 @@ impl<'a> BorrowInfState<'a> {
|
|||
let closure_layout = ProcLayout {
|
||||
arguments: passed_function.argument_layouts,
|
||||
result: passed_function.return_layout,
|
||||
captures_niche: passed_function.name.captures_niche(),
|
||||
niche: passed_function.name.niche(),
|
||||
};
|
||||
|
||||
let function_ps =
|
||||
|
@ -739,8 +739,7 @@ impl<'a> BorrowInfState<'a> {
|
|||
Stmt::Ret(z),
|
||||
) = (v, b)
|
||||
{
|
||||
let top_level =
|
||||
ProcLayout::new(self.arena, arg_layouts, g.captures_niche(), **ret_layout);
|
||||
let top_level = ProcLayout::new(self.arena, arg_layouts, g.niche(), **ret_layout);
|
||||
|
||||
if self.current_proc == g.name() && x == *z {
|
||||
// anonymous functions (for which the ps may not be known)
|
||||
|
|
|
@ -9,7 +9,9 @@ use crate::ir::{
|
|||
Call, CallSpecId, CallType, Expr, HostExposedLayouts, JoinPointId, ModifyRc, Proc, ProcLayout,
|
||||
SelfRecursive, Stmt, UpdateModeId,
|
||||
};
|
||||
use crate::layout::{Builtin, CapturesNiche, LambdaName, Layout, STLayoutInterner, UnionLayout};
|
||||
use crate::layout::{
|
||||
Builtin, CapturesNiche, LambdaName, Layout, Niche, STLayoutInterner, UnionLayout,
|
||||
};
|
||||
|
||||
mod equality;
|
||||
mod refcount;
|
||||
|
@ -404,23 +406,23 @@ impl<'a> CodeGenHelp<'a> {
|
|||
HelperOp::Inc => ProcLayout {
|
||||
arguments: self.arena.alloc([*layout, self.layout_isize]),
|
||||
result: LAYOUT_UNIT,
|
||||
captures_niche: CapturesNiche::no_niche(),
|
||||
niche: Niche::NONE,
|
||||
},
|
||||
HelperOp::Dec => ProcLayout {
|
||||
arguments: self.arena.alloc([*layout]),
|
||||
result: LAYOUT_UNIT,
|
||||
captures_niche: CapturesNiche::no_niche(),
|
||||
niche: Niche::NONE,
|
||||
},
|
||||
HelperOp::Reset => ProcLayout {
|
||||
arguments: self.arena.alloc([*layout]),
|
||||
result: *layout,
|
||||
captures_niche: CapturesNiche::no_niche(),
|
||||
niche: Niche::NONE,
|
||||
},
|
||||
HelperOp::DecRef(_) => unreachable!("No generated Proc for DecRef"),
|
||||
HelperOp::Eq => ProcLayout {
|
||||
arguments: self.arena.alloc([*layout, *layout]),
|
||||
result: LAYOUT_BOOL,
|
||||
captures_niche: CapturesNiche::no_niche(),
|
||||
niche: Niche::NONE,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -556,7 +556,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
let proc_layout = ProcLayout {
|
||||
arguments: arg_layouts,
|
||||
result: **ret_layout,
|
||||
captures_niche: name.captures_niche(),
|
||||
niche: name.niche(),
|
||||
};
|
||||
if !self.procs.contains_key(&(name.name(), proc_layout)) {
|
||||
let similar = self
|
||||
|
|
|
@ -6,7 +6,7 @@ use ven_pretty::{Arena, DocAllocator, DocBuilder};
|
|||
|
||||
use crate::{
|
||||
ir::{Parens, ProcLayout},
|
||||
layout::{CapturesNiche, Layout},
|
||||
layout::{Layout, Niche},
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
@ -465,7 +465,7 @@ where
|
|||
let ProcLayout {
|
||||
arguments,
|
||||
result,
|
||||
captures_niche,
|
||||
niche: captures_niche,
|
||||
} = proc_layout;
|
||||
let args = f.intersperse(
|
||||
arguments
|
||||
|
@ -478,20 +478,19 @@ where
|
|||
f.reflow(" -> "),
|
||||
result.to_doc(f, interner, Parens::NotNeeded),
|
||||
]);
|
||||
let niche = if captures_niche == CapturesNiche::no_niche() {
|
||||
f.reflow("(no niche)")
|
||||
} else {
|
||||
f.concat([
|
||||
let niche = match captures_niche {
|
||||
Niche::NONE => f.reflow("(no niche)"),
|
||||
Niche::Captures(captures_niche) => f.concat([
|
||||
f.reflow("(niche {"),
|
||||
f.intersperse(
|
||||
captures_niche
|
||||
.0
|
||||
.captures()
|
||||
.iter()
|
||||
.map(|&c| interner.get(c).to_doc(f, interner, Parens::NotNeeded)),
|
||||
f.reflow(", "),
|
||||
),
|
||||
f.reflow("})"),
|
||||
])
|
||||
]),
|
||||
};
|
||||
f.concat([fun, f.space(), niche])
|
||||
}
|
||||
|
|
|
@ -595,7 +595,7 @@ impl<'a, 'i> Context<'a, 'i> {
|
|||
..
|
||||
} => {
|
||||
let top_level =
|
||||
ProcLayout::new(self.arena, arg_layouts, name.captures_niche(), **ret_layout);
|
||||
ProcLayout::new(self.arena, arg_layouts, name.niche(), **ret_layout);
|
||||
|
||||
// get the borrow signature
|
||||
let ps = self
|
||||
|
@ -645,7 +645,7 @@ impl<'a, 'i> Context<'a, 'i> {
|
|||
let function_layout = ProcLayout {
|
||||
arguments: passed_function.argument_layouts,
|
||||
result: passed_function.return_layout,
|
||||
captures_niche: passed_function.name.captures_niche(),
|
||||
niche: passed_function.name.niche(),
|
||||
};
|
||||
|
||||
let function_ps = match self
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#![allow(clippy::manual_map)]
|
||||
|
||||
use crate::layout::{
|
||||
self, Builtin, CapturesNiche, ClosureCallOptions, ClosureRepresentation, EnumDispatch,
|
||||
LambdaName, LambdaSet, Layout, LayoutCache, LayoutProblem, RawFunctionLayout, STLayoutInterner,
|
||||
TagIdIntType, UnionLayout, WrappedVariant,
|
||||
self, Builtin, ClosureCallOptions, ClosureRepresentation, EnumDispatch, LambdaName, LambdaSet,
|
||||
Layout, LayoutCache, LayoutProblem, Niche, RawFunctionLayout, STLayoutInterner, TagIdIntType,
|
||||
UnionLayout, WrappedVariant,
|
||||
};
|
||||
use bumpalo::collections::{CollectIn, Vec};
|
||||
use bumpalo::Bump;
|
||||
|
@ -3391,7 +3391,7 @@ fn specialize_proc_help<'a>(
|
|||
let top_level = ProcLayout::new(
|
||||
env.arena,
|
||||
top_level_arguments.into_bump_slice(),
|
||||
CapturesNiche::no_niche(),
|
||||
Niche::NONE,
|
||||
*return_layout,
|
||||
);
|
||||
|
||||
|
@ -3424,7 +3424,7 @@ fn specialize_proc_help<'a>(
|
|||
*symbol,
|
||||
(
|
||||
name,
|
||||
ProcLayout::new(env.arena, &[], CapturesNiche::no_niche(), result),
|
||||
ProcLayout::new(env.arena, &[], Niche::NONE, result),
|
||||
layout,
|
||||
),
|
||||
);
|
||||
|
@ -3956,14 +3956,14 @@ fn specialize_variable<'a>(
|
|||
pub struct ProcLayout<'a> {
|
||||
pub arguments: &'a [Layout<'a>],
|
||||
pub result: Layout<'a>,
|
||||
pub captures_niche: CapturesNiche<'a>,
|
||||
pub niche: Niche<'a>,
|
||||
}
|
||||
|
||||
impl<'a> ProcLayout<'a> {
|
||||
pub(crate) fn new(
|
||||
arena: &'a Bump,
|
||||
old_arguments: &'a [Layout<'a>],
|
||||
old_captures_niche: CapturesNiche<'a>,
|
||||
old_niche: Niche<'a>,
|
||||
result: Layout<'a>,
|
||||
) -> Self {
|
||||
let mut arguments = Vec::with_capacity_in(old_arguments.len(), arena);
|
||||
|
@ -3978,7 +3978,7 @@ impl<'a> ProcLayout<'a> {
|
|||
|
||||
ProcLayout {
|
||||
arguments: arguments.into_bump_slice(),
|
||||
captures_niche: old_captures_niche,
|
||||
niche: old_niche,
|
||||
result: new_result,
|
||||
}
|
||||
}
|
||||
|
@ -3992,10 +3992,10 @@ impl<'a> ProcLayout<'a> {
|
|||
RawFunctionLayout::Function(arguments, lambda_set, result) => {
|
||||
let arguments =
|
||||
lambda_set.extend_argument_list_for_named(arena, lambda_name, arguments);
|
||||
ProcLayout::new(arena, arguments, lambda_name.captures_niche(), *result)
|
||||
ProcLayout::new(arena, arguments, lambda_name.niche(), *result)
|
||||
}
|
||||
RawFunctionLayout::ZeroArgumentThunk(result) => {
|
||||
ProcLayout::new(arena, &[], CapturesNiche::no_niche(), result)
|
||||
ProcLayout::new(arena, &[], Niche::NONE, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8382,8 +8382,7 @@ fn specialize_symbol<'a>(
|
|||
// let layout = Layout::Closure(argument_layouts, lambda_set, ret_layout);
|
||||
// panic!("suspicious");
|
||||
let layout = Layout::LambdaSet(lambda_set);
|
||||
let top_level =
|
||||
ProcLayout::new(env.arena, &[], CapturesNiche::no_niche(), layout);
|
||||
let top_level = ProcLayout::new(env.arena, &[], Niche::NONE, layout);
|
||||
procs.insert_passed_by_name(
|
||||
env,
|
||||
arg_var,
|
||||
|
@ -8427,8 +8426,7 @@ fn specialize_symbol<'a>(
|
|||
}
|
||||
RawFunctionLayout::ZeroArgumentThunk(ret_layout) => {
|
||||
// this is a 0-argument thunk
|
||||
let top_level =
|
||||
ProcLayout::new(env.arena, &[], CapturesNiche::no_niche(), ret_layout);
|
||||
let top_level = ProcLayout::new(env.arena, &[], Niche::NONE, ret_layout);
|
||||
procs.insert_passed_by_name(
|
||||
env,
|
||||
arg_var,
|
||||
|
@ -8756,12 +8754,7 @@ fn call_by_name_help<'a>(
|
|||
let top_level_layout = {
|
||||
let argument_layouts =
|
||||
lambda_set.extend_argument_list_for_named(env.arena, proc_name, argument_layouts);
|
||||
ProcLayout::new(
|
||||
env.arena,
|
||||
argument_layouts,
|
||||
proc_name.captures_niche(),
|
||||
*ret_layout,
|
||||
)
|
||||
ProcLayout::new(env.arena, argument_layouts, proc_name.niche(), *ret_layout)
|
||||
};
|
||||
|
||||
// the variables of the given arguments
|
||||
|
@ -9016,7 +9009,7 @@ fn call_by_name_module_thunk<'a>(
|
|||
assigned: Symbol,
|
||||
hole: &'a Stmt<'a>,
|
||||
) -> Stmt<'a> {
|
||||
let top_level_layout = ProcLayout::new(env.arena, &[], CapturesNiche::no_niche(), *ret_layout);
|
||||
let top_level_layout = ProcLayout::new(env.arena, &[], Niche::NONE, *ret_layout);
|
||||
|
||||
let inner_layout = *ret_layout;
|
||||
|
||||
|
|
|
@ -1241,18 +1241,28 @@ impl std::fmt::Debug for LambdaSet<'_> {
|
|||
///
|
||||
/// See also https://github.com/roc-lang/roc/issues/3336.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct CapturesNiche<'a>(pub(crate) &'a [InLayout<'a>]);
|
||||
pub struct CapturesNiche<'a>(&'a [InLayout<'a>]);
|
||||
|
||||
impl CapturesNiche<'_> {
|
||||
pub fn no_niche() -> Self {
|
||||
Self(&[])
|
||||
impl<'a> CapturesNiche<'a> {
|
||||
pub(crate) fn captures(&self) -> &'a [Layout<'a>] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Niche<'a> {
|
||||
/// A niche for a proc are its captures.
|
||||
Captures(CapturesNiche<'a>),
|
||||
}
|
||||
|
||||
impl<'a> Niche<'a> {
|
||||
pub const NONE: Niche<'a> = Niche::Captures(CapturesNiche(&[]));
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct LambdaName<'a> {
|
||||
name: Symbol,
|
||||
captures_niche: CapturesNiche<'a>,
|
||||
niche: Niche<'a>,
|
||||
}
|
||||
|
||||
impl<'a> LambdaName<'a> {
|
||||
|
@ -1262,29 +1272,29 @@ impl<'a> LambdaName<'a> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn captures_niche(&self) -> CapturesNiche<'a> {
|
||||
self.captures_niche
|
||||
pub fn niche(&self) -> Niche<'a> {
|
||||
self.niche
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn no_captures(&self) -> bool {
|
||||
self.captures_niche.0.is_empty()
|
||||
pub(crate) fn no_captures(&self) -> bool {
|
||||
match self.niche {
|
||||
Niche::NONE => true,
|
||||
Niche::Captures(captures) => captures.0.is_empty(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn no_niche(name: Symbol) -> Self {
|
||||
Self {
|
||||
name,
|
||||
captures_niche: CapturesNiche::no_niche(),
|
||||
niche: Niche::NONE,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn replace_name(&self, name: Symbol) -> Self {
|
||||
Self {
|
||||
name,
|
||||
captures_niche: self.captures_niche,
|
||||
}
|
||||
pub(crate) fn replace_name(&self, name: Symbol) -> Self {
|
||||
Self { name, ..*self }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1377,9 +1387,12 @@ impl<'a> LambdaSet<'a> {
|
|||
}
|
||||
|
||||
pub fn iter_set(&self) -> impl ExactSizeIterator<Item = LambdaName<'a>> {
|
||||
self.set.iter().map(|(name, captures_layouts)| LambdaName {
|
||||
name: *name,
|
||||
captures_niche: CapturesNiche(captures_layouts),
|
||||
self.set.iter().map(|(name, captures_layouts)| {
|
||||
let niche = match captures_layouts {
|
||||
[] => Niche::NONE,
|
||||
_ => Niche::Captures(CapturesNiche(captures_layouts)),
|
||||
};
|
||||
LambdaName { name: *name, niche }
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1403,12 +1416,17 @@ impl<'a> LambdaSet<'a> {
|
|||
{
|
||||
debug_assert!(self.contains(lambda_name.name));
|
||||
|
||||
let captures = match lambda_name.niche {
|
||||
Niche::Captures(captures) => captures.0,
|
||||
Niche::NONE => &[],
|
||||
};
|
||||
|
||||
let comparator = |other_name: Symbol, other_captures_layouts: &[InLayout]| {
|
||||
other_name == lambda_name.name
|
||||
// Make sure all captures are equal
|
||||
&& other_captures_layouts
|
||||
.iter()
|
||||
.eq(lambda_name.captures_niche.0)
|
||||
.eq(captures)
|
||||
};
|
||||
|
||||
self.layout_for_member(interner, comparator)
|
||||
|
@ -1455,7 +1473,7 @@ impl<'a> LambdaSet<'a> {
|
|||
|
||||
LambdaName {
|
||||
name: *name,
|
||||
captures_niche: CapturesNiche(layouts),
|
||||
niche: Niche::Captures(CapturesNiche(layouts)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1658,6 +1676,7 @@ impl<'a> LambdaSet<'a> {
|
|||
lambda_name: LambdaName<'a>,
|
||||
argument_layouts: &'a [Layout<'a>],
|
||||
) -> &'a [Layout<'a>] {
|
||||
let Niche::Captures(CapturesNiche(captures)) = lambda_name.niche;
|
||||
// TODO(https://github.com/roc-lang/roc/issues/4831): we should turn on this debug-assert;
|
||||
// however, currently it causes false-positives, because host-exposed functions that are
|
||||
// function pointers to platform-exposed functions are compiled as if they are proper
|
||||
|
@ -1674,7 +1693,7 @@ impl<'a> LambdaSet<'a> {
|
|||
// );
|
||||
|
||||
// If we don't capture, there is nothing to extend.
|
||||
if lambda_name.captures_niche.0.is_empty() {
|
||||
if captures.is_empty() {
|
||||
argument_layouts
|
||||
} else {
|
||||
let mut arguments = Vec::with_capacity_in(argument_layouts.len() + 1, arena);
|
||||
|
|
|
@ -124,7 +124,7 @@ fn build_app_mono<'a>(
|
|||
let proc_layout = ProcLayout {
|
||||
arguments: &[],
|
||||
result: int_layout,
|
||||
captures_niche: CapturesNiche::no_niche(),
|
||||
niche: CapturesNiche::no_niche(),
|
||||
};
|
||||
|
||||
let mut app = MutMap::default();
|
||||
|
|
|
@ -62,7 +62,7 @@ pub fn jit_to_ast<'a, A: ReplApp<'a>>(
|
|||
ProcLayout {
|
||||
arguments: [],
|
||||
result,
|
||||
captures_niche: _,
|
||||
niche: _,
|
||||
} => {
|
||||
// This is a thunk, which cannot be defined in userspace, so we know
|
||||
// it's `main` and can be executed.
|
||||
|
|
|
@ -5,7 +5,7 @@ use {
|
|||
roc_module::symbol::Interns,
|
||||
roc_mono::{
|
||||
ir::ProcLayout,
|
||||
layout::{CapturesNiche, Layout, LayoutCache},
|
||||
layout::{Layout, LayoutCache, Niche},
|
||||
},
|
||||
roc_parse::ast::Expr,
|
||||
roc_repl_eval::{eval::jit_to_ast, ReplAppMemory},
|
||||
|
@ -67,7 +67,7 @@ pub fn get_values<'a>(
|
|||
let proc_layout = ProcLayout {
|
||||
arguments: &[],
|
||||
result: layout,
|
||||
captures_niche: CapturesNiche::no_niche(),
|
||||
niche: Niche::NONE,
|
||||
};
|
||||
|
||||
jit_to_ast(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue