diff options
author | Philip Herron <herron.philip@googlemail.com> | 2023-06-13 19:14:27 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2023-06-14 08:26:31 +0000 |
commit | c84e7d9db2d33b7684b0a6b4b3ab9d5540adac27 (patch) | |
tree | 9ed80010d9c2beb09c200f1ef5104532780ed00c /gcc/rust | |
parent | c021eef8aa73cc0a3a4e992018cab414a17db4c8 (diff) | |
download | gcc-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.cc | 49 |
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); |