Skip to content

core: implement float conversion methods - #159954

Open
valentynkit wants to merge 1 commit into
rust-lang:mainfrom
valentynkit:float-conversions
Open

core: implement float conversion methods#159954
valentynkit wants to merge 1 commit into
rust-lang:mainfrom
valentynkit:float-conversions

Conversation

@valentynkit

@valentynkit valentynkit commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Implements the accepted ACP rust-lang/libs-team#810, adding float conversion methods on f16, f32, f64, and f128:

  • cast converts to the target float type (self as Flt, IEEE rounding).
  • to_int_saturating converts to an integer with as semantics: saturating, and NaN to 0.
  • to_int_checked truncates toward zero and returns None on NaN, infinity, or out of range.
  • to_int_strict is to_int_checked().unwrap().

Per the libs-api meetings on the ACP, to_float is named cast and to_int_saturating maps NaN to 0 rather than panicking (which the team noted makes rust-lang/libs-team#831 redundant).

The integer-to-float cast from the ACP is left out: it shares the cast method name on integer types with the integer-to-integer cast in rust-lang/libs-team#811 (being unified with the other integer cast methods in rust-lang/libs-team#833), so it needs a decision on how those fit together. Happy to follow up once that settles.

Tracking issue: #159913

r? libs

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 26, 2026
@rust-log-analyzer

This comment has been minimized.

@valentynkit

Copy link
Copy Markdown
Contributor Author

The Codegen Cranelift failure was a pre-existing cg_clif bug in f128 as {i8,i16,u8,u16}, unrelated to this PR.
Reported in #1680 fixed by rust-lang/rustc_codegen_cranelift@29b920534.
Probably need time to sync the fix from latest changes in rustc codegen cranelift?..

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
[RUSTC-TIMING] corebenches test:true 9.119
[RUSTC-TIMING] allocbenches test:true 8.023
[RUSTC-TIMING] alloctests test:true 18.376
[RUSTC-TIMING] alloctests test:true 19.983
error: VerifierErrors([VerifierError { location: inst22, context: Some("v19 = select.i32 v18, v16, v14  ; v16 = 255"), message: "arg 2 (v14) has type i8, expected i32" }])

error: cranelift verify error:
       function u0:2537(f128) -> i8 uext, i8 system_v {
           ss0 = explicit_slot 2
           gv0 = symbol colocated userextname5
           sig0 = (f128, f128) -> f128 system_v
           sig1 = (f128, f128) -> i32 system_v
           sig2 = (f128, f128) -> i32 system_v
           sig3 = (f128) -> i8 system_v
           sig4 = (f128, f128) -> i32 system_v
           fn0 = u0:6734 sig0
           fn1 = u0:6735 sig1
           fn2 = u0:6736 sig2
           fn3 = u0:6737 sig3
           fn4 = u0:6738 sig4
           const0 = 0x00000000000000000000000000000000
           const1 = 0xbfff0000000000000000000000000000
           const2 = 0x40070000000000000000000000000000
       
                                       block0(v0: f128):
                                           v1 -> v0
                                           v8 -> v0
                                           v13 -> v0
                                           nop 
                                           jump block1
       
                                       block1:
                                           nop 
       @0000                               v2 = f128const const0
       @0000                               v3 = call fn0(v1, v2)  ; v2 = 0.0
       @0000                               v4 = f128const const1
       @0000                               v5 = call fn1(v3, v4)  ; v4 = -0x1.0000000000000000000000000000p0
       @0000                               v6 = iconst.i32 0
       @0000                               v7 = icmp sgt v5, v6  ; v6 = 0
       @0000                               brif v7, block2, block4
       
                                       block2:
       @0000                               nop 
       @0002                               v9 = f128const const2
       @0002                               v10 = call fn2(v8, v9)  ; v9 = 0x1.0000000000000000000000000000p8
       @0002                               v11 = iconst.i32 0
       @0002                               v12 = icmp slt v10, v11  ; v11 = 0
       @0002                               brif v12, block3, block5
       
                                       block3:
       @0002                               nop 
       @0003                               v14 = call fn3(v13)
       @0003                               v15 = iconst.i32 0
       @0003                               v16 = iconst.i32 255
       @0003                               v17 = iconst.i8 -1
       @0003                               v18 = icmp ugt v14, v17  ; v17 = -1
       @0003                               v19 = select v18, v16, v14  ; v16 = 255
       ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       ; error: inst22 (v19 = select.i32 v18, v16, v14  ; v16 = 255): arg 2 (v14) has type i8, expected i32
       
       @0003                               v20 = ireduce.i8 v19
       @0003                               v21 = call fn4(v13, v13)
       @0003                               v22 = iconst.i32 0
       @0003                               v23 = icmp eq v21, v22  ; v22 = 0
       @0003                               v24 = iconst.i8 0
       @0003                               v25 = select v23, v20, v24  ; v24 = 0
       @0004                               v26 = stack_addr.i64 ss0+1
       @0004                               store notrap v25, v26
       @0004                               v27 = iconst.i8 1
       @0004                               v28 = stack_addr.i64 ss0
       @0004                               store notrap v27, v28  ; v27 = 1
       @0006                               v29 = stack_addr.i64 ss0
       @0006                               v30 = load.i8 notrap v29
       @0006                               v31 = stack_addr.i64 ss0+1
       @0006                               v32 = load.i8 notrap v31
       @0006                               return v30, v32
       
                                       block4:
       @0006                               nop 
       @0007                               jump block5
       
                                       block5:
       @0007                               nop 
       @0008                               v33 = symbol_value.i64 gv0
       @0008                               v34 = load.i8 notrap v33
       @0008                               v35 = load.i8 notrap v33+1
       @0008                               v36 = stack_addr.i64 ss0
       @0008                               store notrap v34, v36
       @0008                               v37 = stack_addr.i64 ss0+1
       @0008                               store notrap v35, v37
       @0006                               v38 = stack_addr.i64 ss0
       @0006                               v39 = load.i8 notrap v38
       @0006                               v40 = stack_addr.i64 ss0+1
       @0006                               v41 = load.i8 notrap v40
       @0006                               return v39, v41
       
                                       block6:
       @0006                               nop 
       @000a                               v42 = stack_addr.i64 ss0
       @000a                               v43 = load.i8 notrap v42
       @000a                               v44 = stack_addr.i64 ss0+1
       @000a                               v45 = load.i8 notrap v44
       @000a                               return v43, v45
       }
       
       ; 1 verifier error detected (see above). Compilation aborted.
       

fn <f128 as std::convert::FloatToInt<u8>>::to_int_checked(_1: f128) -> std::option::Option<u8> {
    debug self => _1;
    let mut _0: std::option::Option<u8>;
    let mut _2: bool;
    let mut _3: f128;
    let mut _4: bool;
    let mut _5: u8;

    bb0: {
        StorageLive(_2);
        StorageLive(_3);
        _3 = Sub(copy _1, const 0f128);
        _2 = Gt(move _3, const -1f128);
        switchInt(move _2) -> [0: bb3, otherwise: bb1];
    }

    bb1: {
        StorageDead(_3);
        StorageLive(_4);
        _4 = Lt(copy _1, const 256f128);
        switchInt(move _4) -> [0: bb4, otherwise: bb2];
    }

    bb2: {
        StorageLive(_5);
        _5 = copy _1 as u8 (FloatToInt);
---
        return;
    }
}

alloc156042 (size: 2, align: 1) {
    00 __                                           │ .░
}

[RUSTC-TIMING] coretests test:true 90.314
error: could not compile `coretests` (test "coretests") due to 2 previous errors
env -u RUSTC_WRAPPER CARGO_ENCODED_RUSTDOCFLAGS="-Zannotate-moves\u{1f}-Zrandomize-layout\u{1f}-Zunstable-options\u{1f}--check-cfg=cfg(bootstrap)\u{1f}-Wrustdoc::invalid_codeblock_attributes\u{1f}--crate-version\u{1f}1.99.0-nightly\t(a56f74a57\t2026-08-12)" CARGO_ENCODED_RUSTFLAGS="-Zannotate-moves\u{1f}-Zrandomize-layout\u{1f}-Zunstable-options\u{1f}--check-cfg=cfg(bootstrap)\u{1f}-Zmacro-backtrace\u{1f}-Csplit-debuginfo=off\u{1f}-Clink-arg=-L/usr/lib/llvm-21/lib\u{1f}-Cllvm-args=-import-instr-limit=10\u{1f}-Clink-args=-Wl,-z,origin\u{1f}-Clink-args=-Wl,-rpath,$ORIGIN/../lib\u{1f}-Alinker-messages\u{1f}--cap-lints=allow\u{1f}--cfg\u{1f}randomized_layouts" RUSTC="/checkout/obj/build/aarch64-unknown-linux-gnu/stage2-codegen/cg_clif/dist/rustc-clif" RUSTDOC="/checkout/obj/build/aarch64-unknown-linux-gnu/stage2-codegen/cg_clif/dist/rustdoc-clif" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage0/bin/cargo" "test" "--manifest-path" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2-codegen/cg_clif/build/sysroot_tests/Cargo.toml" "--target-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2-codegen/cg_clif/build/sysroot_tests_target" "--locked" "--target" "aarch64-unknown-linux-gnu" "-p" "coretests" "-p" "alloctests" "--tests" "--" "-q" exited with status ExitStatus(unix_wait_status(25856))
Bootstrap failed while executing `--stage 2 test --skip tidy --skip intrinsic-test --skip src/tools/rust-analyzer --skip tests --skip library --skip tidyselftest`
Currently active steps:
test::CodegenCranelift { compilers: RustcPrivateCompilers { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target_compiler: Compiler { stage: 2, host: aarch64-unknown-linux-gnu, forced_compiler: false } }, target: aarch64-unknown-linux-gnu } at src/bootstrap/src/core/build_steps/test.rs:4321
Command `/checkout/obj/build/aarch64-unknown-linux-gnu/stage0/bin/cargo run --target aarch64-unknown-linux-gnu -Zbinary-dep-depinfo -j 4 -Zroot-dir=/checkout --locked --color=always --profile=release --manifest-path /checkout/compiler/rustc_codegen_cranelift/build_system/Cargo.toml -- test --download-dir /checkout/obj/build/cg_clif_download --out-dir /checkout/obj/build/aarch64-unknown-linux-gnu/stage2-codegen/cg_clif --no-unstable-features --use-backend cranelift --sysroot llvm --skip-test testsuite.extended_sysroot [workdir=/checkout/compiler/rustc_codegen_cranelift]` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/test.rs:4335:25
Executed at: src/bootstrap/src/core/build_steps/test.rs:4380:26

Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:21:35
  local time: Wed Aug 12 16:41:47 UTC 2026
  network time: Wed, 12 Aug 2026 16:41:47 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

@JohnTitor

Copy link
Copy Markdown
Member

Seems still failed, is it synced yet or any other issues happen?

@valentynkit

Copy link
Copy Markdown
Contributor Author

Seems still failed, is it synced yet or any other issues happen?

Not synced yet. The fix is rust-lang/rustc_codegen_cranelift@29b9205 and the last subtree sync was #159712.
So current CI failures, are still because of this bug, when it will be synced it should pass.
I re triggered the CI and expected it to be already synced, but it is not.

@JohnTitor

Copy link
Copy Markdown
Member

Alright, cc @bjorn3 for awareness
marking as blocked until it gets synced.

@JohnTitor JohnTitor added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-blocked Status: Blocked on something else such as an RFC or other implementation work. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants