aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-09-13 15:31:19 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-09-14 13:23:56 +0100
commit002313b343746f8c72b62522e48e04fa0953b2d0 (patch)
treed393eecd5333696158e868e907ae93f7530de8ec /gcc/rust/backend
parentc644ee4c4351e3590f5396e94ec24ad7b828a954 (diff)
downloadgcc-002313b343746f8c72b62522e48e04fa0953b2d0.zip
gcc-002313b343746f8c72b62522e48e04fa0953b2d0.tar.gz
gcc-002313b343746f8c72b62522e48e04fa0953b2d0.tar.bz2
Initial autoderef support for method calls
There is compiler magic for method calls the self parameter can be of several forms: - specified type (self: Type) - immutable Self (self) - mutable Self (mut self) - immutable reference (&self) - mutable reference (&mut self) This updates our HIR lowering to actually lower this correctly and apply the apropriate Self type to the TyTy::FnDef. The code used to just default to plain Self ignoring any modifiers. Rust also allows something called the autoderef cycle to coerce the receiver to the correct type for the function such as: ```rust struct Foo(i32); impl Foo { fn bar(&self) { } } fn main() { let a = Foo(123); a.bar(); } ``` In this example the method call is expected to apply an implict reference to variable 'a' such that the method call becomes: ``` Foo::bar(&a); ``` The algorithm is detailed here: https://doc.rust-lang.org/nightly/nomicon/dot-operator.html 1. Try to match Self 2. Apply an immutable Reference and Try again 3. Apply an mutable Reference and Try again 4. Can we dereference ? [deref and go back to 1] else [quit] This is not 100% complete since we do not yet support operator overloading so we wil require an update to support the Deref operator overload for more complex types. Fixes: #241
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile.cc26
1 files changed, 26 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index ef2c16a..5214b1d 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -277,6 +277,32 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
// method receiver
Bexpression *self = CompileExpr::Compile (expr.get_receiver ().get (), ctx);
rust_assert (self != nullptr);
+
+ // lookup the autoderef mappings
+ std::vector<Resolver::Adjustment> *adjustments = nullptr;
+ ok = ctx->get_tyctx ()->lookup_autoderef_mappings (
+ expr.get_mappings ().get_hirid (), &adjustments);
+ rust_assert (ok);
+
+ for (auto &adjustment : *adjustments)
+ {
+ switch (adjustment.get_type ())
+ {
+ case Resolver::Adjustment::AdjustmentType::IMM_REF:
+ case Resolver::Adjustment::AdjustmentType::MUT_REF:
+ self = ctx->get_backend ()->address_expression (
+ self, expr.get_receiver ()->get_locus ());
+ break;
+
+ case Resolver::Adjustment::AdjustmentType::DEREF_REF:
+ Btype *expected_type
+ = TyTyResolveCompile::compile (ctx, adjustment.get_expected ());
+ self = ctx->get_backend ()->indirect_expression (
+ expected_type, self, true, /* known_valid*/
+ expr.get_receiver ()->get_locus ());
+ break;
+ }
+ }
args.push_back (self);
// normal args