@@ -135,6 +135,121 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
135
135
nullptr , expr.get_locus ());
136
136
}
137
137
138
+ void
139
+ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
140
+ {
141
+ fncontext fn = ctx->peek_fn ();
142
+
143
+ auto op = expr.get_expr_type ();
144
+ auto lhs = CompileExpr::Compile (expr.get_left_expr ().get (), ctx);
145
+ auto rhs = CompileExpr::Compile (expr.get_right_expr ().get (), ctx);
146
+
147
+ // this might be an operator overload situation lets check
148
+ TyTy::FnType *fntype;
149
+ bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
150
+ expr.get_mappings ().get_hirid (), &fntype);
151
+ if (!is_op_overload)
152
+ {
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 ());
160
+ 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
+
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
+ return ;
208
+ }
209
+
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 ());
251
+ }
252
+
138
253
Bexpression *
139
254
CompileExpr::compile_dyn_dispatch_call (const TyTy::DynamicObjectType *dyn,
140
255
TyTy::BaseType *receiver,
0 commit comments