aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2025-02-13 14:09:17 +0000
committerPhilip Herron <philip.herron@embecosm.com>2025-02-13 16:29:10 +0000
commit5f7213e82064b3b6220a62e103eb361c0428d2d1 (patch)
treeada6af4fb8932c4cb995b179bae5f7f2dc474776 /gcc
parentc005754701addc8a08fd1ed8381826ccbd92e83e (diff)
downloadgcc-5f7213e82064b3b6220a62e103eb361c0428d2d1.zip
gcc-5f7213e82064b3b6220a62e103eb361c0428d2d1.tar.gz
gcc-5f7213e82064b3b6220a62e103eb361c0428d2d1.tar.bz2
gccrs: fix unconstrained generics check to handle recursive generics
Generics can be constrained within other generic types so this check needs to be recursive. Fixes Rust-GCC#3031 gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-base.cc (walk_types_to_constrain): recursive walker * typecheck/rust-tyty.cc (BaseType::get_subst_argument_mappings): new helper * typecheck/rust-tyty.h: prototype gcc/testsuite/ChangeLog: * rust/compile/issue-3031.rs: New test. Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc42
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc42
-rw-r--r--gcc/rust/typecheck/rust-tyty.h1
-rw-r--r--gcc/testsuite/rust/compile/issue-3031.rs15
4 files changed, 82 insertions, 18 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 1c800a9c..b6d2f03 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -31,6 +31,26 @@ TypeCheckBase::TypeCheckBase ()
context (TypeCheckContext::get ())
{}
+static void
+walk_types_to_constrain (std::set<HirId> &constrained_symbols,
+ const TyTy::SubstitutionArgumentMappings &constraints)
+{
+ for (const auto &c : constraints.get_mappings ())
+ {
+ const TyTy::BaseType *arg = c.get_tyty ();
+ if (arg != nullptr)
+ {
+ const TyTy::BaseType *p = arg->get_root ();
+ constrained_symbols.insert (p->get_ty_ref ());
+ if (p->has_substitutions_defined ())
+ {
+ walk_types_to_constrain (constrained_symbols,
+ p->get_subst_argument_mappings ());
+ }
+ }
+ }
+}
+
bool
TypeCheckBase::check_for_unconstrained (
const std::vector<TyTy::SubstitutionParamMapping> &params_to_constrain,
@@ -52,28 +72,14 @@ TypeCheckBase::check_for_unconstrained (
HirId ref = p.get_param_ty ()->get_ref ();
symbols_to_constrain.insert (ref);
symbol_to_location.insert ({ref, p.get_param_locus ()});
+
+ rust_debug_loc (p.get_param_locus (), "XX constrain THIS");
}
// set up the set of constrained symbols
std::set<HirId> constrained_symbols;
- for (const auto &c : constraint_a.get_mappings ())
- {
- const TyTy::BaseType *arg = c.get_tyty ();
- if (arg != nullptr)
- {
- const TyTy::BaseType *p = arg->get_root ();
- constrained_symbols.insert (p->get_ty_ref ());
- }
- }
- for (const auto &c : constraint_b.get_mappings ())
- {
- const TyTy::BaseType *arg = c.get_tyty ();
- if (arg != nullptr)
- {
- const TyTy::BaseType *p = arg->get_root ();
- constrained_symbols.insert (p->get_ty_ref ());
- }
- }
+ walk_types_to_constrain (constrained_symbols, constraint_a);
+ walk_types_to_constrain (constrained_symbols, constraint_b);
const auto root = reference->get_root ();
if (root->get_kind () == TyTy::TypeKind::PARAM)
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 0b85da4..7221b4d 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -888,6 +888,48 @@ BaseType::needs_generic_substitutions () const
return false;
}
+const SubstitutionArgumentMappings &
+BaseType::get_subst_argument_mappings () const
+{
+ static auto empty = SubstitutionArgumentMappings::empty ();
+ const TyTy::BaseType *x = destructure ();
+ switch (x->get_kind ())
+ {
+ case PROJECTION: {
+ const auto &p = *static_cast<const ProjectionType *> (x);
+ const auto &ref = static_cast<const SubstitutionRef &> (p);
+ return ref.get_substitution_arguments ();
+ }
+ break;
+
+ case FNDEF: {
+ const auto &fn = *static_cast<const FnType *> (x);
+ const auto &ref = static_cast<const SubstitutionRef &> (fn);
+ return ref.get_substitution_arguments ();
+ }
+ break;
+
+ case ADT: {
+ const auto &adt = *static_cast<const ADTType *> (x);
+ const auto &ref = static_cast<const SubstitutionRef &> (adt);
+ return ref.get_substitution_arguments ();
+ }
+ break;
+
+ case CLOSURE: {
+ const auto &closure = *static_cast<const ClosureType *> (x);
+ const auto &ref = static_cast<const SubstitutionRef &> (closure);
+ return ref.get_substitution_arguments ();
+ }
+ break;
+
+ default:
+ return empty;
+ }
+
+ return empty;
+}
+
// InferType
InferType::InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint,
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index d91af33..b8070f4 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -174,6 +174,7 @@ public:
bool has_substitutions_defined () const;
bool needs_generic_substitutions () const;
+ const SubstitutionArgumentMappings &get_subst_argument_mappings () const;
std::string mangle_string () const
{
diff --git a/gcc/testsuite/rust/compile/issue-3031.rs b/gcc/testsuite/rust/compile/issue-3031.rs
new file mode 100644
index 0000000..33f5bf0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3031.rs
@@ -0,0 +1,15 @@
+#![feature(no_core)]
+#![feature(lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait A<T: ?Sized> {}
+
+struct Cell<X> {
+ // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+ x: X,
+}
+
+impl<T, U> A<Cell<U>> for Cell<T> where T: A<U> {}