Skip to content

Commit 0f74fe2

Browse files
committed
Refactor operator overloading work to be more reuseable
1 parent a7fb60b commit 0f74fe2

File tree

3 files changed

+368
-597
lines changed

3 files changed

+368
-597
lines changed

gcc/rust/backend/rust-compile-expr.cc

Lines changed: 119 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -39,100 +39,18 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
3939
TyTy::FnType *fntype;
4040
bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
4141
expr.get_mappings ().get_hirid (), &fntype);
42-
if (!is_op_overload)
42+
if (is_op_overload)
4343
{
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 ());
4648
return;
4749
}
4850

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 ();
13351
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 ());
13654
}
13755

13856
void
@@ -148,106 +66,30 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
14866
TyTy::FnType *fntype;
14967
bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
15068
expr.get_mappings ().get_hirid (), &fntype);
151-
if (!is_op_overload)
69+
if (is_op_overload)
15270
{
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);
16081
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);
18782

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 ());
20783
return;
20884
}
20985

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);
25193
}
25294

25395
Bexpression *
@@ -427,5 +269,99 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
427269
}
428270
}
429271

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+
430366
} // namespace Compile
431367
} // namespace Rust

gcc/rust/backend/rust-compile-expr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,12 @@ class CompileExpr : public HIRCompileBase
10051005
Analysis::NodeMapping expr_mappings,
10061006
Location expr_locus);
10071007

1008+
Bexpression *
1009+
resolve_operator_overload (Analysis::RustLangItem::ItemType lang_item_type,
1010+
HIR::OperatorExpr &expr, Bexpression *lhs,
1011+
Bexpression *rhs, HIR::Expr *lhs_expr,
1012+
HIR::Expr *rhs_expr);
1013+
10081014
private:
10091015
CompileExpr (Context *ctx)
10101016
: HIRCompileBase (ctx), translated (nullptr), capacity_expr (nullptr)

0 commit comments

Comments
 (0)