From 75658091631afe5a8b805a340a43bef4c00def11 Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Sun, 15 Nov 2020 09:35:04 +1000 Subject: [PATCH] add a canary test for complex repr(simd) --- compiler/rustc_middle/src/ty/sty.rs | 8 ++++- src/test/ui/simd/simd-array-trait.rs | 40 ++++++++++++++++++++++++ src/test/ui/simd/simd-array-trait.stderr | 10 ++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/simd/simd-array-trait.rs create mode 100644 src/test/ui/simd/simd-array-trait.stderr diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d1f83d0a83e..5d57ed9e2f8 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1966,7 +1966,13 @@ pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) { let f0_ty = variant.fields[0].ty(tcx, substs); match f0_ty.kind() { - Array(f0_elem_ty, f0_len) => (f0_len.eval_usize(tcx, ParamEnv::empty()) as u64, f0_elem_ty), + Array(f0_elem_ty, f0_len) => { + // FIXME(repr_simd): https://github.com/rust-lang/rust/pull/78863#discussion_r522784112 + // The way we evaluate the `N` in `[T; N]` here only works since we use + // `simd_size_and_type` post-monomorphization. It will probably start to ICE + // if we use it in generic code. See the `simd-array-trait` ui test. + (f0_len.eval_usize(tcx, ParamEnv::empty()) as u64, f0_elem_ty) + } _ => (variant.fields.len() as u64, f0_ty), } } diff --git a/src/test/ui/simd/simd-array-trait.rs b/src/test/ui/simd/simd-array-trait.rs new file mode 100644 index 00000000000..6219e7ca83b --- /dev/null +++ b/src/test/ui/simd/simd-array-trait.rs @@ -0,0 +1,40 @@ +// Figuring out the size of a vector type that depends on traits doesn't ICE + +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +#![feature(repr_simd, platform_intrinsics, const_generics)] +#![allow(non_camel_case_types, incomplete_features)] + +pub trait Simd { + type Lane: Clone + Copy; + const SIZE: usize; +} + +pub struct i32x4; +impl Simd for i32x4 { + type Lane = i32; + const SIZE: usize = 4; +} + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct T([S::Lane; S::SIZE]); //~ ERROR constant expression depends on a generic parameter + +extern "platform-intrinsic" { + fn simd_insert(x: T, idx: u32, y: E) -> T; + fn simd_extract(x: T, idx: u32) -> E; +} + +pub fn main() { + let mut t = T::([0; 4]); + unsafe { + for i in 0_i32..4 { + t = simd_insert(t, i as u32, i); + } + for i in 0_i32..4 { + assert_eq!(i, simd_extract(t, i as u32)); + } + } +} diff --git a/src/test/ui/simd/simd-array-trait.stderr b/src/test/ui/simd/simd-array-trait.stderr new file mode 100644 index 00000000000..c100e020c54 --- /dev/null +++ b/src/test/ui/simd/simd-array-trait.stderr @@ -0,0 +1,10 @@ +error: constant expression depends on a generic parameter + --> $DIR/simd-array-trait.rs:23:23 + | +LL | pub struct T([S::Lane; S::SIZE]); + | ^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to previous error +