diff options
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 28 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/trait10.rs | 43 |
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 +} |