diff options
| author | bors <bors@rust-lang.org> | 2025-03-11 04:07:05 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-03-11 04:07:05 +0000 |
| commit | 374ce1f90951b4dd1c8789c6a5905abe8ea99ef8 (patch) | |
| tree | 62588e7fd01070948f6a9f190f9cbb43b4d873e5 /compiler/rustc_codegen_llvm/src | |
| parent | 90384941aae4ea38de00e4702b50757e9b882a19 (diff) | |
| parent | 2ce0205735afce776f402eb96f85759906959473 (diff) | |
| download | rust-374ce1f90951b4dd1c8789c6a5905abe8ea99ef8.tar.gz rust-374ce1f90951b4dd1c8789c6a5905abe8ea99ef8.zip | |
Auto merge of #136932 - m-ou-se:fmt-width-precision-u16, r=scottmcm
Reduce formatting `width` and `precision` to 16 bits
This is part of https://github.com/rust-lang/rust/issues/99012
This is reduces the `width` and `precision` fields in format strings to 16 bits. They are currently full `usize`s, but it's a bit nonsensical that we need to support the case where someone wants to pad their value to eighteen quintillion spaces and/or have eighteen quintillion digits of precision.
By reducing these fields to 16 bit, we can reduce `FormattingOptions` to 64 bits (see https://github.com/rust-lang/rust/pull/136974) and improve the in memory representation of `format_args!()`. (See additional context below.)
This also fixes a bug where the width or precision is silently truncated when cross-compiling to a target with a smaller `usize`. By reducing the width and precision fields to the minimum guaranteed size of `usize`, 16 bits, this bug is eliminated.
This is a breaking change, but affects almost no existing code.
---
Details of this change:
There are three ways to set a width or precision today:
1. Directly a formatting string, e.g. `println!("{a:1234}")`
2. Indirectly in a formatting string, e.g. `println!("{a:width$}", width=1234)`
3. Through the unstable `FormattingOptions::width` method.
This PR:
- Adds a compiler error for 1. (`println!("{a:9999999}")` no longer compiles and gives a clear error.)
- Adds a runtime check for 2. (`println!("{a:width$}, width=9999999)` will panic.)
- Changes the signatures of the (unstable) `FormattingOptions::[get_]width` methods to use a `u16` instead.
---
Additional context for improving `FormattingOptions` and `fmt::Arguments`:
All the formatting flags and options are currently:
- The `+` flag (1 bit)
- The `-` flag (1 bit)
- The `#` flag (1 bit)
- The `0` flag (1 bit)
- The `x?` flag (1 bit)
- The `X?` flag (1 bit)
- The alignment (2 bits)
- The fill character (21 bits)
- Whether a width is specified (1 bit)
- Whether a precision is specified (1 bit)
- If used, the width (a full usize)
- If used, the precision (a full usize)
Everything except the last two can simply fit in a `u32` (those add up to 31 bits in total).
If we can accept a max width and precision of u16::MAX, we can make a `FormattingOptions` that is exactly 64 bits in size; the same size as a thin reference on most platforms.
If, additionally, we also limit the number of formatting arguments, we can also reduce the size of `fmt::Arguments` (that is, of a `format_args!()` expression).
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
0 files changed, 0 insertions, 0 deletions
