@@ -1693,53 +1693,10 @@ CompileExpr::visit (HIR::CallExpr &expr)
1693
1693
auto fn_address = CompileExpr::Compile (expr.get_fnexpr (), ctx);
1694
1694
1695
1695
// is this a closure call?
1696
- if (RS_CLOSURE_TYPE_P (TREE_TYPE (fn_address)))
1697
- {
1698
- rust_assert (tyty->get_kind () == TyTy::TypeKind::CLOSURE);
1699
- TyTy::ClosureType *closure = static_cast <TyTy::ClosureType *> (tyty);
1700
-
1701
- std::vector<tree> tuple_arg_vals;
1702
- for (auto &argument : expr.get_arguments ())
1703
- {
1704
- auto rvalue = CompileExpr::Compile (argument.get (), ctx);
1705
- tuple_arg_vals.push_back (rvalue);
1706
- }
1707
-
1708
- tree tuple_args_tyty
1709
- = TyTyResolveCompile::compile (ctx, &closure->get_parameters ());
1710
- tree tuple_args
1711
- = ctx->get_backend ()->constructor_expression (tuple_args_tyty, false ,
1712
- tuple_arg_vals, -1 ,
1713
- expr.get_locus ());
1714
-
1715
- // need to apply any autoderef's to the self argument
1716
- HirId autoderef_mappings_id = expr.get_mappings ().get_hirid ();
1717
- std::vector<Resolver::Adjustment> *adjustments = nullptr ;
1718
- bool ok
1719
- = ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id,
1720
- &adjustments);
1721
- rust_assert (ok);
1722
-
1723
- // apply adjustments for the fn call
1724
- tree self
1725
- = resolve_adjustements (*adjustments, fn_address, expr.get_locus ());
1726
-
1727
- // args are always self, and the tuple of the args we are passing where
1728
- // self is the path of the call-expr in this case the fn_address
1729
- std::vector<tree> args;
1730
- args.push_back (self);
1731
- args.push_back (tuple_args);
1732
-
1733
- // get the fn call address
1734
- tree closure_call_site = ctx->lookup_closure_decl (closure);
1735
- tree closure_call_address
1736
- = address_expression (closure_call_site, expr.get_locus ());
1737
- translated
1738
- = ctx->get_backend ()->call_expression (closure_call_address, args,
1739
- nullptr /* static chain ?*/ ,
1740
- expr.get_locus ());
1741
- return ;
1742
- }
1696
+ bool possible_trait_call
1697
+ = generate_possible_fn_trait_call (expr, fn_address, &translated);
1698
+ if (possible_trait_call)
1699
+ return ;
1743
1700
1744
1701
bool is_varadic = false ;
1745
1702
if (tyty->get_kind () == TyTy::TypeKind::FNDEF)
@@ -3073,5 +3030,70 @@ CompileExpr::generate_closure_fntype (HIR::ClosureExpr &expr,
3073
3030
return TyTyResolveCompile::compile (ctx, item_tyty);
3074
3031
}
3075
3032
3033
+ bool
3034
+ CompileExpr::generate_possible_fn_trait_call (HIR::CallExpr &expr,
3035
+ tree receiver, tree *result)
3036
+ {
3037
+ TyTy::FnType *fn_sig = nullptr ;
3038
+ bool found_overload = ctx->get_tyctx ()->lookup_operator_overload (
3039
+ expr.get_mappings ().get_hirid (), &fn_sig);
3040
+ if (!found_overload)
3041
+ return false ;
3042
+
3043
+ auto id = fn_sig->get_ty_ref ();
3044
+ auto dId = fn_sig->get_id ();
3045
+
3046
+ tree function = error_mark_node;
3047
+ bool found_closure = ctx->lookup_function_decl (id, &function, dId, fn_sig);
3048
+ if (!found_closure)
3049
+ {
3050
+ // something went wrong we still return true as this was meant to be an fn
3051
+ // trait call
3052
+ *result = error_mark_node;
3053
+ return true ;
3054
+ }
3055
+
3056
+ // need to apply any autoderef's to the self argument
3057
+ HirId autoderef_mappings_id = expr.get_mappings ().get_hirid ();
3058
+ std::vector<Resolver::Adjustment> *adjustments = nullptr ;
3059
+ bool ok = ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id,
3060
+ &adjustments);
3061
+ rust_assert (ok);
3062
+
3063
+ // apply adjustments for the fn call
3064
+ tree self = resolve_adjustements (*adjustments, receiver, expr.get_locus ());
3065
+
3066
+ // resolve the arguments
3067
+ std::vector<tree> tuple_arg_vals;
3068
+ for (auto &argument : expr.get_arguments ())
3069
+ {
3070
+ auto rvalue = CompileExpr::Compile (argument.get (), ctx);
3071
+ tuple_arg_vals.push_back (rvalue);
3072
+ }
3073
+
3074
+ // this is always the 2nd argument in the function signature
3075
+ tree fnty = TREE_TYPE (function);
3076
+ tree fn_arg_tys = TYPE_ARG_TYPES (fnty);
3077
+ tree tuple_args_tyty_chain = TREE_CHAIN (fn_arg_tys);
3078
+ tree tuple_args_tyty = TREE_VALUE (tuple_args_tyty_chain);
3079
+
3080
+ tree tuple_args
3081
+ = ctx->get_backend ()->constructor_expression (tuple_args_tyty, false ,
3082
+ tuple_arg_vals, -1 ,
3083
+ expr.get_locus ());
3084
+
3085
+ // args are always self, and the tuple of the args we are passing where
3086
+ // self is the path of the call-expr in this case the fn_address
3087
+ std::vector<tree> args;
3088
+ args.push_back (self);
3089
+ args.push_back (tuple_args);
3090
+
3091
+ tree call_address = address_expression (function, expr.get_locus ());
3092
+ *result = ctx->get_backend ()->call_expression (call_address, args,
3093
+ nullptr /* static chain ?*/ ,
3094
+ expr.get_locus ());
3095
+ return true ;
3096
+ }
3097
+
3076
3098
} // namespace Compile
3077
3099
} // namespace Rust
0 commit comments