mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-06 20:13:42 +00:00
Rollup merge of #87716 - calebzulawski:master, r=workingjubilee
Allow generic SIMD array element type Fixes the following: ```rust #[repr(simd)] struct V<T>([T; 4]); ``` cc ``@workingjubilee``
This commit is contained in:
commit
331e78d804
@ -1220,6 +1220,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
|
||||
match e.kind() {
|
||||
ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
|
||||
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
|
||||
ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
|
||||
ty::Array(t, _clen)
|
||||
if matches!(
|
||||
t.kind(),
|
||||
|
@ -10,7 +10,15 @@ struct f32x4(f32, f32, f32, f32);
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct S<const N: usize>([f32; N]);
|
||||
struct A<const N: usize>([f32; N]);
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct B<T>([T; 4]);
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct C<T, const N: usize>([T; N]);
|
||||
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
@ -29,7 +37,23 @@ impl ops::Add for f32x4 {
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Add for S<4> {
|
||||
impl ops::Add for A<4> {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
unsafe { simd_add(self, rhs) }
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Add for B<f32> {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
unsafe { simd_add(self, rhs) }
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Add for C<f32, 4> {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
@ -39,19 +63,23 @@ impl ops::Add for S<4> {
|
||||
|
||||
|
||||
pub fn main() {
|
||||
let lr = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32);
|
||||
let x = [1.0f32, 2.0f32, 3.0f32, 4.0f32];
|
||||
let y = [2.0f32, 4.0f32, 6.0f32, 8.0f32];
|
||||
|
||||
// lame-o
|
||||
let f32x4(x, y, z, w) = add(lr, lr);
|
||||
assert_eq!(x, 2.0f32);
|
||||
assert_eq!(y, 4.0f32);
|
||||
assert_eq!(z, 6.0f32);
|
||||
assert_eq!(w, 8.0f32);
|
||||
let a = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32);
|
||||
let f32x4(a0, a1, a2, a3) = add(a, a);
|
||||
assert_eq!(a0, 2.0f32);
|
||||
assert_eq!(a1, 4.0f32);
|
||||
assert_eq!(a2, 6.0f32);
|
||||
assert_eq!(a3, 8.0f32);
|
||||
|
||||
let lr2 = S::<4>([1.0f32, 2.0f32, 3.0f32, 4.0f32]);
|
||||
let [x, y, z, w] = add(lr2, lr2).0;
|
||||
assert_eq!(x, 2.0f32);
|
||||
assert_eq!(y, 4.0f32);
|
||||
assert_eq!(z, 6.0f32);
|
||||
assert_eq!(w, 8.0f32);
|
||||
let a = A(x);
|
||||
assert_eq!(add(a, a).0, y);
|
||||
|
||||
let b = B(x);
|
||||
assert_eq!(add(b, b).0, y);
|
||||
|
||||
let c = C(x);
|
||||
assert_eq!(add(c, c).0, y);
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
// build-fail
|
||||
|
||||
#![feature(repr_simd)]
|
||||
|
||||
struct E;
|
||||
|
||||
// error-pattern:monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
|
||||
|
||||
#[repr(simd)]
|
||||
struct S<T>([T; 4]);
|
||||
|
||||
fn main() {
|
||||
let _v: Option<S<E>> = None;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
error: monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user