Skip to content

Commit 8003b04

Browse files
impl Op<&'_ RHS> for &'_ LHS
1 parent 257fa7a commit 8003b04

File tree

2 files changed

+106
-30
lines changed

2 files changed

+106
-30
lines changed

Diff for: crates/core_simd/src/ops/deref.rs

+84-30
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,124 @@
11
//! This module hacks in "implicit deref" for Simd's operators.
22
//! Ideally, Rust would take care of this itself,
33
//! and method calls usually handle the LHS implicitly.
4-
//! So, we'll manually deref the RHS.
4+
//! But this is not the case with arithmetic ops.
55
use super::*;
66

7-
macro_rules! deref_ops {
8-
($(impl<T, const LANES: usize> $trait:ident<&Self> for Simd<T, LANES> {
9-
fn $call:ident(rhs: &Self)
10-
})*) => {
11-
$(impl<T, const LANES: usize> $trait<&Self> for Simd<T, LANES>
7+
macro_rules! deref_lhs {
8+
(impl<T, const LANES: usize> $trait:ident for $simd:ty {
9+
fn $call:ident
10+
}) => {
11+
impl<T, const LANES: usize> $trait<$simd> for &$simd
12+
where
13+
T: SimdElement,
14+
$simd: $trait<$simd, Output = $simd>,
15+
LaneCount<LANES>: SupportedLaneCount,
16+
{
17+
type Output = Simd<T, LANES>;
18+
19+
#[inline]
20+
#[must_use = "operator returns a new vector without mutating the inputs"]
21+
fn $call(self, rhs: $simd) -> Self::Output {
22+
(*self).$call(rhs)
23+
}
24+
}
25+
};
26+
}
27+
28+
macro_rules! deref_rhs {
29+
(impl<T, const LANES: usize> $trait:ident for $simd:ty {
30+
fn $call:ident
31+
}) => {
32+
impl<T, const LANES: usize> $trait<&$simd> for $simd
1233
where
13-
Self: $trait<Self, Output = Self>,
1434
T: SimdElement,
35+
$simd: $trait<$simd, Output = $simd>,
1536
LaneCount<LANES>: SupportedLaneCount,
1637
{
17-
type Output = Self;
38+
type Output = Simd<T, LANES>;
1839

1940
#[inline]
2041
#[must_use = "operator returns a new vector without mutating the inputs"]
21-
fn $call(self, rhs: &Self) -> Self::Output {
42+
fn $call(self, rhs: &$simd) -> Self::Output {
2243
self.$call(*rhs)
2344
}
24-
})*
45+
}
46+
};
47+
}
48+
49+
macro_rules! deref_ops {
50+
($(impl<T, const LANES: usize> $trait:ident for $simd:ty {
51+
fn $call:ident
52+
})*) => {
53+
$(
54+
deref_rhs! {
55+
impl<T, const LANES: usize> $trait for $simd {
56+
fn $call
57+
}
58+
}
59+
deref_lhs! {
60+
impl<T, const LANES: usize> $trait for $simd {
61+
fn $call
62+
}
63+
}
64+
impl<'lhs, 'rhs, T, const LANES: usize> $trait<&'rhs $simd> for &'lhs $simd
65+
where
66+
T: SimdElement,
67+
$simd: $trait<$simd, Output = $simd>,
68+
LaneCount<LANES>: SupportedLaneCount,
69+
{
70+
type Output = $simd;
71+
72+
#[inline]
73+
#[must_use = "operator returns a new vector without mutating the inputs"]
74+
fn $call(self, rhs: &$simd) -> Self::Output {
75+
(*self).$call(*rhs)
76+
}
77+
}
78+
)*
2579
}
2680
}
2781

2882
deref_ops! {
2983
// Arithmetic
30-
impl<T, const LANES: usize> Add<&Self> for Simd<T, LANES> {
31-
fn add(rhs: &Self)
84+
impl<T, const LANES: usize> Add for Simd<T, LANES> {
85+
fn add
3286
}
3387

34-
impl<T, const LANES: usize> Mul<&Self> for Simd<T, LANES> {
35-
fn mul(rhs: &Self)
88+
impl<T, const LANES: usize> Mul for Simd<T, LANES> {
89+
fn mul
3690
}
3791

38-
impl<T, const LANES: usize> Sub<&Self> for Simd<T, LANES> {
39-
fn sub(rhs: &Self)
92+
impl<T, const LANES: usize> Sub for Simd<T, LANES> {
93+
fn sub
4094
}
4195

42-
impl<T, const LANES: usize> Div<&Self> for Simd<T, LANES> {
43-
fn div(rhs: &Self)
96+
impl<T, const LANES: usize> Div for Simd<T, LANES> {
97+
fn div
4498
}
4599

46-
impl<T, const LANES: usize> Rem<&Self> for Simd<T, LANES> {
47-
fn rem(rhs: &Self)
100+
impl<T, const LANES: usize> Rem for Simd<T, LANES> {
101+
fn rem
48102
}
49103

50104
// Bitops
51-
impl<T, const LANES: usize> BitAnd<&Self> for Simd<T, LANES> {
52-
fn bitand(rhs: &Self)
105+
impl<T, const LANES: usize> BitAnd for Simd<T, LANES> {
106+
fn bitand
53107
}
54108

55-
impl<T, const LANES: usize> BitOr<&Self> for Simd<T, LANES> {
56-
fn bitor(rhs: &Self)
109+
impl<T, const LANES: usize> BitOr for Simd<T, LANES> {
110+
fn bitor
57111
}
58112

59-
impl<T, const LANES: usize> BitXor<&Self> for Simd<T, LANES> {
60-
fn bitxor(rhs: &Self)
113+
impl<T, const LANES: usize> BitXor for Simd<T, LANES> {
114+
fn bitxor
61115
}
62116

63-
impl<T, const LANES: usize> Shl<&Self> for Simd<T, LANES> {
64-
fn shl(rhs: &Self)
117+
impl<T, const LANES: usize> Shl for Simd<T, LANES> {
118+
fn shl
65119
}
66120

67-
impl<T, const LANES: usize> Shr<&Self> for Simd<T, LANES> {
68-
fn shr(rhs: &Self)
121+
impl<T, const LANES: usize> Shr for Simd<T, LANES> {
122+
fn shr
69123
}
70124
}

Diff for: crates/core_simd/tests/autoderef.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Test that we handle all our "auto-deref" cases correctly.
2+
#![feature(portable_simd)]
3+
use core_simd::f32x4;
4+
5+
#[cfg(target_arch = "wasm32")]
6+
use wasm_bindgen_test::*;
7+
8+
#[cfg(target_arch = "wasm32")]
9+
wasm_bindgen_test_configure!(run_in_browser);
10+
11+
#[test]
12+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
13+
fn deref() {
14+
let x = f32x4::splat(1.0);
15+
let y = f32x4::splat(2.0);
16+
let a = &x;
17+
let b = &y;
18+
assert_eq!(f32x4::splat(3.0), x + y);
19+
assert_eq!(f32x4::splat(3.0), x + b);
20+
assert_eq!(f32x4::splat(3.0), a + y);
21+
assert_eq!(f32x4::splat(3.0), a + b);
22+
}

0 commit comments

Comments
 (0)