Skip to content

float: Fix panic at max exponential precision#154052

Merged
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
cdown:cdown/2026-03-19/precision
Apr 5, 2026
Merged

float: Fix panic at max exponential precision#154052
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
cdown:cdown/2026-03-19/precision

Conversation

@cdown
Copy link
Copy Markdown
Contributor

@cdown cdown commented Mar 18, 2026

Rust's formatting machinery allows precision values of up to u16::MAX. Exponential formatting works out the number of significant digits to use by adding one (for the integral digit before the decimal point).

This previously used usize precision, so the maximum validated precision did not overflow, but in commit fb9ce02 ("Limit formatting width and precision to 16 bits.") the precision type was narrowed to u16 without widening that addition first.

As a result an exponential precision value of 65535 is no longer handled correctly, because the digit count wraps to 0, and thus "{:.65535e}" panics in flt2dec::to_exact_exp_str with "assertion failed: ndigits > 0". Other formats (and the parser) accept values up to u16::MAX.

A naive fix would be to widen that addition back to usize, but that still does not properly address 16-bit targets, where usize is only guaranteed to be able to represent values up to u16::MAX. The real issue is that this internal API is expressed in the wrong units for the formatter.

Fix this by changing exact exponential formatting to take fractional digits internally as well, and compute the temporary significant digit bound only when sizing the scratch buffer. To support that let's also make formatted length accounting saturate so that extremely large rendered outputs do not reintroduce overflows in padding logic.

This preserves the existing intent and keeps FormattingOptions compact while making formatting work consistently again.

@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 Mar 18, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 18, 2026

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @scottmcm, libs
  • @scottmcm, libs expanded to 8 candidates
  • Random selection from Mark-Simulacrum, scottmcm

@cdown cdown force-pushed the cdown/2026-03-19/precision branch 2 times, most recently from 71fe342 to d57cfdf Compare March 19, 2026 03:32
@cdown cdown force-pushed the cdown/2026-03-19/precision branch from d57cfdf to 77f6ba6 Compare March 20, 2026 06:23
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 20, 2026

Some changes occurred in float parsing

cc @tgross35

@cdown cdown requested a review from hkBst March 20, 2026 06:23
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 23, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 23, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Mar 23, 2026
Rust's formatting machinery allows precision values of up to u16::MAX.
Exponential formatting works out the number of significant digits to use
by adding one (for the integral digit before the decimal point).

This previously used usize precision, so the maximum validated precision
did not overflow, but in commit fb9ce02 ("Limit formatting width
and precision to 16 bits.") the precision type was narrowed to u16
without widening that addition first.

As a result an exponential precision value of 65535 is no longer handled
correctly, because the digit count wraps to 0, and thus "{:.65535e}"
panics in flt2dec::to_exact_exp_str with "assertion failed: ndigits >
0". Other formats (and the parser) accept values up to u16::MAX.

A naive fix would be to widen that addition back to usize, but that
still does not properly address 16-bit targets, where usize is only
guaranteed to be able to represent values up to u16::MAX. The real issue
is that this internal API is expressed in the wrong units for the
formatter.

Fix this by changing exact exponential formatting to take fractional
digits internally as well, and compute the temporary significant digit
bound only when sizing the scratch buffer. To support that let's also
make formatted length accounting saturate so that extremely large
rendered outputs do not reintroduce overflows in padding logic.

This preserves the existing intent and keeps FormattingOptions compact
while making formatting work consistently again.
@cdown cdown force-pushed the cdown/2026-03-19/precision branch from 77f6ba6 to 2ae6c61 Compare April 4, 2026 12:46
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 4, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@cdown
Copy link
Copy Markdown
Contributor Author

cdown commented Apr 4, 2026

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 4, 2026
@Mark-Simulacrum
Copy link
Copy Markdown
Member

@bors r+

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Apr 4, 2026

📌 Commit 2ae6c61 has been approved by Mark-Simulacrum

It is now in the queue for this repository.

@rust-bors rust-bors bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 4, 2026
rust-bors bot pushed a commit that referenced this pull request Apr 4, 2026
…uwer

Rollup of 6 pull requests

Successful merges:

 - #147552 ([Debugger Visualizers] Optimize lookup behavior)
 - #154052 (float: Fix panic at max exponential precision)
 - #154706 (fix compilation of time/hermit.rs)
 - #154707 (Make `substr_range` and `subslice_range` return the new `Range` type)
 - #154767 (triagebot: roll library reviewers for `{coretests,alloctests}`)
 - #154797 (bootstrap: Include shorthand aliases in x completions)
@rust-bors rust-bors bot merged commit f523f84 into rust-lang:main Apr 5, 2026
11 checks passed
@rustbot rustbot added this to the 1.96.0 milestone Apr 5, 2026
rust-timer added a commit that referenced this pull request Apr 5, 2026
Rollup merge of #154052 - cdown:cdown/2026-03-19/precision, r=Mark-Simulacrum

float: Fix panic at max exponential precision

Rust's formatting machinery allows precision values of up to u16::MAX. Exponential formatting works out the number of significant digits to use by adding one (for the integral digit before the decimal point).

This previously used usize precision, so the maximum validated precision did not overflow, but in commit fb9ce02 ("Limit formatting width and precision to 16 bits.") the precision type was narrowed to u16 without widening that addition first.

As a result an exponential precision value of 65535 is no longer handled correctly, because the digit count wraps to 0, and thus "{:.65535e}" panics in flt2dec::to_exact_exp_str with "assertion failed: ndigits > 0". Other formats (and the parser) accept values up to u16::MAX.

A naive fix would be to widen that addition back to usize, but that still does not properly address 16-bit targets, where usize is only guaranteed to be able to represent values up to u16::MAX. The real issue is that this internal API is expressed in the wrong units for the formatter.

Fix this by changing exact exponential formatting to take fractional digits internally as well, and compute the temporary significant digit bound only when sizing the scratch buffer. To support that let's also make formatted length accounting saturate so that extremely large rendered outputs do not reintroduce overflows in padding logic.

This preserves the existing intent and keeps FormattingOptions compact while making formatting work consistently again.
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Apr 5, 2026
…uwer

Rollup of 6 pull requests

Successful merges:

 - rust-lang/rust#147552 ([Debugger Visualizers] Optimize lookup behavior)
 - rust-lang/rust#154052 (float: Fix panic at max exponential precision)
 - rust-lang/rust#154706 (fix compilation of time/hermit.rs)
 - rust-lang/rust#154707 (Make `substr_range` and `subslice_range` return the new `Range` type)
 - rust-lang/rust#154767 (triagebot: roll library reviewers for `{coretests,alloctests}`)
 - rust-lang/rust#154797 (bootstrap: Include shorthand aliases in x completions)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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