From: Philip Herron Date: Sat, 21 Jun 2025 13:22:04 +0000 (+0100) Subject: gccrs: Fix cyclical projection to placeholder X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d5c85e24844fe15d729a4acd7c3d05a87057d2ed;p=thirdparty%2Fgcc.git 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 --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 (item_ty); + if (ty->is ()) + { + const auto &projection = *static_cast (ty); + const auto resolved = projection.get (); + if (resolved == item_ty) + return; + } + placeholder->set_associated_type (ty->get_ty_ref ()); }