@@ -39,100 +39,18 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
39
39
TyTy::FnType *fntype;
40
40
bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
41
41
expr.get_mappings ().get_hirid (), &fntype);
42
- if (! is_op_overload)
42
+ if (is_op_overload)
43
43
{
44
- translated = ctx->get_backend ()->arithmetic_or_logical_expression (
45
- op, lhs, rhs, expr.get_locus ());
44
+ auto lang_item_type
45
+ = Analysis::RustLangItem::OperatorToLangItem (expr.get_expr_type ());
46
+ translated = resolve_operator_overload (lang_item_type, expr, lhs, rhs,
47
+ expr.get_lhs (), expr.get_rhs ());
46
48
return ;
47
49
}
48
50
49
- // lookup the resolved name
50
- NodeId resolved_node_id = UNKNOWN_NODEID;
51
- if (!ctx->get_resolver ()->lookup_resolved_name (
52
- expr.get_mappings ().get_nodeid (), &resolved_node_id))
53
- {
54
- rust_error_at (expr.get_locus (), " failed to lookup resolved MethodCall" );
55
- return ;
56
- }
57
-
58
- // reverse lookup
59
- HirId ref;
60
- if (!ctx->get_mappings ()->lookup_node_to_hir (
61
- expr.get_mappings ().get_crate_num (), resolved_node_id, &ref))
62
- {
63
- rust_fatal_error (expr.get_locus (), " reverse lookup failure" );
64
- return ;
65
- }
66
-
67
- TyTy::BaseType *receiver = nullptr ;
68
- bool ok
69
- = ctx->get_tyctx ()->lookup_receiver (expr.get_mappings ().get_hirid (),
70
- &receiver);
71
- rust_assert (ok);
72
-
73
- bool is_dyn_dispatch
74
- = receiver->get_root ()->get_kind () == TyTy::TypeKind::DYNAMIC;
75
- bool is_generic_receiver = receiver->get_kind () == TyTy::TypeKind::PARAM;
76
- if (is_generic_receiver)
77
- {
78
- TyTy::ParamType *p = static_cast <TyTy::ParamType *> (receiver);
79
- receiver = p->resolve ();
80
- }
81
-
82
- if (is_dyn_dispatch)
83
- {
84
- const TyTy::DynamicObjectType *dyn
85
- = static_cast <const TyTy::DynamicObjectType *> (receiver->get_root ());
86
-
87
- std::vector<HIR::Expr *> arguments;
88
- arguments.push_back (expr.get_rhs ());
89
-
90
- translated = compile_dyn_dispatch_call (dyn, receiver, fntype, lhs,
91
- arguments, expr.get_locus ());
92
- return ;
93
- }
94
-
95
- // lookup compiled functions since it may have already been compiled
96
- HIR::PathIdentSegment segment_name (" add" );
97
- Bexpression *fn_expr
98
- = resolve_method_address (fntype, ref, receiver, segment_name,
99
- expr.get_mappings (), expr.get_locus ());
100
-
101
- // lookup the autoderef mappings
102
- std::vector<Resolver::Adjustment> *adjustments = nullptr ;
103
- ok = ctx->get_tyctx ()->lookup_autoderef_mappings (
104
- expr.get_mappings ().get_hirid (), &adjustments);
105
- rust_assert (ok);
106
-
107
- Bexpression *self = lhs;
108
- for (auto &adjustment : *adjustments)
109
- {
110
- switch (adjustment.get_type ())
111
- {
112
- case Resolver::Adjustment::AdjustmentType::IMM_REF:
113
- case Resolver::Adjustment::AdjustmentType::MUT_REF:
114
- self = ctx->get_backend ()->address_expression (
115
- self, expr.get_lhs ()->get_locus ());
116
- break ;
117
-
118
- case Resolver::Adjustment::AdjustmentType::DEREF_REF:
119
- Btype *expected_type
120
- = TyTyResolveCompile::compile (ctx, adjustment.get_expected ());
121
- self = ctx->get_backend ()->indirect_expression (
122
- expected_type, self, true , /* known_valid*/
123
- expr.get_lhs ()->get_locus ());
124
- break ;
125
- }
126
- }
127
-
128
- std::vector<Bexpression *> args;
129
- args.push_back (self); // adjusted self
130
- args.push_back (rhs);
131
-
132
- auto fncontext = ctx->peek_fn ();
133
51
translated
134
- = ctx->get_backend ()->call_expression (fncontext. fndecl , fn_expr, args ,
135
- nullptr , expr.get_locus ());
52
+ = ctx->get_backend ()->arithmetic_or_logical_expression (op, lhs, rhs ,
53
+ expr.get_locus ());
136
54
}
137
55
138
56
void
@@ -148,106 +66,30 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
148
66
TyTy::FnType *fntype;
149
67
bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
150
68
expr.get_mappings ().get_hirid (), &fntype);
151
- if (! is_op_overload)
69
+ if (is_op_overload)
152
70
{
153
- auto operator_expr
154
- = ctx->get_backend ()->arithmetic_or_logical_expression (
155
- op, lhs, rhs, expr.get_locus ());
156
- Bstatement *assignment
157
- = ctx->get_backend ()->assignment_statement (fn.fndecl , lhs,
158
- operator_expr,
159
- expr.get_locus ());
71
+ auto lang_item_type
72
+ = Analysis::RustLangItem::CompoundAssignmentOperatorToLangItem (
73
+ expr.get_expr_type ());
74
+ auto compound_assignment
75
+ = resolve_operator_overload (lang_item_type, expr, lhs, rhs,
76
+ expr.get_left_expr ().get (),
77
+ expr.get_right_expr ().get ());
78
+ auto assignment
79
+ = ctx->get_backend ()->expression_statement (fn.fndecl ,
80
+ compound_assignment);
160
81
ctx->add_statement (assignment);
161
- return ;
162
- }
163
-
164
- // lookup the resolved name
165
- NodeId resolved_node_id = UNKNOWN_NODEID;
166
- if (!ctx->get_resolver ()->lookup_resolved_name (
167
- expr.get_mappings ().get_nodeid (), &resolved_node_id))
168
- {
169
- rust_error_at (expr.get_locus (), " failed to lookup resolved MethodCall" );
170
- return ;
171
- }
172
-
173
- // reverse lookup
174
- HirId ref;
175
- if (!ctx->get_mappings ()->lookup_node_to_hir (
176
- expr.get_mappings ().get_crate_num (), resolved_node_id, &ref))
177
- {
178
- rust_fatal_error (expr.get_locus (), " reverse lookup failure" );
179
- return ;
180
- }
181
-
182
- TyTy::BaseType *receiver = nullptr ;
183
- bool ok
184
- = ctx->get_tyctx ()->lookup_receiver (expr.get_mappings ().get_hirid (),
185
- &receiver);
186
- rust_assert (ok);
187
82
188
- bool is_dyn_dispatch
189
- = receiver->get_root ()->get_kind () == TyTy::TypeKind::DYNAMIC;
190
- bool is_generic_receiver = receiver->get_kind () == TyTy::TypeKind::PARAM;
191
- if (is_generic_receiver)
192
- {
193
- TyTy::ParamType *p = static_cast <TyTy::ParamType *> (receiver);
194
- receiver = p->resolve ();
195
- }
196
-
197
- if (is_dyn_dispatch)
198
- {
199
- const TyTy::DynamicObjectType *dyn
200
- = static_cast <const TyTy::DynamicObjectType *> (receiver->get_root ());
201
-
202
- std::vector<HIR::Expr *> arguments;
203
- arguments.push_back (expr.get_right_expr ().get ());
204
-
205
- translated = compile_dyn_dispatch_call (dyn, receiver, fntype, lhs,
206
- arguments, expr.get_locus ());
207
83
return ;
208
84
}
209
85
210
- // lookup compiled functions since it may have already been compiled
211
- HIR::PathIdentSegment segment_name (" add_assign" );
212
- Bexpression *fn_expr
213
- = resolve_method_address (fntype, ref, receiver, segment_name,
214
- expr.get_mappings (), expr.get_locus ());
215
-
216
- // lookup the autoderef mappings
217
- std::vector<Resolver::Adjustment> *adjustments = nullptr ;
218
- ok = ctx->get_tyctx ()->lookup_autoderef_mappings (
219
- expr.get_mappings ().get_hirid (), &adjustments);
220
- rust_assert (ok);
221
-
222
- Bexpression *self = lhs;
223
- for (auto &adjustment : *adjustments)
224
- {
225
- switch (adjustment.get_type ())
226
- {
227
- case Resolver::Adjustment::AdjustmentType::IMM_REF:
228
- case Resolver::Adjustment::AdjustmentType::MUT_REF:
229
- self = ctx->get_backend ()->address_expression (
230
- self, expr.get_left_expr ()->get_locus ());
231
- break ;
232
-
233
- case Resolver::Adjustment::AdjustmentType::DEREF_REF:
234
- Btype *expected_type
235
- = TyTyResolveCompile::compile (ctx, adjustment.get_expected ());
236
- self = ctx->get_backend ()->indirect_expression (
237
- expected_type, self, true , /* known_valid*/
238
- expr.get_left_expr ()->get_locus ());
239
- break ;
240
- }
241
- }
242
-
243
- std::vector<Bexpression *> args;
244
- args.push_back (self); // adjusted self
245
- args.push_back (rhs);
246
-
247
- auto fncontext = ctx->peek_fn ();
248
- translated
249
- = ctx->get_backend ()->call_expression (fncontext.fndecl , fn_expr, args,
250
- nullptr , expr.get_locus ());
86
+ auto operator_expr
87
+ = ctx->get_backend ()->arithmetic_or_logical_expression (op, lhs, rhs,
88
+ expr.get_locus ());
89
+ Bstatement *assignment
90
+ = ctx->get_backend ()->assignment_statement (fn.fndecl , lhs, operator_expr,
91
+ expr.get_locus ());
92
+ ctx->add_statement (assignment);
251
93
}
252
94
253
95
Bexpression *
@@ -427,5 +269,99 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
427
269
}
428
270
}
429
271
272
+ Bexpression *
273
+ CompileExpr::resolve_operator_overload (
274
+ Analysis::RustLangItem::ItemType lang_item_type, HIR::OperatorExpr &expr,
275
+ Bexpression *lhs, Bexpression *rhs, HIR::Expr *lhs_expr, HIR::Expr *rhs_expr)
276
+ {
277
+ TyTy::FnType *fntype;
278
+ bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
279
+ expr.get_mappings ().get_hirid (), &fntype);
280
+ rust_assert (is_op_overload);
281
+
282
+ // lookup the resolved name
283
+ NodeId resolved_node_id = UNKNOWN_NODEID;
284
+ bool ok = ctx->get_resolver ()->lookup_resolved_name (
285
+ expr.get_mappings ().get_nodeid (), &resolved_node_id);
286
+ rust_assert (ok);
287
+
288
+ // reverse lookup
289
+ HirId ref;
290
+ ok = ctx->get_mappings ()->lookup_node_to_hir (
291
+ expr.get_mappings ().get_crate_num (), resolved_node_id, &ref);
292
+ rust_assert (ok);
293
+
294
+ TyTy::BaseType *receiver = nullptr ;
295
+ ok = ctx->get_tyctx ()->lookup_receiver (expr.get_mappings ().get_hirid (),
296
+ &receiver);
297
+ rust_assert (ok);
298
+
299
+ bool is_dyn_dispatch
300
+ = receiver->get_root ()->get_kind () == TyTy::TypeKind::DYNAMIC;
301
+ bool is_generic_receiver = receiver->get_kind () == TyTy::TypeKind::PARAM;
302
+ if (is_generic_receiver)
303
+ {
304
+ TyTy::ParamType *p = static_cast <TyTy::ParamType *> (receiver);
305
+ receiver = p->resolve ();
306
+ }
307
+
308
+ if (is_dyn_dispatch)
309
+ {
310
+ const TyTy::DynamicObjectType *dyn
311
+ = static_cast <const TyTy::DynamicObjectType *> (receiver->get_root ());
312
+
313
+ std::vector<HIR::Expr *> arguments;
314
+ arguments.push_back (rhs_expr);
315
+
316
+ return compile_dyn_dispatch_call (dyn, receiver, fntype, lhs, arguments,
317
+ expr.get_locus ());
318
+ }
319
+
320
+ // lookup compiled functions since it may have already been compiled
321
+ HIR::PathIdentSegment segment_name (
322
+ Analysis::RustLangItem::ToString (lang_item_type));
323
+ Bexpression *fn_expr
324
+ = resolve_method_address (fntype, ref, receiver, segment_name,
325
+ expr.get_mappings (), expr.get_locus ());
326
+
327
+ // lookup the autoderef mappings
328
+ std::vector<Resolver::Adjustment> *adjustments = nullptr ;
329
+ ok = ctx->get_tyctx ()->lookup_autoderef_mappings (
330
+ expr.get_mappings ().get_hirid (), &adjustments);
331
+ rust_assert (ok);
332
+
333
+ // FIXME refactor this out
334
+ Bexpression *self = lhs;
335
+ for (auto &adjustment : *adjustments)
336
+ {
337
+ switch (adjustment.get_type ())
338
+ {
339
+ case Resolver::Adjustment::AdjustmentType::IMM_REF:
340
+ case Resolver::Adjustment::AdjustmentType::MUT_REF:
341
+ self
342
+ = ctx->get_backend ()->address_expression (self,
343
+ lhs_expr->get_locus ());
344
+ break ;
345
+
346
+ case Resolver::Adjustment::AdjustmentType::DEREF_REF:
347
+ Btype *expected_type
348
+ = TyTyResolveCompile::compile (ctx, adjustment.get_expected ());
349
+ self
350
+ = ctx->get_backend ()->indirect_expression (expected_type, self,
351
+ true , /* known_valid*/
352
+ lhs_expr->get_locus ());
353
+ break ;
354
+ }
355
+ }
356
+
357
+ std::vector<Bexpression *> args;
358
+ args.push_back (self); // adjusted self
359
+ args.push_back (rhs);
360
+
361
+ auto fncontext = ctx->peek_fn ();
362
+ return ctx->get_backend ()->call_expression (fncontext.fndecl , fn_expr, args,
363
+ nullptr , expr.get_locus ());
364
+ }
365
+
430
366
} // namespace Compile
431
367
} // namespace Rust
0 commit comments