aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/backend/rust-compile.cc28
-rw-r--r--gcc/testsuite/rust/execute/torture/trait10.rs43
2 files changed, 65 insertions, 6 deletions
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index f97f701..40e2f86 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -451,8 +451,6 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
}
}
- std::vector<Bexpression *> args;
-
// lookup the autoderef mappings
std::vector<Resolver::Adjustment> *adjustments = nullptr;
ok = ctx->get_tyctx ()->lookup_autoderef_mappings (
@@ -478,13 +476,31 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
break;
}
}
- args.push_back (self);
+
+ std::vector<Bexpression *> args;
+ args.push_back (self); // adjusted self
// normal args
- for (auto &argument : expr.get_arguments ())
+ for (size_t i = 0; i < expr.get_arguments ().size (); i++)
{
- Bexpression *compiled_expr = CompileExpr::Compile (argument.get (), ctx);
- args.push_back (compiled_expr);
+ auto &argument = expr.get_arguments ().at (i);
+ auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+
+ // assignments are coercion sites so lets convert the rvalue if
+ // necessary, offset from the already adjusted implicit self
+ bool ok;
+ TyTy::BaseType *expected = fntype->param_at (i + 1).second;
+
+ TyTy::BaseType *actual = nullptr;
+ ok = ctx->get_tyctx ()->lookup_type (
+ argument->get_mappings ().get_hirid (), &actual);
+ rust_assert (ok);
+
+ // coerce it if required
+ rvalue = coercion_site (rvalue, actual, expected, expr.get_locus ());
+
+ // add it to the list
+ args.push_back (rvalue);
}
auto fncontext = ctx->peek_fn ();
diff --git a/gcc/testsuite/rust/execute/torture/trait10.rs b/gcc/testsuite/rust/execute/torture/trait10.rs
new file mode 100644
index 0000000..615df423
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait10.rs
@@ -0,0 +1,43 @@
+/* { dg-output "123\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+ fn baz(&self);
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+impl Bar for Foo {
+ fn baz(&self) {
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, self.0);
+ }
+ }
+}
+
+struct S;
+impl S {
+ fn dynamic_dispatch(self, t: &dyn Bar) {
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ t.baz();
+ }
+}
+
+pub fn main() -> i32 {
+ let a;
+ a = &Foo(123);
+
+ let b;
+ b = S;
+
+ b.dynamic_dispatch(a);
+
+ 0
+}