diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index e3fc9bfee49c4..994f7d17c5c41 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -136,19 +136,24 @@ impl<'tcx> Value<'tcx> { ty::Ref(_, inner_ty, _) => match inner_ty.kind() { // `&str` can be interpreted as raw bytes ty::Str => {} - // `&[u8]` can be interpreted as raw bytes - ty::Slice(slice_ty) if *slice_ty == tcx.types.u8 => {} + // `&[T]` can be interpreted as raw bytes if elements are `u8` + ty::Slice(_) => {} // other `&_` can't be interpreted as raw bytes _ => return None, }, - // `[u8; N]` can be interpreted as raw bytes - ty::Array(array_ty, _) if *array_ty == tcx.types.u8 => {} + // `[T; N]` can be interpreted as raw bytes if elements are `u8` + ty::Array(_, _) => {} // Otherwise, type cannot be interpreted as raw bytes _ => return None, } // We create an iterator that yields `Option` - let iterator = self.to_branch().into_iter().map(|ct| Some(ct.try_to_leaf()?.to_u8())); + let iterator = self.to_branch().into_iter().map(|ct| { + (*ct) + .try_to_value() + .and_then(|value| (value.ty == tcx.types.u8).then_some(value)) + .and_then(|value| value.try_to_leaf().map(|leaf| leaf.to_u8())) + }); // If there is `None` in the iterator, then the array is not a valid array of u8s and we return `None` let bytes: Vec = iterator.collect::>>()?; diff --git a/tests/ui/const-generics/mgca/array_elem_type_mismatch.rs b/tests/ui/const-generics/mgca/array_elem_type_mismatch.rs new file mode 100644 index 0000000000000..b15f90acb477e --- /dev/null +++ b/tests/ui/const-generics/mgca/array_elem_type_mismatch.rs @@ -0,0 +1,10 @@ +//! Regression test for +#![expect(incomplete_features)] +#![feature(adt_const_params, generic_const_parameter_types, min_generic_const_args)] +fn foo() {} + +fn main() { + foo::<_, { [0, 1u8, 2u32, 8u64] }>(); + //~^ ERROR the constant `2` is not of type `u8` + //~| ERROR the constant `8` is not of type `u8` +} diff --git a/tests/ui/const-generics/mgca/array_elem_type_mismatch.stderr b/tests/ui/const-generics/mgca/array_elem_type_mismatch.stderr new file mode 100644 index 0000000000000..f98dbf1e311ba --- /dev/null +++ b/tests/ui/const-generics/mgca/array_elem_type_mismatch.stderr @@ -0,0 +1,14 @@ +error: the constant `2` is not of type `u8` + --> $DIR/array_elem_type_mismatch.rs:7:16 + | +LL | foo::<_, { [0, 1u8, 2u32, 8u64] }>(); + | ^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `u32` + +error: the constant `8` is not of type `u8` + --> $DIR/array_elem_type_mismatch.rs:7:16 + | +LL | foo::<_, { [0, 1u8, 2u32, 8u64] }>(); + | ^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `u64` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.rs b/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.rs new file mode 100644 index 0000000000000..efc21808787b1 --- /dev/null +++ b/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.rs @@ -0,0 +1,10 @@ +#![expect(incomplete_features)] +#![feature(adt_const_params, min_generic_const_args)] + +struct ArrWrap; + +fn main() { + let _: ArrWrap<{ [1_u8] }> = ArrWrap::<{ [1_u16] }>; + //~^ ERROR: mismatched types + //~| ERROR the constant `1` is not of type `u8` +} diff --git a/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.stderr b/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.stderr new file mode 100644 index 0000000000000..4105f314f7974 --- /dev/null +++ b/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/wrapped_array_elem_type_mismatch.rs:7:34 + | +LL | let _: ArrWrap<{ [1_u8] }> = ArrWrap::<{ [1_u16] }>; + | ------------------- ^^^^^^^^^^^^^^^^^^^^^^ expected `*b"\x01"`, found `[1]` + | | + | expected due to this + | + = note: expected struct `ArrWrap<*b"\x01">` + found struct `ArrWrap<[1]>` + +error: the constant `1` is not of type `u8` + --> $DIR/wrapped_array_elem_type_mismatch.rs:7:46 + | +LL | let _: ArrWrap<{ [1_u8] }> = ArrWrap::<{ [1_u16] }>; + | ^^^^^^^ expected `u8`, found `u16` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`.