Skip to content

float: Fix panic at max exponential precision - #154052

Merged
rust-bors[bot] merged 1 commit into
rust-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 into
rust-lang:mainfrom
cdown:cdown/2026-03-19/precision

Conversation

@cdown

@cdowncdown commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

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.

@rustbotrustbot 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

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
cdownforce-pushed the cdown/2026-03-19/precision branch 2 times, most recently from 71fe342 to d57cfdfCompareMarch 19, 2026 03:32
Comment threadlibrary/core/src/fmt/float.rs Outdated
@cdown
cdownforce-pushed the cdown/2026-03-19/precision branch from d57cfdf to 77f6ba6CompareMarch 20, 2026 06:23
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in float parsing

cc @tgross35

@cdown
cdown requested a review from hkBstMarch 20, 2026 06:23
Comment threadlibrary/core/src/num/imp/fmt.rs
Comment threadlibrary/core/src/num/imp/flt2dec/mod.rs
Comment threadlibrary/core/src/num/imp/fmt.rs
@rustbotrustbot 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

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

@rustbotrustbot 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
cdownforce-pushed the cdown/2026-03-19/precision branch from 77f6ba6 to 2ae6c61CompareApril 4, 2026 12:46
@rustbot

Copy link
Copy Markdown
Collaborator

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

cdown commented Apr 4, 2026

Copy link
Copy Markdown
ContributorAuthor

@rustbot ready

@rustbotrustbot 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

rust-borsBot commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 2ae6c61 has been approved by Mark-Simulacrum

It is now in the queue for this repository.

@rust-borsrust-borsBot 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-borsBot 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-borsBot merged commit f523f84 into rust-lang:mainApr 5, 2026
11 checks passed
@rustbotrustbot 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-actionsBot 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 freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

@cdown@rustbot@Mark-Simulacrum@hkBst