mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 20:01:22 -05:00
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:
committed by
Arthur Cohen
parent
31f1e59962
commit
e42c28bcfd
@@ -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 ();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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 ())
|
||||
|
||||
20
gcc/testsuite/rust/compile/issue-1773.rs
Normal file
20
gcc/testsuite/rust/compile/issue-1773.rs
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user