https://gcc.gnu.org/g:d5c85e24844fe15d729a4acd7c3d05a87057d2ed
commit r16-2885-gd5c85e24844fe15d729a4acd7c3d05a87057d2ed Author: Philip Herron <herron.phi...@googlemail.com> Date: Sat Jun 21 14:22:04 2025 +0100 gccrs: Fix cyclical projection to placeholder 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. Diff: --- 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 35c9b0a6a2d3..fccc53ed6c2d 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 ()); }