mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
sort of stable
This commit is contained in:
parent
c4fc526038
commit
ce195034ee
4 changed files with 119 additions and 54 deletions
|
@ -1877,12 +1877,7 @@ fn specialize_external<'a>(
|
||||||
// if this is a closure, add the closure record argument
|
// if this is a closure, add the closure record argument
|
||||||
let pattern_symbols = match captured_symbols {
|
let pattern_symbols = match captured_symbols {
|
||||||
CapturedSymbols::None => pattern_symbols,
|
CapturedSymbols::None => pattern_symbols,
|
||||||
// CapturedSymbols::Captured([]) => pattern_symbols,
|
CapturedSymbols::Captured([]) => pattern_symbols,
|
||||||
CapturedSymbols::Captured([]) => {
|
|
||||||
let mut temp = Vec::from_iter_in(pattern_symbols.iter().copied(), env.arena);
|
|
||||||
temp.push(Symbol::ARG_CLOSURE);
|
|
||||||
temp.into_bump_slice()
|
|
||||||
}
|
|
||||||
CapturedSymbols::Captured(_) => {
|
CapturedSymbols::Captured(_) => {
|
||||||
let mut temp = Vec::from_iter_in(pattern_symbols.iter().copied(), env.arena);
|
let mut temp = Vec::from_iter_in(pattern_symbols.iter().copied(), env.arena);
|
||||||
temp.push(Symbol::ARG_CLOSURE);
|
temp.push(Symbol::ARG_CLOSURE);
|
||||||
|
@ -2069,7 +2064,6 @@ fn specialize_external<'a>(
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
// dbg!(proc_name, &proc_args, &closure_data_layout, &ret_layout);
|
|
||||||
let proc = Proc {
|
let proc = Proc {
|
||||||
name: proc_name,
|
name: proc_name,
|
||||||
args: proc_args,
|
args: proc_args,
|
||||||
|
@ -2438,7 +2432,8 @@ impl<'a> TopLevelFunctionLayout<'a> {
|
||||||
for old in old_arguments {
|
for old in old_arguments {
|
||||||
match old {
|
match old {
|
||||||
Layout::Closure(_, lambda_set, _) => {
|
Layout::Closure(_, lambda_set, _) => {
|
||||||
arguments.push(lambda_set.runtime_representation())
|
let repr = lambda_set.runtime_representation();
|
||||||
|
arguments.push(repr)
|
||||||
}
|
}
|
||||||
other => arguments.push(*other),
|
other => arguments.push(*other),
|
||||||
}
|
}
|
||||||
|
@ -2994,7 +2989,13 @@ pub fn with_hole<'a>(
|
||||||
});
|
});
|
||||||
|
|
||||||
// even though this was originally a Tag, we treat it as a Struct from now on
|
// even though this was originally a Tag, we treat it as a Struct from now on
|
||||||
let stmt = Stmt::Let(assigned, Expr::Struct(field_symbols), layout, hole);
|
let stmt = if let [only_field] = field_symbols {
|
||||||
|
let mut hole = hole.clone();
|
||||||
|
substitute_in_exprs(env.arena, &mut hole, assigned, *only_field);
|
||||||
|
hole
|
||||||
|
} else {
|
||||||
|
Stmt::Let(assigned, Expr::Struct(field_symbols), layout, hole)
|
||||||
|
};
|
||||||
|
|
||||||
let iter = field_symbols_temp.into_iter().map(|(_, _, data)| data);
|
let iter = field_symbols_temp.into_iter().map(|(_, _, data)| data);
|
||||||
assign_to_symbols(env, procs, layout_cache, iter, stmt)
|
assign_to_symbols(env, procs, layout_cache, iter, stmt)
|
||||||
|
@ -3258,7 +3259,14 @@ pub fn with_hole<'a>(
|
||||||
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
let field_symbols = field_symbols.into_bump_slice();
|
let field_symbols = field_symbols.into_bump_slice();
|
||||||
let mut stmt = Stmt::Let(assigned, Expr::Struct(field_symbols), layout, hole);
|
|
||||||
|
let mut stmt = if let [only_field] = field_symbols {
|
||||||
|
let mut hole = hole.clone();
|
||||||
|
substitute_in_exprs(env.arena, &mut hole, assigned, *only_field);
|
||||||
|
hole
|
||||||
|
} else {
|
||||||
|
Stmt::Let(assigned, Expr::Struct(field_symbols), layout, hole)
|
||||||
|
};
|
||||||
|
|
||||||
for (opt_field, symbol) in can_fields.into_iter().rev().zip(field_symbols.iter().rev())
|
for (opt_field, symbol) in can_fields.into_iter().rev().zip(field_symbols.iter().rev())
|
||||||
{
|
{
|
||||||
|
@ -6135,6 +6143,8 @@ fn call_by_name_help<'a>(
|
||||||
maybe_closure_layout, layout
|
maybe_closure_layout, layout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
dbg!(maybe_closure_layout, field_symbols, &loc_args);
|
||||||
|
|
||||||
call_specialized_proc(
|
call_specialized_proc(
|
||||||
env,
|
env,
|
||||||
procs,
|
procs,
|
||||||
|
@ -7605,8 +7615,8 @@ fn match_on_lambda_set<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
lambda_set: LambdaSet<'a>,
|
lambda_set: LambdaSet<'a>,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
argument_symbols: &[Symbol],
|
argument_symbols: &'a [Symbol],
|
||||||
argument_layouts: &[Layout<'a>],
|
argument_layouts: &'a [Layout<'a>],
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
assigned: Symbol,
|
assigned: Symbol,
|
||||||
hole: &'a Stmt<'a>,
|
hole: &'a Stmt<'a>,
|
||||||
|
@ -7702,8 +7712,8 @@ fn union_lambda_set_to_switch<'a>(
|
||||||
closure_tag_id_symbol: Symbol,
|
closure_tag_id_symbol: Symbol,
|
||||||
closure_tag_id_layout: Layout<'a>,
|
closure_tag_id_layout: Layout<'a>,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
argument_symbols: &[Symbol],
|
argument_symbols: &'a [Symbol],
|
||||||
argument_layouts: &[Layout<'a>],
|
argument_layouts: &'a [Layout<'a>],
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
assigned: Symbol,
|
assigned: Symbol,
|
||||||
hole: &'a Stmt<'a>,
|
hole: &'a Stmt<'a>,
|
||||||
|
@ -7762,8 +7772,8 @@ fn union_lambda_set_branch<'a>(
|
||||||
function_symbol: Symbol,
|
function_symbol: Symbol,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
closure_data_layout: Layout<'a>,
|
closure_data_layout: Layout<'a>,
|
||||||
argument_symbols_slice: &[Symbol],
|
argument_symbols_slice: &'a [Symbol],
|
||||||
argument_layouts_slice: &[Layout<'a>],
|
argument_layouts_slice: &'a [Layout<'a>],
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
let result_symbol = env.unique_symbol();
|
let result_symbol = env.unique_symbol();
|
||||||
|
@ -7788,23 +7798,35 @@ fn union_lambda_set_branch_help<'a>(
|
||||||
function_symbol: Symbol,
|
function_symbol: Symbol,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
closure_data_layout: Layout<'a>,
|
closure_data_layout: Layout<'a>,
|
||||||
argument_symbols_slice: &[Symbol],
|
argument_symbols_slice: &'a [Symbol],
|
||||||
argument_layouts_slice: &[Layout<'a>],
|
argument_layouts_slice: &'a [Layout<'a>],
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
assigned: Symbol,
|
assigned: Symbol,
|
||||||
hole: &'a Stmt<'a>,
|
hole: &'a Stmt<'a>,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
|
let (argument_layouts, argument_symbols) = match closure_data_layout {
|
||||||
|
Layout::Struct(&[]) | Layout::Builtin(Builtin::Int1) | Layout::Builtin(Builtin::Int8) => {
|
||||||
|
(argument_layouts_slice, argument_symbols_slice)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
// extend layouts with the layout of the closure environment
|
// extend layouts with the layout of the closure environment
|
||||||
let mut argument_layouts = Vec::with_capacity_in(argument_layouts_slice.len() + 1, env.arena);
|
let mut argument_layouts =
|
||||||
|
Vec::with_capacity_in(argument_layouts_slice.len() + 1, env.arena);
|
||||||
argument_layouts.extend(argument_layouts_slice);
|
argument_layouts.extend(argument_layouts_slice);
|
||||||
argument_layouts.push(closure_data_layout);
|
argument_layouts.push(closure_data_layout);
|
||||||
let argument_layouts = argument_layouts.into_bump_slice();
|
|
||||||
|
|
||||||
// extend symbols with the symbol of the closure environment
|
// extend symbols with the symbol of the closure environment
|
||||||
let mut argument_symbols = Vec::with_capacity_in(argument_symbols_slice.len() + 1, env.arena);
|
let mut argument_symbols =
|
||||||
|
Vec::with_capacity_in(argument_symbols_slice.len() + 1, env.arena);
|
||||||
argument_symbols.extend(argument_symbols_slice);
|
argument_symbols.extend(argument_symbols_slice);
|
||||||
argument_symbols.push(closure_data_symbol);
|
argument_symbols.push(closure_data_symbol);
|
||||||
let argument_symbols = argument_symbols.into_bump_slice();
|
|
||||||
|
(
|
||||||
|
argument_layouts.into_bump_slice(),
|
||||||
|
argument_symbols.into_bump_slice(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let full_layout = Layout::FunctionPointer(argument_layouts, env.arena.alloc(return_layout));
|
let full_layout = Layout::FunctionPointer(argument_layouts, env.arena.alloc(return_layout));
|
||||||
|
|
||||||
|
@ -7831,8 +7853,8 @@ fn enum_lambda_set_to_switch<'a>(
|
||||||
closure_tag_id_symbol: Symbol,
|
closure_tag_id_symbol: Symbol,
|
||||||
closure_tag_id_layout: Layout<'a>,
|
closure_tag_id_layout: Layout<'a>,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
argument_symbols: &[Symbol],
|
argument_symbols: &'a [Symbol],
|
||||||
argument_layouts: &[Layout<'a>],
|
argument_layouts: &'a [Layout<'a>],
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
assigned: Symbol,
|
assigned: Symbol,
|
||||||
hole: &'a Stmt<'a>,
|
hole: &'a Stmt<'a>,
|
||||||
|
@ -7893,8 +7915,8 @@ fn enum_lambda_set_branch<'a>(
|
||||||
function_symbol: Symbol,
|
function_symbol: Symbol,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
closure_data_layout: Layout<'a>,
|
closure_data_layout: Layout<'a>,
|
||||||
argument_symbols_slice: &[Symbol],
|
argument_symbols_slice: &'a [Symbol],
|
||||||
argument_layouts_slice: &[Layout<'a>],
|
argument_layouts_slice: &'a [Layout<'a>],
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
let result_symbol = env.unique_symbol();
|
let result_symbol = env.unique_symbol();
|
||||||
|
@ -7919,23 +7941,35 @@ fn enum_lambda_set_branch_help<'a>(
|
||||||
function_symbol: Symbol,
|
function_symbol: Symbol,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
closure_data_layout: Layout<'a>,
|
closure_data_layout: Layout<'a>,
|
||||||
argument_symbols_slice: &[Symbol],
|
argument_symbols_slice: &'a [Symbol],
|
||||||
argument_layouts_slice: &[Layout<'a>],
|
argument_layouts_slice: &'a [Layout<'a>],
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
assigned: Symbol,
|
assigned: Symbol,
|
||||||
hole: &'a Stmt<'a>,
|
hole: &'a Stmt<'a>,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
|
let (argument_layouts, argument_symbols) = match closure_data_layout {
|
||||||
|
Layout::Struct(&[]) | Layout::Builtin(Builtin::Int1) | Layout::Builtin(Builtin::Int8) => {
|
||||||
|
(argument_layouts_slice, argument_symbols_slice)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
// extend layouts with the layout of the closure environment
|
// extend layouts with the layout of the closure environment
|
||||||
let mut argument_layouts = Vec::with_capacity_in(argument_layouts_slice.len() + 1, env.arena);
|
let mut argument_layouts =
|
||||||
|
Vec::with_capacity_in(argument_layouts_slice.len() + 1, env.arena);
|
||||||
argument_layouts.extend(argument_layouts_slice);
|
argument_layouts.extend(argument_layouts_slice);
|
||||||
argument_layouts.push(closure_data_layout);
|
argument_layouts.push(closure_data_layout);
|
||||||
let argument_layouts = argument_layouts.into_bump_slice();
|
|
||||||
|
|
||||||
// extend symbols with the symbol of the closure environment
|
// extend symbols with the symbol of the closure environment
|
||||||
let mut argument_symbols = Vec::with_capacity_in(argument_symbols_slice.len() + 1, env.arena);
|
let mut argument_symbols =
|
||||||
|
Vec::with_capacity_in(argument_symbols_slice.len() + 1, env.arena);
|
||||||
argument_symbols.extend(argument_symbols_slice);
|
argument_symbols.extend(argument_symbols_slice);
|
||||||
argument_symbols.push(closure_data_symbol);
|
argument_symbols.push(closure_data_symbol);
|
||||||
let argument_symbols = argument_symbols.into_bump_slice();
|
|
||||||
|
(
|
||||||
|
argument_layouts.into_bump_slice(),
|
||||||
|
argument_symbols.into_bump_slice(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let full_layout = Layout::FunctionPointer(argument_layouts, env.arena.alloc(return_layout));
|
let full_layout = Layout::FunctionPointer(argument_layouts, env.arena.alloc(return_layout));
|
||||||
|
|
||||||
|
|
|
@ -169,11 +169,18 @@ impl<'a> LambdaSet<'a> {
|
||||||
if let [] = self.set {
|
if let [] = self.set {
|
||||||
// TERRIBLE HACK for builting functions
|
// TERRIBLE HACK for builting functions
|
||||||
Layout::FunctionPointer(argument_layouts, ret_layout)
|
Layout::FunctionPointer(argument_layouts, ret_layout)
|
||||||
} else if let [(_, [])] = self.set {
|
} else {
|
||||||
|
match self.representation {
|
||||||
|
Layout::Struct(&[]) => {
|
||||||
// this function does not have anything in its closure, and the lambda set is a
|
// this function does not have anything in its closure, and the lambda set is a
|
||||||
// singleton, so we pass no extra argument
|
// singleton, so we pass no extra argument
|
||||||
Layout::FunctionPointer(argument_layouts, ret_layout)
|
Layout::FunctionPointer(argument_layouts, ret_layout)
|
||||||
} else {
|
}
|
||||||
|
Layout::Builtin(Builtin::Int1) | Layout::Builtin(Builtin::Int8) => {
|
||||||
|
// we don't pass this along either
|
||||||
|
Layout::FunctionPointer(argument_layouts, ret_layout)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
let mut arguments = Vec::with_capacity_in(argument_layouts.len() + 1, arena);
|
let mut arguments = Vec::with_capacity_in(argument_layouts.len() + 1, arena);
|
||||||
arguments.extend(argument_layouts);
|
arguments.extend(argument_layouts);
|
||||||
arguments.push(self.runtime_representation());
|
arguments.push(self.runtime_representation());
|
||||||
|
@ -181,6 +188,8 @@ impl<'a> LambdaSet<'a> {
|
||||||
Layout::FunctionPointer(arguments.into_bump_slice(), ret_layout)
|
Layout::FunctionPointer(arguments.into_bump_slice(), ret_layout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_var(
|
pub fn from_var(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
|
|
|
@ -1094,6 +1094,28 @@ fn return_wrapped_function_pointer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
fn return_wrapped_function_pointer_b() {
|
||||||
|
assert_non_opt_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [ main ] to "./platform"
|
||||||
|
|
||||||
|
|
||||||
|
foo : { x: (I64 -> Str) }
|
||||||
|
foo = { x: (\_ -> "foobar") }
|
||||||
|
|
||||||
|
main : { x: (I64 -> Str) }
|
||||||
|
main = foo
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
1,
|
||||||
|
i64,
|
||||||
|
|_| 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn return_wrapped_closure() {
|
fn return_wrapped_closure() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
|
|
@ -275,7 +275,7 @@ pub fn helper<'a>(
|
||||||
mode,
|
mode,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn_val.print_to_stderr();
|
// fn_val.print_to_stderr();
|
||||||
// module.print_to_stderr();
|
// module.print_to_stderr();
|
||||||
|
|
||||||
panic!(
|
panic!(
|
||||||
|
@ -311,7 +311,7 @@ pub fn helper<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uncomment this to see the module's optimized LLVM instruction output:
|
// Uncomment this to see the module's optimized LLVM instruction output:
|
||||||
env.module.print_to_stderr();
|
// env.module.print_to_stderr();
|
||||||
|
|
||||||
let lib = module_to_dylib(&env.module, &target, opt_level)
|
let lib = module_to_dylib(&env.module, &target, opt_level)
|
||||||
.expect("Error loading compiled dylib for test");
|
.expect("Error loading compiled dylib for test");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue