Skip to content

Commit 64d695b

Browse files
committed
Adds tests to ensure some base op traits exist.
These tests invoke the various op traits using all accepted types they are implemented for as well as for references to those types. This fixes #49660 and ensures the following implementations exist: * `Add`, `Sub`, `Mul`, `Div`, `Rem` * `T op T`, `T op &T`, `&T op T` and `&T op &T` * for all integer and floating point types * `AddAssign`, `SubAssign`, `MulAssign`, `DivAssign`, `RemAssign` * `&mut T op T` and `&mut T op &T` * for all integer and floating point types * `Neg` * `op T` and `op &T` * for all signed integer and floating point types * `Not` * `op T` and `op &T` * for `bool` * `BitAnd`, `BitOr`, `BitXor` * `T op T`, `T op &T`, `&T op T` and `&T op &T` * for all integer types and bool * `BitAndAssign`, `BitOrAssign`, `BitXorAssign` * `&mut T op T` and `&mut T op &T` * for all integer types and bool * `Shl`, `Shr` * `L op R`, `L op &R`, `&L op R` and `&L op &R` * for all pairs of integer types * `ShlAssign`, `ShrAssign` * `&mut L op R`, `&mut L op &R` * for all pairs of integer types
1 parent 8ddad18 commit 64d695b

File tree

2 files changed

+245
-0
lines changed

2 files changed

+245
-0
lines changed

library/core/tests/num/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mod u8;
2929
mod bignum;
3030
mod dec2flt;
3131
mod flt2dec;
32+
mod ops;
3233
mod wrapping;
3334

3435
mod nan;

library/core/tests/num/ops.rs

