https://gcc.gnu.org/g:db64745c39cd533a10391aa6fa49487d18730b4a
commit r16-5351-gdb64745c39cd533a10391aa6fa49487d18730b4a Author: Philip Herron <[email protected]> Date: Sun Nov 9 15:49:09 2025 +0000 gccrs: Fix const generics handling on array types When we were processing generic const param types on arrays the size type was overriding the const param decl because of a hirid reference mismatch Fixes Rust-GCC#3879 gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): fix mappings gcc/testsuite/ChangeLog: * rust/compile/const_generics_18.rs: New test. * rust/compile/const_generics_19.rs: New test. * rust/execute/torture/const-generics-3.rs: New test. * rust/execute/torture/const-generics-4.rs: New test. Signed-off-by: Philip Herron <[email protected]> Diff: --- gcc/rust/typecheck/rust-hir-type-check-type.cc | 3 +- gcc/testsuite/rust/compile/const_generics_18.rs | 10 +++++ gcc/testsuite/rust/compile/const_generics_19.rs | 10 +++++ .../rust/execute/torture/const-generics-3.rs | 13 +++++++ .../rust/execute/torture/const-generics-4.rs | 43 ++++++++++++++++++++++ 5 files changed, 77 insertions(+), 2 deletions(-) diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index 799efc809d51..ca7ef472578a 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -704,7 +704,6 @@ TypeCheckType::visit (HIR::ArrayType &type) TyTy::BaseType *expected_ty = nullptr; bool ok = context->lookup_builtin ("usize", &expected_ty); rust_assert (ok); - context->insert_type (type.get_size_expr ().get_mappings (), expected_ty); TyTy::BaseConstType *const_type = nullptr; if (capacity_type->get_kind () == TyTy::TypeKind::CONST) @@ -745,7 +744,7 @@ TypeCheckType::visit (HIR::ArrayType &type) translated = new TyTy::ArrayType (type.get_mappings ().get_hirid (), type.get_locus (), TyTy::TyVar ( - const_type->as_base_type ()->get_ty_ref ()), + const_type->as_base_type ()->get_ref ()), TyTy::TyVar (element_type->get_ref ())); } diff --git a/gcc/testsuite/rust/compile/const_generics_18.rs b/gcc/testsuite/rust/compile/const_generics_18.rs new file mode 100644 index 000000000000..8bcc26158b44 --- /dev/null +++ b/gcc/testsuite/rust/compile/const_generics_18.rs @@ -0,0 +1,10 @@ +#[lang = "sized"] +trait Sized {} + +struct Foo<const N: usize>; +type Alias = Foo<4>; + +fn main() -> i32 { + let _x: Alias = Foo::<4> {}; + 0 +} diff --git a/gcc/testsuite/rust/compile/const_generics_19.rs b/gcc/testsuite/rust/compile/const_generics_19.rs new file mode 100644 index 000000000000..b0932ae60272 --- /dev/null +++ b/gcc/testsuite/rust/compile/const_generics_19.rs @@ -0,0 +1,10 @@ +#[lang = "sized"] +trait Sized {} + +struct Foo<const N: usize>; +struct Wrapper<T>(T); + +fn main() -> i32 { + let _: Wrapper<Foo<3>> = Wrapper(Foo::<3> {}); + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/const-generics-3.rs b/gcc/testsuite/rust/execute/torture/const-generics-3.rs new file mode 100644 index 000000000000..53698bb2dd64 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/const-generics-3.rs @@ -0,0 +1,13 @@ +#[lang = "sized"] +pub trait Sized {} + +fn simd_shuffle<const N: usize>(idx: [u32; N]) -> [u32; N] { + idx +} + +fn main() -> i32 { + let a = [1u32, 2, 3, 4]; + let out = simd_shuffle(a); + let _check: [u32; 4] = out; + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/const-generics-4.rs b/gcc/testsuite/rust/execute/torture/const-generics-4.rs new file mode 100644 index 000000000000..bf64f13e6545 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/const-generics-4.rs @@ -0,0 +1,43 @@ +#[lang = "sized"] +trait Sized {} + +#[allow(unused)] +macro_rules! simd_shuffle { + ($x:expr, $y:expr, $idx:expr $(,)?) => {{ + simd_shuffle( + $x, + $y, + const { + let v: [u32; _] = $idx; + v + }, + ) + }}; +} + +const fn simd_shuffle(_a: [u32; 4], _b: [u32; 4], idx: [u32; 4]) -> [u32; 4] { + idx +} + +fn main() -> i32 { + let a = [1, 2, 3, 4]; + let b = [5, 6, 7, 8]; + let indices = [3, 2, 1, 0]; + + let result: [u32; 4] = simd_shuffle!(a, b, indices); + + if result[0] != 3 { + return 1; + } + if result[1] != 2 { + return 2; + } + if result[2] != 1 { + return 3; + } + if result[3] != 0 { + return 4; + } + + 0 +}
