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