aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-09-15 16:16:55 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-09-15 16:27:21 +0100
commit04549bf8c34cdb3ea435d8542f2cac6d46bcd30f (patch)
tree49df4a8cb24256fa97180bcd464a0cd5ba71f0ae /gcc/rust/backend
parent4493f1c927c79e5b0933d26e9597044790c22f12 (diff)
downloadgcc-04549bf8c34cdb3ea435d8542f2cac6d46bcd30f.zip
gcc-04549bf8c34cdb3ea435d8542f2cac6d46bcd30f.tar.gz
gcc-04549bf8c34cdb3ea435d8542f2cac6d46bcd30f.tar.bz2
Fix bug when calling method from generic reciever type-bound
When we have a generic function with a specified type bound, this means the method resolution can only resolve this to the trait item. During code generation we must then monomorphize this and lookup the associated impl block item for this trait (if it exists) and call this function. Fixes #678
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile.cc28
1 files changed, 22 insertions, 6 deletions
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 5214b1d..f0e26dc 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -22,6 +22,7 @@
#include "rust-compile-struct-field-expr.h"
#include "rust-hir-trait-resolve.h"
#include "rust-hir-path-probe.h"
+#include "rust-hir-dot-operator.h"
namespace Rust {
namespace Compile {
@@ -171,10 +172,11 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
// item so its up to us to figure out if this path should resolve
// to an trait-impl-block-item or if it can be defaulted to the
// trait-impl-item's definition
+
+ auto root = receiver->get_root ();
std::vector<Resolver::PathProbeCandidate> candidates
= Resolver::PathProbeType::Probe (
- receiver, expr.get_method_name ().get_segment (), true, false,
- true);
+ root, expr.get_method_name ().get_segment (), true, false, true);
if (candidates.size () == 0)
{
@@ -186,6 +188,11 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
rust_assert (ok); // found
rust_assert (trait_item_ref->is_optional ()); // has definition
+ // FIXME Optional means it has a definition and an associated
+ // block which can be a default implementation, if it does not
+ // contain an implementation we should actually return
+ // error_mark_node
+
TyTy::BaseType *self_type = nullptr;
if (!ctx->get_tyctx ()->lookup_type (
expr.get_receiver ()->get_mappings ().get_hirid (),
@@ -209,10 +216,19 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
}
else
{
- Resolver::PathProbeCandidate &candidate = candidates.at (0);
- rust_assert (candidate.is_impl_candidate ());
-
- HIR::ImplItem *impl_item = candidate.item.impl.impl_item;
+ std::vector<Resolver::Adjustment> adjustments;
+ Resolver::PathProbeCandidate *candidate
+ = Resolver::MethodResolution::Select (candidates, root,
+ adjustments);
+
+ // FIXME this will be a case to return error_mark_node, there is
+ // an error scenario where a Trait Foo has a method Bar, but this
+ // receiver does not implement this trait or has an incompatible
+ // implementation and we should just return error_mark_node
+ rust_assert (candidate != nullptr);
+ rust_assert (candidate->is_impl_candidate ());
+
+ HIR::ImplItem *impl_item = candidate->item.impl.impl_item;
TyTy::BaseType *self_type = nullptr;
if (!ctx->get_tyctx ()->lookup_type (