From: Philip Herron <herron.phi...@googlemail.com> Prevent infinite loops when projecting associated types by properly handling cyclical references with placeholder types.
gcc/rust/ChangeLog: * typecheck/rust-hir-trait-resolve.cc: Add cyclical projection protection. --- gcc/rust/typecheck/rust-hir-trait-resolve.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index 35c9b0a6a2d..fccc53ed6c2 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -444,11 +444,27 @@ TraitItemReference::associated_type_set (TyTy::BaseType *ty) const { rust_assert (get_trait_item_type () == TraitItemType::TYPE); + // this isnt super safe there are cases like the FnTraits where the type is + // set to the impls placeholder associated type. For example + // + // type Output = F::Output; -- see the fn trait impls in libcore + // + // then this projection ends up resolving back to this placeholder so it just + // ends up being cyclical + TyTy::BaseType *item_ty = get_tyty (); rust_assert (item_ty->get_kind () == TyTy::TypeKind::PLACEHOLDER); TyTy::PlaceholderType *placeholder = static_cast<TyTy::PlaceholderType *> (item_ty); + if (ty->is<TyTy::ProjectionType> ()) + { + const auto &projection = *static_cast<const TyTy::ProjectionType *> (ty); + const auto resolved = projection.get (); + if (resolved == item_ty) + return; + } + placeholder->set_associated_type (ty->get_ty_ref ()); } -- 2.49.0