mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
Add fx var to can's Call
This commit is contained in:
parent
3cef756559
commit
e8d7820f34
14 changed files with 52 additions and 10 deletions
|
@ -413,13 +413,14 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
|
|||
}
|
||||
|
||||
Call(f, args, called_via) => {
|
||||
let (fn_var, fn_expr, clos_var, ret_var) = &**f;
|
||||
let (fn_var, fn_expr, clos_var, ret_var, fx_var) = &**f;
|
||||
Call(
|
||||
Box::new((
|
||||
sub!(*fn_var),
|
||||
fn_expr.map(|e| go_help!(e)),
|
||||
sub!(*clos_var),
|
||||
sub!(*ret_var),
|
||||
sub!(*fx_var),
|
||||
)),
|
||||
args.iter()
|
||||
.map(|(var, expr)| (sub!(*var), expr.map(|e| go_help!(e))))
|
||||
|
|
|
@ -267,7 +267,7 @@ fn expr<'a>(c: &Ctx, p: EPrec, f: &'a Arena<'a>, e: &'a Expr) -> DocBuilder<'a,
|
|||
.append(expr(c, Free, f, &body.value))
|
||||
.group(),
|
||||
Call(fun, args, _) => {
|
||||
let (_, fun, _, _) = &**fun;
|
||||
let (_, fun, _, _, _) = &**fun;
|
||||
maybe_paren!(
|
||||
Free,
|
||||
p,
|
||||
|
|
|
@ -155,7 +155,7 @@ pub enum Expr {
|
|||
/// This is *only* for calling functions, not for tag application.
|
||||
/// The Tag variant contains any applied values inside it.
|
||||
Call(
|
||||
Box<(Variable, Loc<Expr>, Variable, Variable)>,
|
||||
Box<(Variable, Loc<Expr>, Variable, Variable, Variable)>,
|
||||
Vec<(Variable, Loc<Expr>)>,
|
||||
CalledVia,
|
||||
),
|
||||
|
@ -930,6 +930,7 @@ pub fn canonicalize_expr<'a>(
|
|||
fn_expr,
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
)),
|
||||
args,
|
||||
*application_style,
|
||||
|
@ -969,6 +970,7 @@ pub fn canonicalize_expr<'a>(
|
|||
fn_expr,
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
)),
|
||||
args,
|
||||
*application_style,
|
||||
|
@ -2448,10 +2450,11 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
|||
}
|
||||
|
||||
Call(boxed_tuple, args, called_via) => {
|
||||
let (fn_var, loc_expr, closure_var, expr_var) = *boxed_tuple;
|
||||
let (fn_var, loc_expr, closure_var, expr_var, fx_var) = *boxed_tuple;
|
||||
|
||||
match loc_expr.value {
|
||||
Var(symbol, _) if symbol.is_builtin() => {
|
||||
// NOTE: This assumes builtins are not effectful!
|
||||
match builtin_defs_map(symbol, var_store) {
|
||||
Some(Def {
|
||||
loc_expr:
|
||||
|
@ -2519,7 +2522,7 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
|||
_ => {
|
||||
// For now, we only inline calls to builtins. Leave this alone!
|
||||
Call(
|
||||
Box::new((fn_var, loc_expr, closure_var, expr_var)),
|
||||
Box::new((fn_var, loc_expr, closure_var, expr_var, fx_var)),
|
||||
args,
|
||||
called_via,
|
||||
)
|
||||
|
@ -2787,6 +2790,7 @@ fn desugar_str_segments(var_store: &mut VarStore, segments: Vec<StrSegment>) ->
|
|||
fn_expr,
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
)),
|
||||
vec![
|
||||
(var_store.fresh(), empty_string),
|
||||
|
@ -2823,6 +2827,7 @@ fn desugar_str_segments(var_store: &mut VarStore, segments: Vec<StrSegment>) ->
|
|||
fn_expr,
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
var_store.fresh(),
|
||||
)),
|
||||
vec![
|
||||
(var_store.fresh(), loc_new_expr),
|
||||
|
|
|
@ -292,7 +292,7 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
|
|||
visitor.visit_expr(&body.value, body.region, var);
|
||||
}
|
||||
Expr::Call(f, args, _called_via) => {
|
||||
let (fn_var, loc_fn, _closure_var, _ret_var) = &**f;
|
||||
let (fn_var, loc_fn, _closure_var, _ret_var, _fx_var) = &**f;
|
||||
walk_call(visitor, *fn_var, loc_fn, args);
|
||||
}
|
||||
Expr::Crash { msg, .. } => {
|
||||
|
|
|
@ -481,7 +481,7 @@ pub fn constrain_expr(
|
|||
}
|
||||
}
|
||||
Call(boxed, loc_args, called_via) => {
|
||||
let (fn_var, loc_fn, closure_var, ret_var) = &**boxed;
|
||||
let (fn_var, loc_fn, closure_var, ret_var, fx_var) = &**boxed;
|
||||
// The expression that evaluates to the function being called, e.g. `foo` in
|
||||
// (foo) bar baz
|
||||
let opt_symbol = if let Var(symbol, _) | AbilityMember(symbol, _, _) = loc_fn.value {
|
||||
|
@ -512,6 +512,9 @@ pub fn constrain_expr(
|
|||
// The function's return type
|
||||
let ret_type = Variable(*ret_var);
|
||||
|
||||
// The function's effect type
|
||||
let fx_type = Variable(*fx_var);
|
||||
|
||||
// type of values captured in the closure
|
||||
let closure_type = Variable(*closure_var);
|
||||
|
||||
|
@ -521,6 +524,7 @@ pub fn constrain_expr(
|
|||
vars.push(*fn_var);
|
||||
vars.push(*ret_var);
|
||||
vars.push(*closure_var);
|
||||
vars.push(*fx_var);
|
||||
|
||||
let mut arg_types = Vec::with_capacity(loc_args.len());
|
||||
let mut arg_cons = Vec::with_capacity(loc_args.len());
|
||||
|
@ -555,8 +559,7 @@ pub fn constrain_expr(
|
|||
let arguments = types.from_old_type_slice(arg_types.iter());
|
||||
let lambda_set = types.from_old_type(&closure_type);
|
||||
let ret = types.from_old_type(&ret_type);
|
||||
// [purity-inference] TODO: Add fx var to call
|
||||
let fx = types.from_old_type(&Type::Variable(Variable::PURE));
|
||||
let fx = types.from_old_type(&fx_type);
|
||||
let typ = types.function(arguments, lambda_set, ret, fx);
|
||||
constraints.push_type(types, typ)
|
||||
};
|
||||
|
@ -572,6 +575,7 @@ pub fn constrain_expr(
|
|||
constraints.equal_types_var(*fn_var, expected_fn_type, category.clone(), fn_region),
|
||||
constraints.and_constraint(arg_cons),
|
||||
constraints.equal_types_var(*ret_var, expected_final_type, category, region),
|
||||
// [purity-inference] TODO: union with current function's fx var
|
||||
];
|
||||
|
||||
let and_constraint = constraints.and_constraint(and_cons);
|
||||
|
|
|
@ -91,6 +91,7 @@ fn wrap_in_decode_custom_decode_with(
|
|||
Loc::at_zero(decode_with_var),
|
||||
this_decode_with_clos_var,
|
||||
this_decode_with_ret_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
let decode_with_call = Call(
|
||||
decode_with_fn,
|
||||
|
@ -198,6 +199,7 @@ fn wrap_in_decode_custom_decode_with(
|
|||
Loc::at_zero(decode_custom_var),
|
||||
this_decode_custom_clos_var,
|
||||
this_decode_custom_ret_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
let decode_custom_call = Call(
|
||||
decode_custom_fn,
|
||||
|
|
|
@ -78,6 +78,7 @@ pub(crate) fn decoder(env: &mut Env<'_>, _def_symbol: Symbol) -> (Expr, Variable
|
|||
Loc::at_zero(decode_list_member),
|
||||
this_decode_list_clos_var,
|
||||
this_decode_list_ret_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
let decode_list_call = Call(
|
||||
|
|
|
@ -130,6 +130,7 @@ pub(crate) fn decoder(
|
|||
)),
|
||||
decode_record_lambda_set,
|
||||
record_decoder_var,
|
||||
Variable::PURE,
|
||||
)),
|
||||
vec![
|
||||
(initial_state_var, Loc::at_zero(initial_state)),
|
||||
|
@ -422,6 +423,7 @@ fn custom_decoder(env: &mut Env<'_>, args: DecodingFieldArgs) -> (Variable, Expr
|
|||
Loc::at_zero(Expr::Var(Symbol::DECODE_CUSTOM, this_decode_custom_var)),
|
||||
decode_custom_closure_var,
|
||||
decode_custom_ret_var,
|
||||
Variable::PURE,
|
||||
)),
|
||||
vec![(this_custom_callback_var, Loc::at_zero(custom_callback))],
|
||||
CalledVia::Space,
|
||||
|
@ -1328,6 +1330,7 @@ pub(super) fn decode_with(
|
|||
Loc::at_zero(Expr::Var(Symbol::DECODE_DECODE_WITH, this_decode_with_var)),
|
||||
lambda_set_var,
|
||||
rec_var,
|
||||
Variable::PURE,
|
||||
)),
|
||||
vec![
|
||||
(Variable::LIST_U8, Loc::at_zero(bytes_arg_expr)),
|
||||
|
|
|
@ -120,6 +120,7 @@ pub(crate) fn decoder(env: &mut Env, _def_symbol: Symbol, arity: u32) -> (Expr,
|
|||
)),
|
||||
decode_record_lambda_set,
|
||||
tuple_decoder_var,
|
||||
Variable::PURE,
|
||||
)),
|
||||
vec![
|
||||
(state_var, Loc::at_zero(initial_state)),
|
||||
|
@ -490,6 +491,7 @@ fn step_elem(
|
|||
Loc::at_zero(Expr::Var(Symbol::DECODE_DECODE_WITH, this_decode_with_var)),
|
||||
lambda_set_var,
|
||||
rec_var,
|
||||
Variable::PURE,
|
||||
)),
|
||||
vec![
|
||||
(
|
||||
|
@ -598,6 +600,7 @@ fn step_elem(
|
|||
Loc::at_zero(Expr::Var(Symbol::DECODE_CUSTOM, this_decode_custom_var)),
|
||||
decode_custom_closure_var,
|
||||
decode_custom_ret_var,
|
||||
Variable::PURE,
|
||||
)),
|
||||
vec![(this_custom_callback_var, Loc::at_zero(custom_callback))],
|
||||
CalledVia::Space,
|
||||
|
|
|
@ -146,6 +146,7 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
|
|||
Loc::at_zero(to_encoder_var),
|
||||
to_encoder_clos_var,
|
||||
elem_encoder_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// toEncoder elem
|
||||
|
@ -231,6 +232,7 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
|
|||
Loc::at_zero(encode_list),
|
||||
this_encode_list_clos_var,
|
||||
this_list_encoder_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Encode.list lst to_elem_encoder
|
||||
|
@ -370,6 +372,7 @@ fn to_encoder_record(
|
|||
Loc::at_zero(to_encoder_var),
|
||||
to_encoder_clos_var,
|
||||
encoder_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// toEncoder rcd.a
|
||||
|
@ -451,6 +454,7 @@ fn to_encoder_record(
|
|||
Loc::at_zero(encode_record_var),
|
||||
encode_record_clos_var,
|
||||
encoder_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Encode.record [ { key: .., value: .. }, .. ]
|
||||
|
@ -574,6 +578,7 @@ fn to_encoder_tuple(
|
|||
Loc::at_zero(to_encoder_var),
|
||||
to_encoder_clos_var,
|
||||
encoder_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// toEncoder tup.0
|
||||
|
@ -635,6 +640,7 @@ fn to_encoder_tuple(
|
|||
Loc::at_zero(encode_tuple_var),
|
||||
encode_tuple_clos_var,
|
||||
encoder_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Encode.tuple [ { key: .., value: .. }, .. ]
|
||||
|
@ -776,6 +782,7 @@ fn to_encoder_tag_union(
|
|||
Loc::at_zero(to_encoder_var),
|
||||
to_encoder_clos_var,
|
||||
encoder_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// toEncoder rcd.a
|
||||
|
@ -835,6 +842,7 @@ fn to_encoder_tag_union(
|
|||
Loc::at_zero(encode_tag_var),
|
||||
this_encode_tag_clos_var,
|
||||
this_encoder_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Encode.tag "A" [ Encode.toEncoder v1, Encode.toEncoder v2 ]
|
||||
|
@ -991,6 +999,7 @@ fn wrap_in_encode_custom(
|
|||
Loc::at_zero(Var(Symbol::ENCODE_APPEND_WITH, this_append_with_fn_var)),
|
||||
this_append_with_clos_var,
|
||||
Variable::LIST_U8,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Encode.appendWith bytes encoder fmt
|
||||
|
@ -1084,6 +1093,7 @@ fn wrap_in_encode_custom(
|
|||
Loc::at_zero(Var(Symbol::ENCODE_CUSTOM, this_custom_fn_var)),
|
||||
this_custom_clos_var, // -[clos]->
|
||||
this_custom_encoder_var, // t' ~ Encoder fmt
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Encode.custom \bytes, fmt -> Encode.appendWith bytes encoder fmt
|
||||
|
|
|
@ -489,6 +489,7 @@ fn call_hash_ability_member(
|
|||
Loc::at_zero(hash_fn_head),
|
||||
this_hash_clos_var,
|
||||
this_out_hasher_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
let hash_arguments = vec![
|
||||
|
|
|
@ -152,6 +152,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
|
|||
Loc::at_zero(to_inspector_var),
|
||||
to_inspector_clos_var,
|
||||
elem_inspector_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// toInspector elem
|
||||
|
@ -238,6 +239,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
|
|||
Loc::at_zero(inspect_list),
|
||||
this_inspect_list_clos_var,
|
||||
this_list_inspector_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Inspect.list lst to_elem_inspector
|
||||
|
@ -382,6 +384,7 @@ fn to_inspector_record(
|
|||
Loc::at_zero(to_inspector_var),
|
||||
to_inspector_clos_var,
|
||||
inspector_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// toInspector rcd.a
|
||||
|
@ -463,6 +466,7 @@ fn to_inspector_record(
|
|||
Loc::at_zero(inspect_record_var),
|
||||
inspect_record_clos_var,
|
||||
inspector_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Inspect.record [ { key: .., value: .. }, .. ]
|
||||
|
@ -587,6 +591,7 @@ fn to_inspector_tuple(
|
|||
Loc::at_zero(to_inspector_var),
|
||||
to_inspector_clos_var,
|
||||
inspector_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// toInspector tup.0
|
||||
|
@ -648,6 +653,7 @@ fn to_inspector_tuple(
|
|||
Loc::at_zero(inspect_tuple_var),
|
||||
inspect_tuple_clos_var,
|
||||
inspector_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Inspect.tuple [ { key: .., value: .. }, .. ]
|
||||
|
@ -789,6 +795,7 @@ fn to_inspector_tag_union(
|
|||
Loc::at_zero(to_inspector_var),
|
||||
to_inspector_clos_var,
|
||||
inspector_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// toInspector rcd.a
|
||||
|
@ -852,6 +859,7 @@ fn to_inspector_tag_union(
|
|||
Loc::at_zero(inspect_tag_var),
|
||||
this_inspect_tag_clos_var,
|
||||
this_inspector_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Inspect.tag "A" [ Inspect.toInspector v1, Inspect.toInspector v2 ]
|
||||
|
@ -997,6 +1005,7 @@ fn wrap_in_inspect_custom(
|
|||
Loc::at_zero(Var(Symbol::INSPECT_APPLY, this_apply_fn_var)),
|
||||
this_apply_clos_var,
|
||||
fmt_var,
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Inspect.apply inspector fmt
|
||||
|
@ -1081,6 +1090,7 @@ fn wrap_in_inspect_custom(
|
|||
Loc::at_zero(Var(Symbol::INSPECT_CUSTOM, this_custom_fn_var)),
|
||||
this_custom_clos_var, // -[clos]->
|
||||
this_custom_inspector_var, // t' ~ Inspector fmt
|
||||
Variable::PURE,
|
||||
));
|
||||
|
||||
// Inspect.custom \fmt -> Inspect.apply inspector fmt
|
||||
|
|
|
@ -520,6 +520,7 @@ impl<'a> LowerParams<'a> {
|
|||
Loc::at_zero(Var(symbol, var)),
|
||||
self.var_store.fresh(),
|
||||
self.var_store.fresh(),
|
||||
self.var_store.fresh(),
|
||||
));
|
||||
|
||||
let body = Call(
|
||||
|
@ -565,6 +566,7 @@ impl<'a> LowerParams<'a> {
|
|||
Loc::at_zero(Var(symbol, var)),
|
||||
self.var_store.fresh(),
|
||||
self.var_store.fresh(),
|
||||
self.var_store.fresh(),
|
||||
));
|
||||
|
||||
Call(
|
||||
|
|
|
@ -5455,7 +5455,7 @@ pub fn with_hole<'a>(
|
|||
}
|
||||
|
||||
Call(boxed, loc_args, _) => {
|
||||
let (fn_var, loc_expr, _lambda_set_var, _ret_var) = *boxed;
|
||||
let (fn_var, loc_expr, _lambda_set_var, _ret_var, _fx_var) = *boxed;
|
||||
|
||||
// even if a call looks like it's by name, it may in fact be by-pointer.
|
||||
// E.g. in `(\f, x -> f x)` the call is in fact by pointer.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue