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.
This commit is contained in:
Philip Herron
2023-01-27 15:38:58 +00:00
committed by Arthur Cohen
parent 31f1e59962
commit e42c28bcfd
5 changed files with 57 additions and 17 deletions

View File

@@ -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 ();

View File

@@ -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

View File

@@ -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 ();
TyTy::BaseType *impl_block_ty = nullptr;
bool ok = query_type (impl_ty_id, &impl_block_ty);
rust_assert (ok);
// associated types
HirId impl_block_id
= associated_impl_block->get_mappings ().get_hirid ();
if (impl_block_ty->needs_generic_substitutions ())
impl_block_ty
= SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
AssociatedImplTrait *associated = nullptr;
bool found_impl_trait
= context->lookup_associated_trait_impl (impl_block_id,
&associated);
TyTy::BaseType *impl_block_ty = nullptr;
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 ();
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),

View File

@@ -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 ())

View File

@@ -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);
}