[COMMITTED 10/83] gccrs: when binding we need to distingish between generics/const-generics

arthur.cohen@opensrcsec.com arthur.cohen@opensrcsec.com
Wed Sep 16 12:29:29 GMT 2026


From: Philip Herron <herron.philip@googlemail.com>

Fixes Rust-GCC/gccrs#4812

gcc/rust/ChangeLog:

	* typecheck/rust-hir-trait-resolve.cc (AssociatedImplTrait::bind_impl_for_projection):
	switch between generics
	(AssociatedImplTrait::bind_impl_for_bound): likewise

gcc/testsuite/ChangeLog:

	* rust/compile/issue-4812.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc | 50 +++++++++++++++-----
 gcc/testsuite/rust/compile/issue-4812.rs     | 23 +++++++++
 2 files changed, 61 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-4812.rs

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 3ed46e0f0cc..be71f6fabac 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -561,17 +561,26 @@ AssociatedImplTrait::bind_impl_for_projection (TyTy::ProjectionType &proj,
   std::vector<TyTy::SubstitutionParamMapping> impl_substitutions;
   for (auto &generic_param : impl->get_generic_params ())
     {
-      if (generic_param->get_kind () != HIR::GenericParam::GenericKind::TYPE)
+      if (generic_param->get_kind () != HIR::GenericParam::GenericKind::TYPE
+	  && generic_param->get_kind ()
+	       != HIR::GenericParam::GenericKind::CONST)
 	continue;
       TyTy::BaseType *l = nullptr;
       bool ok
 	= context->lookup_type (generic_param->get_mappings ().get_hirid (),
 				&l);
-      if (!ok || l->get_kind () != TyTy::TypeKind::PARAM)
+      if (!ok)
 	continue;
-      impl_substitutions.emplace_back (static_cast<HIR::TypeParam &> (
-					 *generic_param),
-				       static_cast<TyTy::ParamType *> (l));
+
+      TyTy::BaseGeneric *param = nullptr;
+      if (l->get_kind () == TyTy::TypeKind::PARAM)
+	param = static_cast<TyTy::ParamType *> (l);
+      else if (l->get_kind () == TyTy::TypeKind::CONST
+	       && l->as_const_type ()->const_kind ()
+		    == TyTy::BaseConstType::ConstKind::Decl)
+	param = static_cast<TyTy::ConstParamType *> (l);
+      if (param != nullptr)
+	impl_substitutions.emplace_back (*generic_param, param);
     }
 
   // Build infer args for each impl param so we dont mutate the impls own
@@ -583,7 +592,11 @@ AssociatedImplTrait::bind_impl_for_projection (TyTy::ProjectionType &proj,
   for (auto &p : impl_substitutions)
     {
       const std::string &symbol = p.get_param_ty ()->get_symbol ();
-      TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
+      TyTy::TyVar infer_var
+	= p.get_generic_param ().get_kind ()
+	      == HIR::GenericParam::GenericKind::CONST
+	    ? TyTy::TyVar::get_implicit_const_infer_var (locus)
+	    : TyTy::TyVar::get_implicit_infer_var (locus);
       TyTy::BaseType *resolved = infer_var.get_tyty ();
       infer_arg_vec.emplace_back (&p, resolved);
       param_mappings[symbol] = resolved->get_ref ();
@@ -703,17 +716,26 @@ AssociatedImplTrait::bind_impl_for_bound (TyTy::BaseType *receiver,
   std::vector<TyTy::SubstitutionParamMapping> impl_substitutions;
   for (auto &generic_param : impl->get_generic_params ())
     {
-      if (generic_param->get_kind () != HIR::GenericParam::GenericKind::TYPE)
+      if (generic_param->get_kind () != HIR::GenericParam::GenericKind::TYPE
+	  && generic_param->get_kind ()
+	       != HIR::GenericParam::GenericKind::CONST)
 	continue;
       TyTy::BaseType *l = nullptr;
       bool ok
 	= context->lookup_type (generic_param->get_mappings ().get_hirid (),
 				&l);
-      if (!ok || l->get_kind () != TyTy::TypeKind::PARAM)
+      if (!ok)
 	continue;
-      impl_substitutions.emplace_back (static_cast<HIR::TypeParam &> (
-					 *generic_param),
-				       static_cast<TyTy::ParamType *> (l));
+
+      TyTy::BaseGeneric *param = nullptr;
+      if (l->get_kind () == TyTy::TypeKind::PARAM)
+	param = static_cast<TyTy::ParamType *> (l);
+      else if (l->get_kind () == TyTy::TypeKind::CONST
+	       && l->as_const_type ()->const_kind ()
+		    == TyTy::BaseConstType::ConstKind::Decl)
+	param = static_cast<TyTy::ConstParamType *> (l);
+      if (param != nullptr)
+	impl_substitutions.emplace_back (*generic_param, param);
     }
 
   std::vector<TyTy::SubstitutionArg> infer_arg_vec;
@@ -721,7 +743,11 @@ AssociatedImplTrait::bind_impl_for_bound (TyTy::BaseType *receiver,
   for (auto &p : impl_substitutions)
     {
       const std::string &symbol = p.get_param_ty ()->get_symbol ();
-      TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
+      TyTy::TyVar infer_var
+	= p.get_generic_param ().get_kind ()
+	      == HIR::GenericParam::GenericKind::CONST
+	    ? TyTy::TyVar::get_implicit_const_infer_var (locus)
+	    : TyTy::TyVar::get_implicit_infer_var (locus);
       TyTy::BaseType *resolved = infer_var.get_tyty ();
       infer_arg_vec.emplace_back (&p, resolved);
       param_mappings[symbol] = resolved->get_ref ();
diff --git a/gcc/testsuite/rust/compile/issue-4812.rs b/gcc/testsuite/rust/compile/issue-4812.rs
new file mode 100644
index 00000000000..8fdb5c09bbe
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4812.rs
@@ -0,0 +1,23 @@
+#![no_core]
+#![feature(no_core)]
+#![feature(lang_items)]
+#![feature(min_const_generics)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Array {
+    type Element;
+}
+
+impl<T, const N: usize> Array for [T; N] {
+    type Element = T;
+}
+
+fn require_byte_array<T: Array<Element = u8>>() {}
+
+fn main() {
+    require_byte_array::<[u8; 0]>();
+    require_byte_array::<[u8; 32]>();
+    require_byte_array::<[u8; 1024]>();
+}
-- 
2.50.1



More information about the Gcc-rust mailing list