Skip to content

Conversation

@tautschnig
Copy link
Member

Since Rust 1.45, the as keyword performs a saturating cast when casting from float to int. See Rust Reference: Numeric cast.

Co-authored-by: Kani autonomous agent

Resolves #4536

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

Since Rust 1.45, the `as` keyword performs a *saturating cast* when
casting from float to int. See [Rust Reference: Numeric
cast](https://doc.rust-lang.org/reference/expressions/operator-expr.html#numeric-cast).

Co-authored-by: Kani autonomous agent

Resolves model-checking#4536
Copilot AI review requested due to automatic review settings February 11, 2026 14:13
@tautschnig tautschnig requested a review from a team as a code owner February 11, 2026 14:13
@github-actions github-actions bot added Z-EndToEndBenchCI Tag a PR to run benchmark CI Z-CompilerBenchCI Tag a PR to run benchmark CI labels Feb 11, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes a bug where Kani was incorrectly implementing float-to-int casts. Since Rust 1.45, the as keyword performs saturating casts when converting from floating-point to integer types, but Kani was using wrapping (modulo) semantics instead. For example, 300.0f32 as u8 should produce 255 (saturating to u8::MAX), but Kani was incorrectly producing 44 (300 % 256).

Changes:

  • Implemented saturating cast semantics for float-to-int conversions with proper handling of NaN, infinity, and out-of-bounds values
  • Added comprehensive regression tests covering various edge cases of float-to-int saturating casts
  • Extended expression bindings with IsNan and IsInf unary operators for CBMC integration

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
tests/kani/Cast/float_to_int_saturating.rs Regression tests for float-to-int saturating cast covering NaN, infinity, out-of-bounds, and in-range cases for f32 and f64
kani-compiler/src/codegen_cprover_gotoc/codegen/rvalue.rs Core implementation of saturating cast logic with special handling for NaN (→0), infinity and out-of-bounds values (→MIN/MAX), and in-range truncation
cprover_bindings/src/goto_program/expr.rs Added IsNan and IsInf unary operators and corresponding helper methods for float type checking
cprover_bindings/src/irep/to_irep.rs Added IREP ID mappings for IsNan and IsInf operators to interface with CBMC

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Z-CompilerBenchCI Tag a PR to run benchmark CI Z-EndToEndBenchCI Tag a PR to run benchmark CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

float to int saturating cast

1 participant