https://gcc.gnu.org/g:8a308f852b6eda59549c22c5d5ef7b82907c7b88
commit r17-4098-g8a308f852b6eda59549c22c5d5ef7b82907c7b88 Author: Enes Cevik <[email protected]> Date: Thu Jul 16 12:09:02 2026 +0300 gccrs: typecheck: Add auto-trait field propagation and negative impl checks This patch adds support for structural auto-traits and fixes how negative trait implementations are handled. gcc/rust/ChangeLog: * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::add_trait_bound): Check all fields of an ADT. * typecheck/rust-tyty.cc (BaseType::satisfies_bound): Reject trait if there is a negative impl. Signed-off-by: Enes Cevik <[email protected]> Diff: --- gcc/rust/typecheck/rust-tyty-bounds.cc | 28 ++++++++++++++++++++++++++++ gcc/rust/typecheck/rust-tyty.cc | 14 +++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc index 5ec3f0b40054..21a55ac6c488 100644 --- a/gcc/rust/typecheck/rust-tyty-bounds.cc +++ b/gcc/rust/typecheck/rust-tyty-bounds.cc @@ -181,6 +181,34 @@ TypeBoundsProbe::add_trait_bound (HIR::Trait *trait) { auto trait_ref = TraitResolver::Resolve (*trait); + for (const auto &existing : trait_references) + if (existing.first->is_equal (*trait_ref)) + return; + + if (receiver->get_kind () == TyTy::TypeKind::ADT) + { + TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (receiver); + for (auto &variant : adt->get_variants ()) + { + for (auto &field : variant->get_fields ()) + { + TyTy::BaseType *field_ty = field->get_field_type (); + + // TODO: A loop guard is needed here to prevent infinite + // recursion, but self-referential types currently crash due to + // issue Rust-GCC/gccrs#4709. Therefore, I avoided adding an + // untested guard for now. + + if (!field_ty->satisfies_bound ( + TyTy::TypeBoundPredicate (*trait_ref, + BoundPolarity::RegularBound, + UNDEF_LOCATION), + false)) + return; + } + } + } + trait_references.emplace_back (trait_ref, mappings.lookup_builtin_marker ()); } diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index af43b1c122ae..65130ea25303 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -324,10 +324,18 @@ BaseType::satisfies_bound (const TypeBoundPredicate &predicate, bool emit_error) if (!bound->is_equal (*query)) continue; - // builtin ones have no impl-block this needs fixed and use a builtin node - // of somekind + // builtin ones have no impl-block this needs fixed and use a builtin + // node of somekind if (b.second == nullptr) - return true; + { + return predicate.get_polarity () == BoundPolarity::RegularBound; + } + else + { + const auto &impl = *(b.second); + if (predicate.get_polarity () != impl.get_polarity ()) + continue; + } // need to check that associated types can match as well const HIR::ImplBlock &impl = *(b.second);