+244
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
use core::ops::*;
2+
3+
// For types L and R, checks that a trait implementation exists for
4+
// * binary ops: L op R, L op &R, &L op R and &L op &R
5+
// * assign ops: &mut L op R, &mut L op &R
6+
macro_rules! impl_defined {
7+
($op:ident, $method:ident($lhs:literal, $rhs:literal), $result:literal, $lt:ty, $rt:ty) => {
8+
let lhs = $lhs as $lt;
9+
let rhs = $rhs as $rt;
10+
assert_eq!($result as $lt, $op::$method(lhs, rhs));
11+
assert_eq!($result as $lt, $op::$method(lhs, &rhs));
12+
assert_eq!($result as $lt, $op::$method(&lhs, rhs));
13+
assert_eq!($result as $lt, $op::$method(&lhs, &rhs));
14+
};
15+
($op:ident, $method:ident(&mut $lhs:literal, $rhs:literal), $result:literal, $lt:ty, $rt:ty) => {
16+
let rhs = $rhs as $rt;
17+
let mut lhs = $lhs as $lt;
18+
$op::$method(&mut lhs, rhs);
19+
assert_eq!($result as $lt, lhs);
20+
21+
let mut lhs = $lhs as $lt;
22+
$op::$method(&mut lhs, &rhs);
23+
assert_eq!($result as $lt, lhs);
24+
};
25+
}
26+
27+
// For all specified types T, checks that a trait implementation exists for
28+
// * binary ops: T op T, T op &T, &T op T and &T op &T
29+
// * assign ops: &mut T op T, &mut T op &T
30+
// * unary ops: op T and op &T
31+
macro_rules! impls_defined {
32+
($op:ident, $method:ident($lhs:literal, $rhs:literal), $result:literal, $($t:ty),+) => {$(
33+
impl_defined!($op, $method($lhs, $rhs), $result, $t, $t);
34+
)+};
35+
($op:ident, $method:ident(&mut $lhs:literal, $rhs:literal), $result:literal, $($t:ty),+) => {$(
36+
impl_defined!($op, $method(&mut $lhs, $rhs), $result, $t, $t);
37+
)+};
38+
($op:ident, $method:ident($operand:literal), $result:literal, $($t:ty),+) => {$(
39+
let operand = $operand as $t;
40+
assert_eq!($result as $t, $op::$method(operand));
41+
assert_eq!($result as $t, $op::$method(&operand));
42+
)+};
43+
}
44+
45+
macro_rules! test_op {
46+
($fn_name:ident, $op:ident::$method:ident($lhs:literal, $rhs:literal), $result:literal, $($t:ty),+) => {
47+
#[test]
48+
fn $fn_name() {
49+
impls_defined!($op, $method($lhs, $rhs), $result, $($t),+);
50+
}
51+
};
52+
($fn_name:ident, $op:ident::$method:ident(&mut $lhs:literal, $rhs:literal), $result:literal, $($t:ty),+) => {
53+
#[test]
54+
fn $fn_name() {
55+
impls_defined!($op, $method(&mut $lhs, $rhs), $result, $($t),+);
56+
}
57+
};
58+
($fn_name:ident, $op:ident::$method:ident($lhs:literal), $result:literal, $($t:ty),+) => {
59+
#[test]
60+
fn $fn_name() {
61+
impls_defined!($op, $method($lhs), $result, $($t),+);
62+
}
63+
};
64+
}
65+
66+
test_op!(test_neg_defined, Neg::neg(0), 0, i8, i16, i32, i64, f32, f64);
67+
#[cfg(not(target_os = "emscripten"))]
68+
test_op!(test_neg_defined_128, Neg::neg(0), 0, i128);
69+
70+
test_op!(test_not_defined_bool, Not::not(true), false, bool);
71+
72+
macro_rules! test_arith_op {
73+
($fn_name:ident, $op:ident::$method:ident($lhs:literal, $rhs:literal)) => {
74+
#[test]
75+
fn $fn_name() {
76+
impls_defined!(
77+
$op,
78+
$method($lhs, $rhs),
79+
0,
80+
i8,
81+
i16,
82+
i32,
83+
i64,
84+
isize,
85+
u8,
86+
u16,
87+
u32,
88+
u64,
89+
usize,
90+
f32,
91+
f64
92+
);
93+
#[cfg(not(target_os = "emscripten"))]
94+
impls_defined!($op, $method($lhs, $rhs), 0, i128, u128);
95+
}
96+
};
97+
($fn_name:ident, $op:ident::$method:ident(&mut $lhs:literal, $rhs:literal)) => {
98+
#[test]
99+
fn $fn_name() {
100+
impls_defined!(
101+
$op,
102+
$method(&mut $lhs, $rhs),
103+
0,
104+
i8,
105+
i16,
106+
i32,
107+
i64,
108+
isize,
109+
u8,
110+
u16,
111+
u32,
112+
u64,
113+
usize,
114+
f32,
115+
f64
116+
);
117+
#[cfg(not(target_os = "emscripten"))]
118+
impls_defined!($op, $method(&mut $lhs, $rhs), 0, i128, u128);
119+
}
120+
};
121+
}
122+
123+
test_arith_op!(test_add_defined, Add::add(0, 0));
124+
test_arith_op!(test_add_assign_defined, AddAssign::add_assign(&mut 0, 0));
125+
test_arith_op!(test_sub_defined, Sub::sub(0, 0));
126+
test_arith_op!(test_sub_assign_defined, SubAssign::sub_assign(&mut 0, 0));
127+
test_arith_op!(test_mul_defined, Mul::mul(0, 0));
128+
test_arith_op!(test_mul_assign_defined, MulAssign::mul_assign(&mut 0, 0));
129+
test_arith_op!(test_div_defined, Div::div(0, 1));
130+
test_arith_op!(test_div_assign_defined, DivAssign::div_assign(&mut 0, 1));
131+
test_arith_op!(test_rem_defined, Rem::rem(0, 1));
132+
test_arith_op!(test_rem_assign_defined, RemAssign::rem_assign(&mut 0, 1));
133+
134+
macro_rules! test_bitop {
135+
($test_name:ident, $op:ident::$method:ident) => {
136+
#[test]
137+
fn $test_name() {
138+
impls_defined!(
139+
$op,
140+
$method(0, 0),
141+
0,
142+
i8,
143+
i16,
144+
i32,
145+
i64,
146+
isize,
147+
u8,
148+
u16,
149+
u32,
150+
u64,
151+
usize
152+
);
153+
#[cfg(not(target_os = "emscripten"))]
154+
impls_defined!($op, $method(0, 0), 0, i128, u128);
155+
impls_defined!($op, $method(false, false), false, bool);
156+
}
157+
};
158+
}
159+
macro_rules! test_bitop_assign {
160+
($test_name:ident, $op:ident::$method:ident) => {
161+
#[test]
162+
fn $test_name() {
163+
impls_defined!(
164+
$op,
165+
$method(&mut 0, 0),
166+
0,
167+
i8,
168+
i16,
169+
i32,
170+
i64,
171+
isize,
172+
u8,
173+
u16,
174+
u32,
175+
u64,
176+
usize
177+
);
178+
#[cfg(not(target_os = "emscripten"))]
179+
impls_defined!($op, $method(&mut 0, 0), 0, i128, u128);
180+
impls_defined!($op, $method(&mut false, false), false, bool);
181+
}
182+
};
183+
}
184+
185+
test_bitop!(test_bitand_defined, BitAnd::bitand);
186+
test_bitop_assign!(test_bitand_assign_defined, BitAndAssign::bitand_assign);
187+
test_bitop!(test_bitor_defined, BitOr::bitor);
188+
test_bitop_assign!(test_bitor_assign_defined, BitOrAssign::bitor_assign);
189+
test_bitop!(test_bitxor_defined, BitXor::bitxor);
190+
test_bitop_assign!(test_bitxor_assign_defined, BitXorAssign::bitxor_assign);
191+
192+
macro_rules! test_shift_inner {
193+
($op:ident::$method:ident, $lt:ty, $($rt:ty),+) => {
194+
$(impl_defined!($op, $method(0,0), 0, $lt, $rt);)+
195+
};
196+
($op:ident::$method:ident, $lt:ty) => {
197+
test_shift_inner!($op::$method, $lt, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
198+
#[cfg(not(target_os = "emscripten"))]
199+
test_shift_inner!($op::$method, $lt, i128, u128);
200+
};
201+
}
202+
203+
macro_rules! test_shift {
204+
($op:ident::$method:ident, $($lt:ty),+) => {
205+
$(test_shift_inner!($op::$method, $lt);)+
206+
};
207+
($test_name:ident, $op:ident::$method:ident) => {
208+
#[test]
209+
fn $test_name() {
210+
test_shift!($op::$method, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
211+
#[cfg(not(target_os = "emscripten"))]
212+
test_shift!($op::$method, i128, u128);
213+
}
214+
};
215+
}
216+
217+
macro_rules! test_shift_assign_inner {
218+
($op:ident::$method:ident, $lt:ty, $($rt:ty),+) => {
219+
$(impl_defined!($op, $method(&mut 0,0), 0, $lt, $rt);)+
220+
};
221+
($op:ident::$method:ident, $lt:ty) => {
222+
test_shift_assign_inner!($op::$method, $lt, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
223+
#[cfg(not(target_os = "emscripten"))]
224+
test_shift_assign_inner!($op::$method, $lt, i128, u128);
225+
};
226+
}
227+
228+
macro_rules! test_shift_assign {
229+
($op:ident::$method:ident, $($lt:ty),+) => {
230+
$(test_shift_assign_inner!($op::$method, $lt);)+
231+
};
232+
($test_name:ident, $op:ident::$method:ident) => {
233+
#[test]
234+
fn $test_name() {
235+
test_shift_assign!($op::$method, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
236+
#[cfg(not(target_os = "emscripten"))]
237+
test_shift_assign!($op::$method, i128, u128);
238+
}
239+
};
240+
}
241+
test_shift!(test_shl_defined, Shl::shl);
242+
test_shift_assign!(test_shl_assign_defined, ShlAssign::shl_assign);
243+
test_shift!(test_shr_defined, Shr::shr);
244+
test_shift_assign!(test_shr_assign_defined, ShrAssign::shr_assign);

0 commit comments

Comments
 (0)