https://gcc.gnu.org/g:a7064fee10914f73161eed4a7a099f13cb992a0f
commit r17-4287-ga7064fee10914f73161eed4a7a099f13cb992a0f Author: Philip Herron <[email protected]> Date: Sun Aug 23 16:28:04 2026 +0100 gccrs: when binding we need to distingish between generics/const-generics 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]> Diff: --- gcc/rust/typecheck/rust-hir-trait-resolve.cc | 50 +++++++++++++++++++++------- gcc/testsuite/rust/compile/issue-4812.rs | 23 +++++++++++++ 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index 3ed46e0f0cce..be71f6fabacb 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 000000000000..8fdb5c09bbe1 --- /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]>(); +}
