From: Enes Cevik <[email protected]>
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]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github: https://github.com/Rust-GCC/gccrs/commit/4597a4c3229aa4a1484466f92aeab06c9bcc545a
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4720
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 5ec3f0b40..21a55ac6c 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 af43b1c12..65130ea25 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);
base-commit: 7a0c8beaa0c2cdd5607e561edeeebee196277ad9
--
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.