From: Philip Herron <[email protected]>

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 <[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/0fd9c68665c73458385978ac698b7d0b644c7d87

The commit has been mentioned in the following issue(s):
 - Rust-GCC/gccrs#4812: https://github.com/Rust-GCC/gccrs/issues/4812

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4813

 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 3ed46e0f0..be71f6fab 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 000000000..8fdb5c09b
--- /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]>();
+}

base-commit: 46cdf5156d172f95c81e8acf0b892bd1c9f42c23
-- 
2.55.0

Reply via email to