aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-09-15 15:29:42 +0000
committerGitHub <noreply@github.com>2021-09-15 15:29:42 +0000
commit887598b92f28d69141b0091d09998672c07e131c (patch)
tree82d424164ca7e906c477de1cf3bb2c359a837df6 /gcc/rust/backend
parentaf472f5931920b821d2e483749563c902424096c (diff)
parent04549bf8c34cdb3ea435d8542f2cac6d46bcd30f (diff)
downloadgcc-887598b92f28d69141b0091d09998672c07e131c.zip
gcc-887598b92f28d69141b0091d09998672c07e131c.tar.gz
gcc-887598b92f28d69141b0091d09998672c07e131c.tar.bz2
Merge #679
679: Fix bug when calling method from generic reciever type-bound r=philberty a=philberty 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 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
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 (