aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-compile-expr.cc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-11-26 09:19:08 +0000
committerGitHub <noreply@github.com>2021-11-26 09:19:08 +0000
commit0024bc2f028369b871a65ceb11b2fddfb0f9c3aa (patch)
tree8996e916a4375af6f33d1a835218a0e1fb003fd6 /gcc/rust/backend/rust-compile-expr.cc
parent3b8cbff816c969aa43aca9c611b3c3f9ef5a1af5 (diff)
parentc7af812802ff64a88b4d251dae83377f45c0a8a3 (diff)
downloadgcc-0024bc2f028369b871a65ceb11b2fddfb0f9c3aa.zip
gcc-0024bc2f028369b871a65ceb11b2fddfb0f9c3aa.tar.gz
gcc-0024bc2f028369b871a65ceb11b2fddfb0f9c3aa.tar.bz2
Merge #818
818: Deref operator overloading r=philberty a=philberty This adds initial support for dereferencing operator overloading. We need to be able to use this as part of the autoderef cycle next. It has two default impl's one for '&T' and '&mut T' to apply genericly. The reason it is interesting is from the prototype the deref lang item always returns &Self::Target in all cases regardless of mutability, the lang item here is designed to wrap up any dereference such that when applied it guarentees the type system you will get back an immutable reference to something. The reason for doing this is more clear when thinking about autoderef and method-resolution and how you apply dereference operations to custom types and a test case is included for that. Fixes #809 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/backend/rust-compile-expr.cc')
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc37
1 files changed, 37 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index fb01d8d..6051f50 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -117,6 +117,43 @@ CompileExpr::visit (HIR::NegationExpr &expr)
= ctx->get_backend ()->negation_expression (op, negated_expr, location);
}
+void
+CompileExpr::visit (HIR::DereferenceExpr &expr)
+{
+ TyTy::BaseType *tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &tyty))
+ {
+ rust_fatal_error (expr.get_locus (),
+ "did not resolve type for this TupleExpr");
+ return;
+ }
+
+ tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+
+ // this might be an operator overload situation lets check
+ TyTy::FnType *fntype;
+ bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
+ expr.get_mappings ().get_hirid (), &fntype);
+ if (is_op_overload)
+ {
+ auto lang_item_type = Analysis::RustLangItem::ItemType::DEREF;
+ tree operator_overload_call
+ = resolve_operator_overload (lang_item_type, expr, main_expr, nullptr,
+ expr.get_expr ().get (), nullptr);
+
+ // rust deref always returns a reference from this overload then we can
+ // actually do the indirection
+ main_expr = operator_overload_call;
+ }
+
+ tree expected_type = TyTyResolveCompile::compile (ctx, tyty);
+ bool known_valid = true;
+ translated
+ = ctx->get_backend ()->indirect_expression (expected_type, main_expr,
+ known_valid, expr.get_locus ());
+}
+
tree
CompileExpr::compile_dyn_dispatch_call (const TyTy::DynamicObjectType *dyn,
TyTy::BaseType *receiver,