diff options
author | Philip Herron <herron.philip@googlemail.com> | 2023-01-27 15:38:58 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2023-02-05 00:10:48 +0000 |
commit | edcf5b63bf60c1aec18df315fffbcd3d59d23119 (patch) | |
tree | 18d4727bded65c9fecf5ee1c783c7730be6c17cb /gcc/rust | |
parent | b5719d74b349bf96735851844158ea9b5d65db85 (diff) | |
download | gcc-edcf5b63bf60c1aec18df315fffbcd3d59d23119.zip gcc-edcf5b63bf60c1aec18df315fffbcd3d59d23119.tar.gz gcc-edcf5b63bf60c1aec18df315fffbcd3d59d23119.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.
Diffstat (limited to 'gcc/rust')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-reference.h | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.cc | 10 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-path.cc | 36 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-call.cc | 1 |
4 files changed, 36 insertions, 16 deletions
diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h b/gcc/rust/typecheck/rust-hir-trait-reference.h index d0814f6..0d4da3b 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 b293279..a7e0735 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 4e765ad..1625eda 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 6334b69..6ff0113 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 ()) |