aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2025-02-03 16:19:30 +0000
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-24 13:07:02 +0100
commit6711c73135612c02aab536899917eb3413a8327d (patch)
treec363bde19df99a3b8a85ffa42f9e2ebfa97b5bfe /gcc/rust/backend
parente09a03982cfb694509034c560f1c762bce8ce574 (diff)
downloadgcc-6711c73135612c02aab536899917eb3413a8327d.zip
gcc-6711c73135612c02aab536899917eb3413a8327d.tar.gz
gcc-6711c73135612c02aab536899917eb3413a8327d.tar.bz2
gccrs: Fix compilation of trait-items which map to impl items
When we have paths such as Try::from_error the Try references the Trait and then from_error references the from_error trait item. So this resolves directly to a trait implementation which has the type: fn <Self> (v: placeholder) -> Self Remember that a path such as: Try::from_error gets handled by doing a clever substitution: <T? as Try>::from_error The main piece here is that we resolve this function type and for monomoprhization we know this is a trait call but we know that all trait's have an implicit Self type param which in this case is Result<i32, i32> so when it comes to knowing which impl block this is we got rid of the old bad insert/lookup receiver hack and use the specified type to know which impl block we are talking about to generate the function. The hard part here is inside rust-compil-item.cc, where we have the 'concete' type which is the trait item fntype of: fn <Result<i32, i32>> (v : i32) -> Result<i32,i32> This does not really match the signiture of the impl item for Result which is: fn <T, E> (v: i32) -> Result<T, E> So what we need to do is actually infer this by inputing inference variables on the impl fntype then unify'ing the trait object to this to compute the types of this to monomorphize this. Fixes Rust-GCC#3381 gcc/rust/ChangeLog: * backend/rust-compile-expr.cc (CompileExpr::visit): remove receiver interface * backend/rust-compile-item.cc (CompileItem::visit): monomorphize trait to impl item * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): use trait item Self * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): remove receiver interface (TypeCheckExpr::resolve_fn_trait_call): likewise * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): likewise (TypeCheckExpr::resolve_segments): likewise * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise * typecheck/rust-hir-type-check.h: likewise * typecheck/rust-typecheck-context.cc (TypeCheckContext::insert_receiver): remove (TypeCheckContext::lookup_receiver): remove gcc/testsuite/ChangeLog: * rust/execute/torture/issue-3381.rs: New test. Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc8
-rw-r--r--gcc/rust/backend/rust-compile-item.cc27
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc16
3 files changed, 39 insertions, 12 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 48713e7..21f4ca1 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1394,8 +1394,8 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup_fntype);
TyTy::BaseType *receiver = nullptr;
- ok = ctx->get_tyctx ()->lookup_receiver (expr.get_mappings ().get_hirid (),
- &receiver);
+ ok = ctx->get_tyctx ()->lookup_type (
+ expr.get_receiver ().get_mappings ().get_hirid (), &receiver);
rust_assert (ok);
bool is_dyn_dispatch
@@ -1532,8 +1532,8 @@ CompileExpr::resolve_operator_overload (
TyTy::BaseType *receiver = nullptr;
bool ok
- = ctx->get_tyctx ()->lookup_receiver (expr.get_mappings ().get_hirid (),
- &receiver);
+ = ctx->get_tyctx ()->lookup_type (lhs_expr.get_mappings ().get_hirid (),
+ &receiver);
rust_assert (ok);
bool is_generic_receiver = receiver->get_kind () == TyTy::TypeKind::PARAM;
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index 39d4b9e..7ce9848 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -19,6 +19,8 @@
#include "rust-compile-item.h"
#include "rust-compile-implitem.h"
#include "rust-compile-extern.h"
+#include "rust-substitution-mapper.h"
+#include "rust-type-util.h"
#include "rust-immutable-name-resolution-context.h"
namespace Rust {
@@ -165,12 +167,33 @@ CompileItem::visit (HIR::Function &function)
// is given
if (concrete == nullptr)
return;
- else
+
+ rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);
+ bool is_trait_item_concrete
+ = ctx->get_mappings ()
+ .lookup_trait_item_defid (concrete_fnty->get_id ())
+ .has_value ();
+ if (!is_trait_item_concrete)
{
rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
fntype = static_cast<TyTy::FnType *> (concrete);
- fntype->monomorphize ();
}
+ else
+ {
+ TyTy::BaseType *infer
+ = Resolver::SubstMapper::InferSubst (fntype, function.get_locus ());
+ TyTy::BaseType *resolved
+ = Resolver::unify_site (function.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (infer),
+ TyTy::TyWithLocation (concrete),
+ function.get_locus ());
+
+ rust_assert (resolved->is<TyTy::FnType> ());
+ fntype = resolved->as<TyTy::FnType> ();
+ }
+
+ fntype->monomorphize ();
}
else
{
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index fbf9a3d..c54cc09 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -297,16 +297,20 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
trait->get_mappings ().get_defid (), &trait_ref);
rust_assert (ok);
- TyTy::BaseType *receiver = nullptr;
- ok = ctx->get_tyctx ()->lookup_receiver (mappings.get_hirid (),
- &receiver);
- rust_assert (ok);
- receiver = receiver->destructure ();
-
// the type resolver can only resolve type bounds to their trait
// 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
+ //
+ // because we know this is resolved to a trait item we can actually
+ // just grab the Self type parameter here for the receiver to match
+ // the appropriate impl block
+
+ rust_assert (lookup->is<TyTy::FnType> ());
+ auto fn = lookup->as<TyTy::FnType> ();
+ rust_assert (fn->get_num_type_params () > 0);
+ auto &self = fn->get_substs ().at (0);
+ auto receiver = self.get_param_ty ();
auto candidates
= Resolver::PathProbeImplTrait::Probe (receiver, final_segment,
trait_ref);