https://gcc.gnu.org/g:29e6cfbd27776087073f3f0d8295c5598a893d36
commit r16-2884-g29e6cfbd27776087073f3f0d8295c5598a893d36 Author: Philip Herron <herron.phi...@googlemail.com> Date: Fri Jun 20 17:49:32 2025 +0100 gccrs: Ensure we look at the bounds behind a reference When type checking expressions that involve references, we need to examine the bounds of the referenced type to properly resolve traits and methods. gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-expr.cc: Look at bounds behind references. * typecheck/rust-hir-type-check-expr.h: Add helper method. Diff: --- gcc/rust/typecheck/rust-hir-type-check-expr.cc | 37 +++++++++++++++++++++----- gcc/rust/typecheck/rust-hir-type-check-expr.h | 3 ++- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 81d95c83239f..753d3915f69f 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -2086,16 +2086,13 @@ TypeCheckExpr::resolve_operator_overload ( HIR::PathIdentSegment TypeCheckExpr::resolve_possible_fn_trait_call_method_name ( - TyTy::BaseType &receiver, TyTy::TypeBoundPredicate *associated_predicate) + const TyTy::BaseType &receiver, + TyTy::TypeBoundPredicate *associated_predicate) { - // Question - // do we need to probe possible bounds here? I think not, i think when we - // support Fn traits they are explicitly specified - // FIXME // the logic to map the FnTrait to their respective call trait-item is // duplicated over in the backend/rust-compile-expr.cc - for (auto &bound : receiver.get_specified_bounds ()) + for (const auto &bound : receiver.get_specified_bounds ()) { bool found_fn = bound.get_name ().compare ("Fn") == 0; bool found_fn_mut = bound.get_name ().compare ("FnMut") == 0; @@ -2118,6 +2115,34 @@ TypeCheckExpr::resolve_possible_fn_trait_call_method_name ( } } + if (receiver.is<TyTy::ReferenceType> ()) + { + const auto &ref = static_cast<const TyTy::ReferenceType &> (receiver); + const auto &underlying = *ref.get_base (); + for (const auto &bound : underlying.get_specified_bounds ()) + { + bool found_fn = bound.get_name ().compare ("Fn") == 0; + bool found_fn_mut = bound.get_name ().compare ("FnMut") == 0; + bool found_fn_once = bound.get_name ().compare ("FnOnce") == 0; + + if (found_fn) + { + *associated_predicate = bound; + return HIR::PathIdentSegment ("call"); + } + else if (found_fn_mut) + { + *associated_predicate = bound; + return HIR::PathIdentSegment ("call_mut"); + } + else if (found_fn_once) + { + *associated_predicate = bound; + return HIR::PathIdentSegment ("call_once"); + } + } + } + // nothing *associated_predicate = TyTy::TypeBoundPredicate::error (); return HIR::PathIdentSegment (""); diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index e0a3278fb82d..531197436853 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -109,7 +109,8 @@ protected: TyTy::BaseType **result); HIR::PathIdentSegment resolve_possible_fn_trait_call_method_name ( - TyTy::BaseType &receiver, TyTy::TypeBoundPredicate *associated_predicate); + const TyTy::BaseType &receiver, + TyTy::TypeBoundPredicate *associated_predicate); private: TypeCheckExpr ();