Skip to content

Commit 8d1f533

Browse files
committed
also test unsafe cast intrinsic (happy cases)
1 parent 85dff8b commit 8d1f533

File tree

1 file changed

+125
-60
lines changed

1 file changed

+125
-60
lines changed

tests/run-pass/float.rs

Lines changed: 125 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,63 @@ fn assert_eq<T: PartialEq + Debug>(x: T, y: T) {
1010
assert_eq!(x, y);
1111
}
1212

13+
trait FloatToInt<Int>: Copy {
14+
fn cast(self) -> Int;
15+
unsafe fn cast_unchecked(self) -> Int;
16+
}
17+
18+
impl FloatToInt<i8> for f32 {
19+
fn cast(self) -> i8 { self as _ }
20+
unsafe fn cast_unchecked(self) -> i8 { self.to_int_unchecked() }
21+
}
22+
impl FloatToInt<i32> for f32 {
23+
fn cast(self) -> i32 { self as _ }
24+
unsafe fn cast_unchecked(self) -> i32 { self.to_int_unchecked() }
25+
}
26+
impl FloatToInt<u32> for f32 {
27+
fn cast(self) -> u32 { self as _ }
28+
unsafe fn cast_unchecked(self) -> u32 { self.to_int_unchecked() }
29+
}
30+
impl FloatToInt<i64> for f32 {
31+
fn cast(self) -> i64 { self as _ }
32+
unsafe fn cast_unchecked(self) -> i64 { self.to_int_unchecked() }
33+
}
34+
impl FloatToInt<u64> for f32 {
35+
fn cast(self) -> u64 { self as _ }
36+
unsafe fn cast_unchecked(self) -> u64 { self.to_int_unchecked() }
37+
}
38+
39+
impl FloatToInt<i8> for f64 {
40+
fn cast(self) -> i8 { self as _ }
41+
unsafe fn cast_unchecked(self) -> i8 { self.to_int_unchecked() }
42+
}
43+
impl FloatToInt<i32> for f64 {
44+
fn cast(self) -> i32 { self as _ }
45+
unsafe fn cast_unchecked(self) -> i32 { self.to_int_unchecked() }
46+
}
47+
impl FloatToInt<u32> for f64 {
48+
fn cast(self) -> u32 { self as _ }
49+
unsafe fn cast_unchecked(self) -> u32 { self.to_int_unchecked() }
50+
}
51+
impl FloatToInt<i64> for f64 {
52+
fn cast(self) -> i64 { self as _ }
53+
unsafe fn cast_unchecked(self) -> i64 { self.to_int_unchecked() }
54+
}
55+
impl FloatToInt<u64> for f64 {
56+
fn cast(self) -> u64 { self as _ }
57+
unsafe fn cast_unchecked(self) -> u64 { self.to_int_unchecked() }
58+
}
59+
60+
/// Test this cast both via `as` and via `approx_unchecked` (i.e., it must not saturate).
61+
#[track_caller]
62+
#[inline(never)]
63+
fn test_cast<F, I>(x: F, y: I)
64+
where F: FloatToInt<I>, I: PartialEq + Debug
65+
{
66+
assert_eq!(x.cast(), y);
67+
assert_eq!(unsafe { x.cast_unchecked() }, y);
68+
}
69+
1370
fn main() {
1471
basic();
1572
casts();
@@ -50,19 +107,23 @@ fn basic() {
50107
}
51108

52109
fn casts() {
110+
// f32 -> i8
111+
test_cast::<f32, i8>(127.99, 127);
112+
test_cast::<f32, i8>(-128.99, -128);
113+
53114
// f32 -> i32
54-
assert_eq::<i32>(0.0f32 as i32, 0);
55-
assert_eq::<i32>(-0.0f32 as i32, 0);
56-
assert_eq::<i32>(/*0x1p-149*/ f32::from_bits(0x00000001) as i32, 0);
57-
assert_eq::<i32>(/*-0x1p-149*/ f32::from_bits(0x80000001) as i32, 0);
58-
assert_eq::<i32>(/*0x1.19999ap+0*/ f32::from_bits(0x3f8ccccd) as i32, 1);
59-
assert_eq::<i32>(/*-0x1.19999ap+0*/ f32::from_bits(0xbf8ccccd) as i32, -1);
60-
assert_eq::<i32>(1.9f32 as i32, 1);
61-
assert_eq::<i32>(-1.9f32 as i32, -1);
62-
assert_eq::<i32>(5.0f32 as i32, 5);
63-
assert_eq::<i32>(-5.0f32 as i32, -5);
64-
assert_eq::<i32>(2147483520.0f32 as i32, 2147483520);
65-
assert_eq::<i32>(-2147483648.0f32 as i32, -2147483648);
115+
test_cast::<f32, i32>(0.0, 0);
116+
test_cast::<f32, i32>(-0.0, 0);
117+
test_cast::<f32, i32>(/*0x1p-149*/ f32::from_bits(0x00000001), 0);
118+
test_cast::<f32, i32>(/*-0x1p-149*/ f32::from_bits(0x80000001), 0);
119+
test_cast::<f32, i32>(/*0x1.19999ap+0*/ f32::from_bits(0x3f8ccccd), 1);
120+
test_cast::<f32, i32>(/*-0x1.19999ap+0*/ f32::from_bits(0xbf8ccccd), -1);
121+
test_cast::<f32, i32>(1.9, 1);
122+
test_cast::<f32, i32>(-1.9, -1);
123+
test_cast::<f32, i32>(5.0, 5);
124+
test_cast::<f32, i32>(-5.0, -5);
125+
test_cast::<f32, i32>(2147483520.0, 2147483520);
126+
test_cast::<f32, i32>(-2147483648.0, -2147483648);
66127
// unrepresentable casts
67128
assert_eq::<i32>(2147483648.0f32 as i32, i32::MAX);
68129
assert_eq::<i32>(-2147483904.0f32 as i32, i32::MIN);
@@ -74,19 +135,19 @@ fn casts() {
74135
assert_eq::<i32>((-f32::NAN) as i32, 0);
75136

76137
// f32 -> u32
77-
assert_eq::<u32>(0.0f32 as u32, 0);
78-
assert_eq::<u32>(-0.0f32 as u32, 0);
79-
assert_eq::<u32>(/*0x1p-149*/ f32::from_bits(0x1) as u32, 0);
80-
assert_eq::<u32>(/*-0x1p-149*/ f32::from_bits(0x80000001) as u32, 0);
81-
assert_eq::<u32>(/*0x1.19999ap+0*/ f32::from_bits(0x3f8ccccd) as u32, 1);
82-
assert_eq::<u32>(1.9f32 as u32, 1);
83-
assert_eq::<u32>(5.0f32 as u32, 5);
84-
assert_eq::<u32>(2147483648.0f32 as u32, 0x8000_0000);
85-
assert_eq::<u32>(4294967040.0f32 as u32, 0u32.wrapping_sub(256));
86-
assert_eq::<u32>(/*-0x1.ccccccp-1*/ f32::from_bits(0xbf666666) as u32, 0);
87-
assert_eq::<u32>(/*-0x1.fffffep-1*/ f32::from_bits(0xbf7fffff) as u32, 0);
88-
assert_eq::<u32>((u32::MAX-127) as f32 as u32, u32::MAX); // rounding loss
89-
assert_eq::<u32>((u32::MAX-128) as f32 as u32, u32::MAX-255); // rounding loss
138+
test_cast::<f32, u32>(0.0, 0);
139+
test_cast::<f32, u32>(-0.0, 0);
140+
test_cast::<f32, u32>(/*0x1p-149*/ f32::from_bits(0x1), 0);
141+
test_cast::<f32, u32>(/*-0x1p-149*/ f32::from_bits(0x80000001), 0);
142+
test_cast::<f32, u32>(/*0x1.19999ap+0*/ f32::from_bits(0x3f8ccccd), 1);
143+
test_cast::<f32, u32>(1.9, 1);
144+
test_cast::<f32, u32>(5.0, 5);
145+
test_cast::<f32, u32>(2147483648.0, 0x8000_0000);
146+
test_cast::<f32, u32>(4294967040.0, 0u32.wrapping_sub(256));
147+
test_cast::<f32, u32>(/*-0x1.ccccccp-1*/ f32::from_bits(0xbf666666), 0);
148+
test_cast::<f32, u32>(/*-0x1.fffffep-1*/ f32::from_bits(0xbf7fffff), 0);
149+
test_cast::<f32, u32>((u32::MAX-127) as f32, u32::MAX); // rounding loss
150+
test_cast::<f32, u32>((u32::MAX-128) as f32, u32::MAX-255); // rounding loss
90151
// unrepresentable casts
91152
assert_eq::<u32>(4294967296.0f32 as u32, u32::MAX);
92153
assert_eq::<u32>(-5.0f32 as u32, 0);
@@ -98,40 +159,44 @@ fn casts() {
98159
assert_eq::<u32>((-f32::NAN) as u32, 0);
99160

100161
// f32 -> i64
101-
assert_eq::<i64>(4294967296.0f32 as i64, 4294967296);
102-
assert_eq::<i64>(-4294967296.0f32 as i64, -4294967296);
103-
assert_eq::<i64>(9223371487098961920.0f32 as i64, 9223371487098961920);
104-
assert_eq::<i64>(-9223372036854775808.0f32 as i64, -9223372036854775808);
162+
test_cast::<f32, i64>(4294967296.0, 4294967296);
163+
test_cast::<f32, i64>(-4294967296.0, -4294967296);
164+
test_cast::<f32, i64>(9223371487098961920.0, 9223371487098961920);
165+
test_cast::<f32, i64>(-9223372036854775808.0, -9223372036854775808);
166+
167+
// f64 -> i8
168+
test_cast::<f64, i8>(127.99, 127);
169+
test_cast::<f64, i8>(-128.99, -128);
105170

106171
// f64 -> i32
107-
assert_eq::<i32>(0.0f64 as i32, 0);
108-
assert_eq::<i32>(-0.0f64 as i32, 0);
109-
assert_eq::<i32>(/*0x1.199999999999ap+0*/ f64::from_bits(0x3ff199999999999a) as i32, 1);
110-
assert_eq::<i32>(/*-0x1.199999999999ap+0*/ f64::from_bits(0xbff199999999999a) as i32, -1);
111-
assert_eq::<i32>(1.9f64 as i32, 1);
112-
assert_eq::<i32>(-1.9f64 as i32, -1);
113-
assert_eq::<i32>(1e8f64 as i32, 100_000_000);
114-
assert_eq::<i32>(2147483647.0f64 as i32, 2147483647);
115-
assert_eq::<i32>(-2147483648.0f64 as i32, -2147483648);
172+
test_cast::<f64, i32>(0.0, 0);
173+
test_cast::<f64, i32>(-0.0, 0);
174+
test_cast::<f64, i32>(/*0x1.199999999999ap+0*/ f64::from_bits(0x3ff199999999999a), 1);
175+
test_cast::<f64, i32>(/*-0x1.199999999999ap+0*/ f64::from_bits(0xbff199999999999a), -1);
176+
test_cast::<f64, i32>(1.9, 1);
177+
test_cast::<f64, i32>(-1.9, -1);
178+
test_cast::<f64, i32>(1e8, 100_000_000);
179+
test_cast::<f64, i32>(2147483647.0, 2147483647);
180+
test_cast::<f64, i32>(-2147483648.0, -2147483648);
116181
// unrepresentable casts
117182
assert_eq::<i32>(2147483648.0f64 as i32, i32::MAX);
118183
assert_eq::<i32>(-2147483649.0f64 as i32, i32::MIN);
119184

120185
// f64 -> i64
121-
assert_eq::<i64>(0.0f64 as i64, 0);
122-
assert_eq::<i64>(-0.0f64 as i64, 0);
123-
assert_eq::<i64>(/*0x0.0000000000001p-1022*/ f64::from_bits(0x1) as i64, 0);
124-
assert_eq::<i64>(/*-0x0.0000000000001p-1022*/ f64::from_bits(0x8000000000000001) as i64, 0);
125-
assert_eq::<i64>(/*0x1.199999999999ap+0*/ f64::from_bits(0x3ff199999999999a) as i64, 1);
126-
assert_eq::<i64>(/*-0x1.199999999999ap+0*/ f64::from_bits(0xbff199999999999a) as i64, -1);
127-
assert_eq::<i64>(5.0f64 as i64, 5);
128-
assert_eq::<i64>(5.9f64 as i64, 5);
129-
assert_eq::<i64>(-5.0f64 as i64, -5);
130-
assert_eq::<i64>(-5.9f64 as i64, -5);
131-
assert_eq::<i64>(4294967296.0f64 as i64, 4294967296);
132-
assert_eq::<i64>(-4294967296.0f64 as i64, -4294967296);
133-
assert_eq::<i64>(9223372036854774784.0f64 as i64, 9223372036854774784);
134-
assert_eq::<i64>(-9223372036854775808.0f64 as i64, -9223372036854775808);
186+
test_cast::<f64, i64>(0.0, 0);
187+
test_cast::<f64, i64>(-0.0, 0);
188+
test_cast::<f64, i64>(/*0x0.0000000000001p-1022*/ f64::from_bits(0x1), 0);
189+
test_cast::<f64, i64>(/*-0x0.0000000000001p-1022*/ f64::from_bits(0x8000000000000001), 0);
190+
test_cast::<f64, i64>(/*0x1.199999999999ap+0*/ f64::from_bits(0x3ff199999999999a), 1);
191+
test_cast::<f64, i64>(/*-0x1.199999999999ap+0*/ f64::from_bits(0xbff199999999999a), -1);
192+
test_cast::<f64, i64>(5.0, 5);
193+
test_cast::<f64, i64>(5.9, 5);
194+
test_cast::<f64, i64>(-5.0, -5);
195+
test_cast::<f64, i64>(-5.9, -5);
196+
test_cast::<f64, i64>(4294967296.0, 4294967296);
197+
test_cast::<f64, i64>(-4294967296.0, -4294967296);
198+
test_cast::<f64, i64>(9223372036854774784.0, 9223372036854774784);
199+
test_cast::<f64, i64>(-9223372036854775808.0, -9223372036854775808);
135200
// unrepresentable casts
136201
assert_eq::<i64>(9223372036854775808.0f64 as i64, i64::MAX);
137202
assert_eq::<i64>(-9223372036854777856.0f64 as i64, i64::MIN);
@@ -143,14 +208,14 @@ fn casts() {
143208
assert_eq::<i64>((-f64::NAN) as i64, 0);
144209

145210
// f64 -> u64
146-
assert_eq::<u64>(0.0f64 as u64, 0);
147-
assert_eq::<u64>(-0.0f64 as u64, 0);
148-
assert_eq::<u64>(5.0f64 as u64, 5);
149-
assert_eq::<u64>(-5.0f64 as u64, 0);
150-
assert_eq::<u64>(1e16f64 as u64, 10000000000000000);
151-
assert_eq::<u64>((u64::MAX-1023) as f64 as u64, u64::MAX); // rounding loss
152-
assert_eq::<u64>((u64::MAX-1024) as f64 as u64, u64::MAX-2047); // rounding loss
153-
assert_eq::<u64>(9223372036854775808.0f64 as u64, 9223372036854775808);
211+
test_cast::<f64, u64>(0.0, 0);
212+
test_cast::<f64, u64>(-0.0, 0);
213+
test_cast::<f64, u64>(5.0, 5);
214+
test_cast::<f64, u64>(-5.0, 0);
215+
test_cast::<f64, u64>(1e16, 10000000000000000);
216+
test_cast::<f64, u64>((u64::MAX-1023) as f64, u64::MAX); // rounding loss
217+
test_cast::<f64, u64>((u64::MAX-1024) as f64, u64::MAX-2047); // rounding loss
218+
test_cast::<f64, u64>(9223372036854775808.0, 9223372036854775808);
154219
// unrepresentable casts
155220
assert_eq::<u64>(18446744073709551616.0f64 as u64, u64::MAX);
156221
assert_eq::<u64>(f64::MAX as u64, u64::MAX);

0 commit comments

Comments
 (0)