aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-10-22 16:07:18 +0000
committerGitHub <noreply@github.com>2021-10-22 16:07:18 +0000
commita51180ca2db69136bc594b804f799cf084222f20 (patch)
tree44de1b6bd618e97c92ef4033e1e75976f331c547 /gcc
parent94b1da7d971fe354f7a2e479a52e48a4145be768 (diff)
parente0b43ccd05b72f6c7402b87eeeb8e26d18bef92b (diff)
downloadgcc-a51180ca2db69136bc594b804f799cf084222f20.zip
gcc-a51180ca2db69136bc594b804f799cf084222f20.tar.gz
gcc-a51180ca2db69136bc594b804f799cf084222f20.tar.bz2
Merge #762
762: Add missing coercion site code to MethodCallExpr's r=philberty a=philberty Arguments to methods are coercion sites and may have implicit conversions to be performed this adds this missing code for this case. Fixes #755 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-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
+}