-
Notifications
You must be signed in to change notification settings - Fork 372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement float_to_int_unchecked #1325
Merged
Merged
Changes from 6 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
8d1f533
also test unsafe cast intrinsic (happy cases)
RalfJung 78ce616
implement float_to_int_unchecked
RalfJung 30d07c8
move error-pattern to inline annotation where possible
RalfJung 25c71e5
test some more corner cases in happy float casts
RalfJung 17c52d4
add tests for invalid float-to-int casts
RalfJung a82efce
remove some unnecessary trait bounds
RalfJung bb38ab4
use u128::MAX symbolic name
RalfJung File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f32, i32>(f32::INFINITY); } //~ ERROR: cannot be represented in target type `i32` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f32, i32>(f32::NEG_INFINITY); } //~ ERROR: cannot be represented in target type `i32` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f32, u32>(f32::NAN); } //~ ERROR: cannot be represented in target type `u32` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f32, u32>(-f32::NAN); } //~ ERROR: cannot be represented in target type `u32` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f32, u32>(-1.000000001f32); } //~ ERROR: cannot be represented in target type `u32` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f32, i32>(2147483648.0f32); } //~ ERROR: cannot be represented in target type `i32` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f32, u32>((u32::MAX-127) as f32); } //~ ERROR: cannot be represented in target type `u32` | ||
} |
10 changes: 10 additions & 0 deletions
10
tests/compile-fail/intrinsics/float_to_int_32_too_small1.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f32, i32>(-2147483904.0f32); } //~ ERROR: cannot be represented in target type `i32` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, u128>(f64::INFINITY); } //~ ERROR: cannot be represented in target type `u128` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, u128>(f64::NEG_INFINITY); } //~ ERROR: cannot be represented in target type `u128` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, i128>(f64::NEG_INFINITY); } //~ ERROR: cannot be represented in target type `i128` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, u32>(f64::NAN); } //~ ERROR: cannot be represented in target type `u32` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, u128>(-1.0000000000001f64); } //~ ERROR: cannot be represented in target type `u128` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, i32>(2147483648.0f64); } //~ ERROR: cannot be represented in target type `i32` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, i64>(9223372036854775808.0f64); } //~ ERROR: cannot be represented in target type `i64` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, u64>(18446744073709551616.0f64); } //~ ERROR: cannot be represented in target type `u64` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, u128>(340282366920938463463374607431768211455.0f64); } //~ ERROR: cannot be represented in target type `u128` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, i128>(240282366920938463463374607431768211455.0f64); } //~ ERROR: cannot be represented in target type `i128` | ||
} |
10 changes: 10 additions & 0 deletions
10
tests/compile-fail/intrinsics/float_to_int_64_too_small1.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, i32>(-2147483649.0f64); } //~ ERROR: cannot be represented in target type `i32` | ||
} |
10 changes: 10 additions & 0 deletions
10
tests/compile-fail/intrinsics/float_to_int_64_too_small2.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, i64>(-9223372036854777856.0f64); } //~ ERROR: cannot be represented in target type `i64` | ||
} |
10 changes: 10 additions & 0 deletions
10
tests/compile-fail/intrinsics/float_to_int_64_too_small3.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(intrinsics)] | ||
|
||
// Directly call intrinsic to avoid debug assertions in libstd | ||
extern "rust-intrinsic" { | ||
fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int; | ||
} | ||
|
||
fn main() { | ||
unsafe { float_to_int_unchecked::<f64, i128>(-240282366920938463463374607431768211455.0f64); } //~ ERROR: cannot be represented in target type `i128` | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this test is correct, but it looks misleading or confusing. 340282366920938463463374607431768211455 (the integer) is
u128::MAX
, so at first glance the conversion should succeed. But the340282366920938463463374607431768211455.0f64
float is in fact not equal to that integer. That integer cannot be represented exactly in f64, so the Rust parser presumably rounds to the nearest representable float which is one more, 2^128, and does indeed overflow conversion to u128.(I’m using Python to figure this out since it has infinite-capacity integers and
f64
floats.a = 340282366920938463463374607431768211455; (hex(a), int(float(a)) - a, a.bit_length())
prints('0xffffffffffffffffffffffffffffffff', 1, 128)
.)But the point of these tests is not to test the Rust parser. I feel it’d be better to pick a decimal representation of the float that would, if precision and range were infinite, have the same numerical value as the actual f64 value does.
In fact it’d be even better if the source code of test cases could contain something closer to the memory representation of
f64
. Hex float syntax exists, but not in Rust literals. I don’t know if this would be worth using a library for parsing it from strings. I see some other tests usef32::from_bits
with hex integers, but that’s much harder for humans to read.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, that number here and these
from_bits
constants are all derived from https://github.com/WebAssembly/testsuite/blob/master/conversions.wast.I could change this to
u128::MAX as f64
, if you think that's better.