mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Typecheck and compile opaque wrapping functions
This enables you to write something like ``` A := U8 List.map [1, 2, 3] @A ``` which will be compiled as if it was `List.map [1, 2, 3] \x -> @A x`. Closes #3499
This commit is contained in:
parent
d889f1fda9
commit
f1a6ea6a40
9 changed files with 360 additions and 15 deletions
|
@ -1,6 +1,6 @@
|
|||
use roc_can::{
|
||||
def::Def,
|
||||
expr::{AccessorData, ClosureData, Expr, Field, WhenBranch},
|
||||
expr::{AccessorData, ClosureData, Expr, Field, OpaqueWrapFunctionData, WhenBranch},
|
||||
};
|
||||
use roc_module::ident::{Lowercase, TagName};
|
||||
use roc_types::{
|
||||
|
@ -543,6 +543,29 @@ fn deep_copy_type_vars_into_expr_help<C: CopyEnv>(
|
|||
lambda_set_variables: lambda_set_variables.clone(),
|
||||
},
|
||||
|
||||
OpaqueWrapFunction(OpaqueWrapFunctionData {
|
||||
opaque_name,
|
||||
opaque_var,
|
||||
specialized_def_type,
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
function_name,
|
||||
function_var,
|
||||
argument_var,
|
||||
closure_var,
|
||||
}) => OpaqueWrapFunction(OpaqueWrapFunctionData {
|
||||
opaque_name: *opaque_name,
|
||||
opaque_var: sub!(*opaque_var),
|
||||
function_name: *function_name,
|
||||
function_var: sub!(*function_var),
|
||||
argument_var: sub!(*argument_var),
|
||||
closure_var: sub!(*closure_var),
|
||||
// The following three are only used for constraining
|
||||
specialized_def_type: specialized_def_type.clone(),
|
||||
type_arguments: type_arguments.clone(),
|
||||
lambda_set_variables: lambda_set_variables.clone(),
|
||||
}),
|
||||
|
||||
Expect {
|
||||
loc_condition,
|
||||
loc_continuation,
|
||||
|
|
|
@ -4387,6 +4387,60 @@ pub fn with_hole<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
OpaqueWrapFunction(wrap_fn_data) => {
|
||||
let opaque_var = wrap_fn_data.opaque_var;
|
||||
let arg_symbol = env.unique_symbol();
|
||||
|
||||
let ClosureData {
|
||||
name,
|
||||
function_type,
|
||||
arguments,
|
||||
loc_body,
|
||||
..
|
||||
} = wrap_fn_data.to_closure_data(arg_symbol);
|
||||
|
||||
match procs.insert_anonymous(
|
||||
env,
|
||||
LambdaName::no_niche(name),
|
||||
function_type,
|
||||
arguments,
|
||||
*loc_body,
|
||||
CapturedSymbols::None,
|
||||
opaque_var,
|
||||
layout_cache,
|
||||
) {
|
||||
Ok(_) => {
|
||||
let raw_layout = return_on_layout_error!(
|
||||
env,
|
||||
layout_cache.raw_from_var(env.arena, function_type, env.subs),
|
||||
"Expr::OpaqueWrapFunction"
|
||||
);
|
||||
|
||||
match raw_layout {
|
||||
RawFunctionLayout::Function(_, lambda_set, _) => {
|
||||
let lambda_name =
|
||||
find_lambda_name(env, layout_cache, lambda_set, name, &[]);
|
||||
construct_closure_data(
|
||||
env,
|
||||
lambda_set,
|
||||
lambda_name,
|
||||
&[],
|
||||
assigned,
|
||||
hole,
|
||||
)
|
||||
}
|
||||
RawFunctionLayout::ZeroArgumentThunk(_) => {
|
||||
internal_error!("should not be a thunk!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(_error) => Stmt::RuntimeError(
|
||||
"TODO convert anonymous function error to a RuntimeError string",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
Update {
|
||||
record_var,
|
||||
symbol: structure,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue