Skip to content

Commit e5221f9

Browse files
authored
Rollup merge of rust-lang#40241 - Sawyer47:fix-39997, r=alexcrichton
Change how the `0` flag works in format! Now it always implies right-alignment, so that padding zeroes are placed after the sign (if any) and before the digits. In other words, it always takes precedence over explicitly specified `[[fill]align]`. This also affects the '#' flag: zeroes are placed after the prefix (0b, 0o, 0x) and before the digits. Here's a short summary of how similar format strings work in Python and Rust: ``` :05 :<05 :>05 :^05 Python 3.6 |-0001| |-1000| |000-1| |0-100| Rust before |-0001| |-1000| |-0001| |-0100| Rust after |-0001| |-0001| |-0001| |-0001| :#05x :<#05x :>#05x :^#05x Python 3.6 |0x001| |0x100| |000x1| |00x10| Rust before |0x001| |0x100| |000x1| |0x010| Rust after |0x001| |0x001| |0x001| |0x001| ``` Fixes rust-lang#39997 [breaking-change]
2 parents 6eb9960 + 8065486 commit e5221f9

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

src/libcollections/fmt.rs

+4
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@
367367
//! like `{:08}` would yield `00000001` for the integer `1`, while the
368368
//! same format would yield `-0000001` for the integer `-1`. Notice that
369369
//! the negative version has one fewer zero than the positive version.
370+
//! Note that padding zeroes are always placed after the sign (if any)
371+
//! and before the digits. When used together with the `#` flag, a similar
372+
//! rule applies: padding zeroes are inserted after the prefix but before
373+
//! the digits.
370374
//!
371375
//! ## Width
372376
//!

src/libcore/fmt/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,7 @@ impl<'a> Formatter<'a> {
10451045
// is zero
10461046
Some(min) if self.sign_aware_zero_pad() => {
10471047
self.fill = '0';
1048+
self.align = rt::v1::Alignment::Right;
10481049
write_prefix(self)?;
10491050
self.with_padding(min - width, rt::v1::Alignment::Right, |f| {
10501051
f.buf.write_str(buf)
@@ -1153,8 +1154,9 @@ impl<'a> Formatter<'a> {
11531154
// for the sign-aware zero padding, we render the sign first and
11541155
// behave as if we had no sign from the beginning.
11551156
let mut formatted = formatted.clone();
1156-
let mut align = self.align;
11571157
let old_fill = self.fill;
1158+
let old_align = self.align;
1159+
let mut align = old_align;
11581160
if self.sign_aware_zero_pad() {
11591161
// a sign always goes first
11601162
let sign = unsafe { str::from_utf8_unchecked(formatted.sign) };
@@ -1165,6 +1167,7 @@ impl<'a> Formatter<'a> {
11651167
width = if width < sign.len() { 0 } else { width - sign.len() };
11661168
align = rt::v1::Alignment::Right;
11671169
self.fill = '0';
1170+
self.align = rt::v1::Alignment::Right;
11681171
}
11691172

11701173
// remaining parts go through the ordinary padding process.
@@ -1177,6 +1180,7 @@ impl<'a> Formatter<'a> {
11771180
})
11781181
};
11791182
self.fill = old_fill;
1183+
self.align = old_align;
11801184
ret
11811185
} else {
11821186
// this is the common case and we take a shortcut

src/test/run-pass/ifmt.rs

+28
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,34 @@ pub fn main() {
160160
t!(format!("{:?}", -0.0), "-0");
161161
t!(format!("{:?}", 0.0), "0");
162162

163+
// sign aware zero padding
164+
t!(format!("{:<3}", 1), "1 ");
165+
t!(format!("{:>3}", 1), " 1");
166+
t!(format!("{:^3}", 1), " 1 ");
167+
t!(format!("{:03}", 1), "001");
168+
t!(format!("{:<03}", 1), "001");
169+
t!(format!("{:>03}", 1), "001");
170+
t!(format!("{:^03}", 1), "001");
171+
t!(format!("{:+03}", 1), "+01");
172+
t!(format!("{:<+03}", 1), "+01");
173+
t!(format!("{:>+03}", 1), "+01");
174+
t!(format!("{:^+03}", 1), "+01");
175+
t!(format!("{:#05x}", 1), "0x001");
176+
t!(format!("{:<#05x}", 1), "0x001");
177+
t!(format!("{:>#05x}", 1), "0x001");
178+
t!(format!("{:^#05x}", 1), "0x001");
179+
t!(format!("{:05}", 1.2), "001.2");
180+
t!(format!("{:<05}", 1.2), "001.2");
181+
t!(format!("{:>05}", 1.2), "001.2");
182+
t!(format!("{:^05}", 1.2), "001.2");
183+
t!(format!("{:05}", -1.2), "-01.2");
184+
t!(format!("{:<05}", -1.2), "-01.2");
185+
t!(format!("{:>05}", -1.2), "-01.2");
186+
t!(format!("{:^05}", -1.2), "-01.2");
187+
t!(format!("{:+05}", 1.2), "+01.2");
188+
t!(format!("{:<+05}", 1.2), "+01.2");
189+
t!(format!("{:>+05}", 1.2), "+01.2");
190+
t!(format!("{:^+05}", 1.2), "+01.2");
163191

164192
// Ergonomic format_args!
165193
t!(format!("{0:x} {0:X}", 15), "f F");

0 commit comments

Comments
 (0)