aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2023-01-27 15:38:58 +0000
committerArthur Cohen <arthur.cohen@embecosm.com>2023-04-06 10:47:21 +0200
commite42c28bcfdde1f81c4908c08ee5e2da6e1c4bd93 (patch)
tree4f616921772fa93cf14b7d0dba12b9a272772821
parent31f1e59962b81408e37ac4f46f6b39456ee54b21 (diff)
downloadgcc-e42c28bcfdde1f81c4908c08ee5e2da6e1c4bd93.zip
gcc-e42c28bcfdde1f81c4908c08ee5e2da6e1c4bd93.tar.gz
gcc-e42c28bcfdde1f81c4908c08ee5e2da6e1c4bd93.tar.bz2
gccrs: Remove monomorphization hack to setup possible associated types
During CallExpr argument type checking we may be calling a default implementation of a trait function this will require any possible associated types to be resolved and setup. This monomoprhization call does this but it will premtivly do extra unification of types which will throw off type checking later on. This fix is required for my work into type bounds checking. Fixes #1773 Signed-off-by: Philip Herron <herron.philip@googlemail.com> gcc/rust/ChangeLog: * typecheck/rust-hir-trait-reference.h: change interface to return self * typecheck/rust-hir-trait-resolve.cc: likewise * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): likewise * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): remove monomorphization hack gcc/testsuite/ChangeLog: * rust/compile/issue-1773.rs: New test.
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-reference.h5
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc10
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc36
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.cc1
-rw-r--r--gcc/testsuite/rust/compile/issue-1773.rs20
5 files changed, 56 insertions, 16 deletions
diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h b/gcc/rust/typecheck/rust-hir-trait-reference.h
index 0df3526..9b4461b 100644
--- a/gcc/rust/typecheck/rust-hir-trait-reference.h
+++ b/gcc/rust/typecheck/rust-hir-trait-reference.h
@@ -497,8 +497,9 @@ public:
TyTy::BaseType *get_self () { return self; }
- void setup_associated_types (const TyTy::BaseType *self,
- const TyTy::TypeBoundPredicate &bound);
+ TyTy::BaseType *
+ setup_associated_types (const TyTy::BaseType *self,
+ const TyTy::TypeBoundPredicate &bound);
void reset_associated_types ();
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index e2d0cf2..6e23093 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -377,13 +377,10 @@ TraitItemReference::associated_type_reset () const
placeholder->clear_associated_type ();
}
-void
+TyTy::BaseType *
AssociatedImplTrait::setup_associated_types (
const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound)
{
- if (!bound.contains_associated_types ())
- return;
-
// compute the constrained impl block generic arguments based on self and the
// higher ranked trait bound
TyTy::BaseType *receiver = self->clone ();
@@ -486,6 +483,7 @@ AssociatedImplTrait::setup_associated_types (
TyTy::TyWithLocation (receiver), TyTy::TyWithLocation (impl_self_infer),
impl_predicate.get_locus ());
rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
+ TyTy::BaseType *self_result = result;
// unify the bounds arguments
std::vector<TyTy::BaseType *> hrtb_bound_arguments;
@@ -500,7 +498,7 @@ AssociatedImplTrait::setup_associated_types (
}
if (impl_trait_predicate_args.size () != hrtb_bound_arguments.size ())
- return;
+ return self_result;
for (size_t i = 0; i < impl_trait_predicate_args.size (); i++)
{
@@ -554,6 +552,8 @@ AssociatedImplTrait::setup_associated_types (
resolved_trait_item->associated_type_set (substituted);
});
iter.go ();
+
+ return self_result;
}
void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 6f1fd41..9d9b294 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -379,16 +379,36 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
if (associated_impl_block != nullptr)
{
- // get the type of the parent Self
- HirId impl_ty_id
- = associated_impl_block->get_type ()->get_mappings ().get_hirid ();
+ // associated types
+ HirId impl_block_id
+ = associated_impl_block->get_mappings ().get_hirid ();
+
+ AssociatedImplTrait *associated = nullptr;
+ bool found_impl_trait
+ = context->lookup_associated_trait_impl (impl_block_id,
+ &associated);
TyTy::BaseType *impl_block_ty = nullptr;
- bool ok = query_type (impl_ty_id, &impl_block_ty);
- rust_assert (ok);
+ if (found_impl_trait)
+ {
+ TyTy::TypeBoundPredicate predicate (*associated->get_trait (),
+ seg.get_locus ());
+ impl_block_ty
+ = associated->setup_associated_types (prev_segment, predicate);
+ }
+ else
+ {
+ // get the type of the parent Self
+ HirId impl_ty_id = associated_impl_block->get_type ()
+ ->get_mappings ()
+ .get_hirid ();
- if (impl_block_ty->needs_generic_substitutions ())
- impl_block_ty
- = SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
+ bool ok = query_type (impl_ty_id, &impl_block_ty);
+ rust_assert (ok);
+
+ if (impl_block_ty->needs_generic_substitutions ())
+ impl_block_ty
+ = SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
+ }
prev_segment = unify_site (seg.get_mappings ().get_hirid (),
TyTy::TyWithLocation (prev_segment),
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
index d520b59..4c6442e 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -85,7 +85,6 @@ TypeCheckCallExpr::visit (ADTType &type)
void
TypeCheckCallExpr::visit (FnType &type)
{
- type.monomorphize ();
if (call.num_params () != type.num_params ())
{
if (type.is_varadic ())
diff --git a/gcc/testsuite/rust/compile/issue-1773.rs b/gcc/testsuite/rust/compile/issue-1773.rs
new file mode 100644
index 0000000..c627ac0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1773.rs
@@ -0,0 +1,20 @@
+trait Foo<T> {
+ type A;
+
+ fn test(a: Self::A) -> Self::A {
+ a
+ }
+}
+
+struct Bar<T>(T);
+impl<T> Foo<T> for Bar<i32> {
+ type A = T;
+}
+
+fn main() {
+ let a;
+ a = Bar(123);
+
+ let b;
+ b = Bar::test(a.0);
+}