aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2023-06-13 19:14:27 +0100
committerPhilip Herron <philip.herron@embecosm.com>2023-06-14 08:26:31 +0000
commitc84e7d9db2d33b7684b0a6b4b3ab9d5540adac27 (patch)
tree9ed80010d9c2beb09c200f1ef5104532780ed00c /gcc/rust
parentc021eef8aa73cc0a3a4e992018cab414a17db4c8 (diff)
downloadgcc-c84e7d9db2d33b7684b0a6b4b3ab9d5540adac27.zip
gcc-c84e7d9db2d33b7684b0a6b4b3ab9d5540adac27.tar.gz
gcc-c84e7d9db2d33b7684b0a6b4b3ab9d5540adac27.tar.bz2
gccrs: fortify resolve_method_address to match the types
Fixes #2019 gcc/rust/ChangeLog: * backend/rust-compile-base.cc (HIRCompileBase::resolve_method_address): match the fntype to the candidate gcc/testsuite/ChangeLog: * rust/compile/issue-2019-2.rs: New test. * rust/compile/issue-2019-3.rs: New test. Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/backend/rust-compile-base.cc49
1 files changed, 43 insertions, 6 deletions
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index caa10ed..988c675 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -770,6 +770,10 @@ HIRCompileBase::resolve_method_address (TyTy::FnType *fntype,
TyTy::BaseType *receiver,
Location expr_locus)
{
+ rust_debug_loc (expr_locus, "resolve_method_address for %s and receiver %s",
+ fntype->debug_str ().c_str (),
+ receiver->debug_str ().c_str ());
+
DefId id = fntype->get_id ();
rust_assert (id != UNKNOWN_DEFID);
@@ -823,13 +827,46 @@ HIRCompileBase::resolve_method_address (TyTy::FnType *fntype,
ctx, fntype, true, expr_locus);
}
- // 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
+ const Resolver::PathProbeCandidate *selectedCandidate = nullptr;
+ rust_debug_loc (expr_locus, "resolved to %lu candidates", candidates.size ());
+
+ // filter for the possible case of non fn type items
+ std::set<Resolver::PathProbeCandidate> filteredFunctionCandidates;
+ for (auto &candidate : candidates)
+ {
+ bool is_fntype = candidate.ty->get_kind () == TyTy::TypeKind::FNDEF;
+ if (!is_fntype)
+ continue;
+
+ filteredFunctionCandidates.insert (candidate);
+ }
+
+ // look for the exact fntype
+ for (auto &candidate : filteredFunctionCandidates)
+ {
+ bool compatable
+ = Resolver::types_compatable (TyTy::TyWithLocation (candidate.ty),
+ TyTy::TyWithLocation (fntype), expr_locus,
+ false);
+
+ rust_debug_loc (candidate.locus, "candidate: %s vs %s compatable=%s",
+ candidate.ty->debug_str ().c_str (),
+ fntype->debug_str ().c_str (),
+ compatable ? "true" : "false");
+
+ if (compatable)
+ {
+ selectedCandidate = &candidate;
+ break;
+ }
+ }
+
+ // FIXME eventually this should just return error mark node when we support
+ // going through all the passes
+ rust_assert (selectedCandidate != nullptr);
- rust_assert (candidates.size () == 1);
- auto &candidate = *candidates.begin ();
+ // lets compile it
+ const Resolver::PathProbeCandidate &candidate = *selectedCandidate;
rust_assert (candidate.is_impl_candidate ());
rust_assert (candidate.ty->get_kind () == TyTy::TypeKind::FNDEF);
TyTy::FnType *candidate_call = static_cast<TyTy::FnType *> (candidate.ty);