Skip to content

Commit b23de51

Browse files
committed
Allow generic SIMD array element type
1 parent e3b1c12 commit b23de51

File tree

4 files changed

+62
-15
lines changed

4 files changed

+62
-15
lines changed

compiler/rustc_typeck/src/check/check.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
12201220
match e.kind() {
12211221
ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
12221222
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
1223+
ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
12231224
ty::Array(t, _clen)
12241225
if matches!(
12251226
t.kind(),

src/test/ui/simd/simd-generics.rs

+43-15
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@ struct f32x4(f32, f32, f32, f32);
1010

1111
#[repr(simd)]
1212
#[derive(Copy, Clone)]
13-
struct S<const N: usize>([f32; N]);
13+
struct A<const N: usize>([f32; N]);
14+
15+
#[repr(simd)]
16+
#[derive(Copy, Clone)]
17+
struct B<T>([T; 4]);
18+
19+
#[repr(simd)]
20+
#[derive(Copy, Clone)]
21+
struct C<T, const N: usize>([T; N]);
1422

1523

1624
extern "platform-intrinsic" {
@@ -29,7 +37,23 @@ impl ops::Add for f32x4 {
2937
}
3038
}
3139

32-
impl ops::Add for S<4> {
40+
impl ops::Add for A<4> {
41+
type Output = Self;
42+
43+
fn add(self, rhs: Self) -> Self {
44+
unsafe { simd_add(self, rhs) }
45+
}
46+
}
47+
48+
impl ops::Add for B<f32> {
49+
type Output = Self;
50+
51+
fn add(self, rhs: Self) -> Self {
52+
unsafe { simd_add(self, rhs) }
53+
}
54+
}
55+
56+
impl ops::Add for C<f32, 4> {
3357
type Output = Self;
3458

3559
fn add(self, rhs: Self) -> Self {
@@ -39,19 +63,23 @@ impl ops::Add for S<4> {
3963

4064

4165
pub fn main() {
42-
let lr = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32);
66+
let x = [1.0f32, 2.0f32, 3.0f32, 4.0f32];
67+
let y = [2.0f32, 4.0f32, 6.0f32, 8.0f32];
4368

4469
// lame-o
45-
let f32x4(x, y, z, w) = add(lr, lr);
46-
assert_eq!(x, 2.0f32);
47-
assert_eq!(y, 4.0f32);
48-
assert_eq!(z, 6.0f32);
49-
assert_eq!(w, 8.0f32);
50-
51-
let lr2 = S::<4>([1.0f32, 2.0f32, 3.0f32, 4.0f32]);
52-
let [x, y, z, w] = add(lr2, lr2).0;
53-
assert_eq!(x, 2.0f32);
54-
assert_eq!(y, 4.0f32);
55-
assert_eq!(z, 6.0f32);
56-
assert_eq!(w, 8.0f32);
70+
let a = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32);
71+
let f32x4(a0, a1, a2, a3) = add(a, a);
72+
assert_eq!(a0, 2.0f32);
73+
assert_eq!(a1, 4.0f32);
74+
assert_eq!(a2, 6.0f32);
75+
assert_eq!(a3, 8.0f32);
76+
77+
let a = A(x);
78+
assert_eq!(add(a, a).0, y);
79+
80+
let b = B(x);
81+
assert_eq!(add(b, b).0, y);
82+
83+
let c = C(x);
84+
assert_eq!(add(c, c).0, y);
5785
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// build-fail
2+
3+
#![feature(repr_simd)]
4+
5+
struct E;
6+
7+
// error-pattern:monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
8+
9+
#[repr(simd)]
10+
struct S<T>([T; 4]);
11+
12+
fn main() {
13+
let _v: Option<S<E>> = None;
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
error: monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`
2+
3+
error: aborting due to previous error
4+

0 commit comments

Comments
 (0)