Auto merge of #136974 - m-ou-se:fmt-options-64-bit, r=scottmcm
Reduce FormattingOptions to 64 bits This is part of https://github.com/rust-lang/rust/issues/99012 This reduces FormattingOptions from 6-7 machine words (384 bits on 64-bit platforms, 224 bits on 32-bit platforms) to just 64 bits (a single register on 64-bit platforms). Before: ```rust pub struct FormattingOptions { flags: u32, // only 6 bits used fill: char, align: Option<Alignment>, width: Option<usize>, precision: Option<usize>, } ``` After: ```rust pub struct FormattingOptions { /// Bits: /// - 0-20: fill character (21 bits, a full `char`) /// - 21: `+` flag /// - 22: `-` flag /// - 23: `#` flag /// - 24: `0` flag /// - 25: `x?` flag /// - 26: `X?` flag /// - 27: Width flag (if set, the width field below is used) /// - 28: Precision flag (if set, the precision field below is used) /// - 29-30: Alignment (0: Left, 1: Right, 2: Center, 3: Unknown) /// - 31: Always set to 1 flags: u32, /// Width if width flag above is set. Otherwise, always 0. width: u16, /// Precision if precision flag above is set. Otherwise, always 0. precision: u16, } ```
This commit is contained in:
commit
0ce1369bde
12 changed files with 363 additions and 321 deletions
|
@ -2150,11 +2150,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
self.expr_uint(sp, ast::UintTy::U16, value as u128)
|
self.expr_uint(sp, ast::UintTy::U16, value as u128)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn expr_char(&mut self, sp: Span, value: char) -> hir::Expr<'hir> {
|
|
||||||
let lit = self.arena.alloc(hir::Lit { span: sp, node: ast::LitKind::Char(value) });
|
|
||||||
self.expr(sp, hir::ExprKind::Lit(lit))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn expr_str(&mut self, sp: Span, value: Symbol) -> hir::Expr<'hir> {
|
pub(super) fn expr_str(&mut self, sp: Span, value: Symbol) -> hir::Expr<'hir> {
|
||||||
let lit = self
|
let lit = self
|
||||||
.arena
|
.arena
|
||||||
|
|
|
@ -361,24 +361,26 @@ fn make_format_spec<'hir>(
|
||||||
zero_pad,
|
zero_pad,
|
||||||
debug_hex,
|
debug_hex,
|
||||||
} = &placeholder.format_options;
|
} = &placeholder.format_options;
|
||||||
let fill = ctx.expr_char(sp, fill.unwrap_or(' '));
|
let fill = fill.unwrap_or(' ');
|
||||||
let align = ctx.expr_lang_item_type_relative(
|
// These need to match the constants in library/core/src/fmt/rt.rs.
|
||||||
sp,
|
let align = match alignment {
|
||||||
hir::LangItem::FormatAlignment,
|
Some(FormatAlignment::Left) => 0,
|
||||||
match alignment {
|
Some(FormatAlignment::Right) => 1,
|
||||||
Some(FormatAlignment::Left) => sym::Left,
|
Some(FormatAlignment::Center) => 2,
|
||||||
Some(FormatAlignment::Right) => sym::Right,
|
None => 3,
|
||||||
Some(FormatAlignment::Center) => sym::Center,
|
};
|
||||||
None => sym::Unknown,
|
// This needs to match the constants in library/core/src/fmt/rt.rs.
|
||||||
},
|
let flags: u32 = fill as u32
|
||||||
);
|
| ((sign == Some(FormatSign::Plus)) as u32) << 21
|
||||||
// This needs to match `Flag` in library/core/src/fmt/rt.rs.
|
| ((sign == Some(FormatSign::Minus)) as u32) << 22
|
||||||
let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32)
|
| (alternate as u32) << 23
|
||||||
| ((sign == Some(FormatSign::Minus)) as u32) << 1
|
| (zero_pad as u32) << 24
|
||||||
| (alternate as u32) << 2
|
| ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 25
|
||||||
| (zero_pad as u32) << 3
|
| ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 26
|
||||||
| ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4
|
| (width.is_some() as u32) << 27
|
||||||
| ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5;
|
| (precision.is_some() as u32) << 28
|
||||||
|
| align << 29
|
||||||
|
| 1 << 31; // Highest bit always set.
|
||||||
let flags = ctx.expr_u32(sp, flags);
|
let flags = ctx.expr_u32(sp, flags);
|
||||||
let precision = make_count(ctx, sp, precision, argmap);
|
let precision = make_count(ctx, sp, precision, argmap);
|
||||||
let width = make_count(ctx, sp, width, argmap);
|
let width = make_count(ctx, sp, width, argmap);
|
||||||
|
@ -387,7 +389,7 @@ fn make_format_spec<'hir>(
|
||||||
hir::LangItem::FormatPlaceholder,
|
hir::LangItem::FormatPlaceholder,
|
||||||
sym::new,
|
sym::new,
|
||||||
));
|
));
|
||||||
let args = ctx.arena.alloc_from_iter([position, fill, align, flags, precision, width]);
|
let args = ctx.arena.alloc_from_iter([position, flags, precision, width]);
|
||||||
ctx.expr_call_mut(sp, format_placeholder_new, args)
|
ctx.expr_call_mut(sp, format_placeholder_new, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -322,7 +322,6 @@ language_item_table! {
|
||||||
BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None;
|
BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None;
|
||||||
|
|
||||||
// Lang items needed for `format_args!()`.
|
// Lang items needed for `format_args!()`.
|
||||||
FormatAlignment, sym::format_alignment, format_alignment, Target::Enum, GenericRequirement::None;
|
|
||||||
FormatArgument, sym::format_argument, format_argument, Target::Struct, GenericRequirement::None;
|
FormatArgument, sym::format_argument, format_argument, Target::Struct, GenericRequirement::None;
|
||||||
FormatArguments, sym::format_arguments, format_arguments, Target::Struct, GenericRequirement::None;
|
FormatArguments, sym::format_arguments, format_arguments, Target::Struct, GenericRequirement::None;
|
||||||
FormatCount, sym::format_count, format_count, Target::Enum, GenericRequirement::None;
|
FormatCount, sym::format_count, format_count, Target::Enum, GenericRequirement::None;
|
||||||
|
|
|
@ -1003,7 +1003,6 @@ symbols! {
|
||||||
forbid,
|
forbid,
|
||||||
forget,
|
forget,
|
||||||
format,
|
format,
|
||||||
format_alignment,
|
|
||||||
format_args,
|
format_args,
|
||||||
format_args_capture,
|
format_args_capture,
|
||||||
format_args_macro,
|
format_args_macro,
|
||||||
|
|
|
@ -86,7 +86,7 @@ where
|
||||||
true => flt2dec::Sign::MinusPlus,
|
true => flt2dec::Sign::MinusPlus,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(precision) = fmt.options.precision {
|
if let Some(precision) = fmt.options.get_precision() {
|
||||||
float_to_decimal_common_exact(fmt, num, sign, precision)
|
float_to_decimal_common_exact(fmt, num, sign, precision)
|
||||||
} else {
|
} else {
|
||||||
let min_precision = 0;
|
let min_precision = 0;
|
||||||
|
@ -162,7 +162,7 @@ where
|
||||||
true => flt2dec::Sign::MinusPlus,
|
true => flt2dec::Sign::MinusPlus,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(precision) = fmt.options.precision {
|
if let Some(precision) = fmt.options.get_precision() {
|
||||||
// 1 integral digit + `precision` fractional digits = `precision + 1` total digits
|
// 1 integral digit + `precision` fractional digits = `precision + 1` total digits
|
||||||
float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper)
|
float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper)
|
||||||
} else {
|
} else {
|
||||||
|
@ -180,7 +180,7 @@ where
|
||||||
true => flt2dec::Sign::MinusPlus,
|
true => flt2dec::Sign::MinusPlus,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(precision) = fmt.options.precision {
|
if let Some(precision) = fmt.options.get_precision() {
|
||||||
// this behavior of {:.PREC?} predates exponential formatting for {:?}
|
// this behavior of {:.PREC?} predates exponential formatting for {:?}
|
||||||
float_to_decimal_common_exact(fmt, num, sign, precision)
|
float_to_decimal_common_exact(fmt, num, sign, precision)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -33,19 +33,6 @@ pub enum Alignment {
|
||||||
Center,
|
Center,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[unstable(feature = "fmt_internals", reason = "internal to standard library", issue = "none")]
|
|
||||||
impl From<rt::Alignment> for Option<Alignment> {
|
|
||||||
fn from(value: rt::Alignment) -> Self {
|
|
||||||
match value {
|
|
||||||
rt::Alignment::Left => Some(Alignment::Left),
|
|
||||||
rt::Alignment::Right => Some(Alignment::Right),
|
|
||||||
rt::Alignment::Center => Some(Alignment::Center),
|
|
||||||
rt::Alignment::Unknown => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "debug_builders", since = "1.2.0")]
|
#[stable(feature = "debug_builders", since = "1.2.0")]
|
||||||
pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
|
pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
|
||||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||||
|
@ -291,11 +278,52 @@ pub enum DebugAsHex {
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub struct FormattingOptions {
|
pub struct FormattingOptions {
|
||||||
|
/// Flags, with the following bit fields:
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// 31 30 29 28 27 26 25 24 23 22 21 20 0
|
||||||
|
/// ┌───┬───────┬───┬───┬───┬───┬───┬───┬───┬───┬──────────────────────────────────┐
|
||||||
|
/// │ 1 │ align │ p │ w │ X?│ x?│'0'│ # │ - │ + │ fill │
|
||||||
|
/// └───┴───────┴───┴───┴───┴───┴───┴───┴───┴───┴──────────────────────────────────┘
|
||||||
|
/// │ │ │ │ └─┬───────────────────┘ └─┬──────────────────────────────┘
|
||||||
|
/// │ │ │ │ │ └─ The fill character (21 bits char).
|
||||||
|
/// │ │ │ │ └─ The debug upper/lower hex, zero pad, alternate, and plus/minus flags.
|
||||||
|
/// │ │ │ └─ Whether a width is set. (The value is stored separately.)
|
||||||
|
/// │ │ └─ Whether a precision is set. (The value is stored separately.)
|
||||||
|
/// │ ├─ 0: Align left. (<)
|
||||||
|
/// │ ├─ 1: Align right. (>)
|
||||||
|
/// │ ├─ 2: Align center. (^)
|
||||||
|
/// │ └─ 3: Alignment not set. (default)
|
||||||
|
/// └─ Always set.
|
||||||
|
/// This makes it possible to distinguish formatting flags from
|
||||||
|
/// a &str size when stored in (the upper bits of) the same field.
|
||||||
|
/// (fmt::Arguments will make use of this property in the future.)
|
||||||
|
/// ```
|
||||||
|
// Note: This could use a special niche type with range 0x8000_0000..=0xfdd0ffff.
|
||||||
|
// It's unclear if that's useful, though.
|
||||||
flags: u32,
|
flags: u32,
|
||||||
fill: char,
|
/// Width if width flag (bit 27) above is set. Otherwise, always 0.
|
||||||
align: Option<Alignment>,
|
width: u16,
|
||||||
width: Option<u16>,
|
/// Precision if precision flag (bit 28) above is set. Otherwise, always 0.
|
||||||
precision: Option<u16>,
|
precision: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
// This needs to match with compiler/rustc_ast_lowering/src/format.rs.
|
||||||
|
mod flags {
|
||||||
|
pub(super) const SIGN_PLUS_FLAG: u32 = 1 << 21;
|
||||||
|
pub(super) const SIGN_MINUS_FLAG: u32 = 1 << 22;
|
||||||
|
pub(super) const ALTERNATE_FLAG: u32 = 1 << 23;
|
||||||
|
pub(super) const SIGN_AWARE_ZERO_PAD_FLAG: u32 = 1 << 24;
|
||||||
|
pub(super) const DEBUG_LOWER_HEX_FLAG: u32 = 1 << 25;
|
||||||
|
pub(super) const DEBUG_UPPER_HEX_FLAG: u32 = 1 << 26;
|
||||||
|
pub(super) const WIDTH_FLAG: u32 = 1 << 27;
|
||||||
|
pub(super) const PRECISION_FLAG: u32 = 1 << 28;
|
||||||
|
pub(super) const ALIGN_BITS: u32 = 0b11 << 29;
|
||||||
|
pub(super) const ALIGN_LEFT: u32 = 0 << 29;
|
||||||
|
pub(super) const ALIGN_RIGHT: u32 = 1 << 29;
|
||||||
|
pub(super) const ALIGN_CENTER: u32 = 2 << 29;
|
||||||
|
pub(super) const ALIGN_UNKNOWN: u32 = 3 << 29;
|
||||||
|
pub(super) const ALWAYS_SET: u32 = 1 << 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormattingOptions {
|
impl FormattingOptions {
|
||||||
|
@ -311,7 +339,11 @@ impl FormattingOptions {
|
||||||
/// - no [`DebugAsHex`] output mode.
|
/// - no [`DebugAsHex`] output mode.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self { flags: 0, fill: ' ', align: None, width: None, precision: None }
|
Self {
|
||||||
|
flags: ' ' as u32 | flags::ALIGN_UNKNOWN | flags::ALWAYS_SET,
|
||||||
|
width: 0,
|
||||||
|
precision: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets or removes the sign (the `+` or the `-` flag).
|
/// Sets or removes the sign (the `+` or the `-` flag).
|
||||||
|
@ -324,13 +356,12 @@ impl FormattingOptions {
|
||||||
/// - `-`: Currently not used
|
/// - `-`: Currently not used
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub fn sign(&mut self, sign: Option<Sign>) -> &mut Self {
|
pub fn sign(&mut self, sign: Option<Sign>) -> &mut Self {
|
||||||
self.flags =
|
let sign = match sign {
|
||||||
self.flags & !(1 << rt::Flag::SignMinus as u32 | 1 << rt::Flag::SignPlus as u32);
|
None => 0,
|
||||||
match sign {
|
Some(Sign::Plus) => flags::SIGN_PLUS_FLAG,
|
||||||
None => {}
|
Some(Sign::Minus) => flags::SIGN_MINUS_FLAG,
|
||||||
Some(Sign::Plus) => self.flags |= 1 << rt::Flag::SignPlus as u32,
|
};
|
||||||
Some(Sign::Minus) => self.flags |= 1 << rt::Flag::SignMinus as u32,
|
self.flags = self.flags & !(flags::SIGN_PLUS_FLAG | flags::SIGN_MINUS_FLAG) | sign;
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Sets or unsets the `0` flag.
|
/// Sets or unsets the `0` flag.
|
||||||
|
@ -339,9 +370,9 @@ impl FormattingOptions {
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub fn sign_aware_zero_pad(&mut self, sign_aware_zero_pad: bool) -> &mut Self {
|
pub fn sign_aware_zero_pad(&mut self, sign_aware_zero_pad: bool) -> &mut Self {
|
||||||
if sign_aware_zero_pad {
|
if sign_aware_zero_pad {
|
||||||
self.flags |= 1 << rt::Flag::SignAwareZeroPad as u32
|
self.flags |= flags::SIGN_AWARE_ZERO_PAD_FLAG;
|
||||||
} else {
|
} else {
|
||||||
self.flags &= !(1 << rt::Flag::SignAwareZeroPad as u32)
|
self.flags &= !flags::SIGN_AWARE_ZERO_PAD_FLAG;
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -356,9 +387,9 @@ impl FormattingOptions {
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub fn alternate(&mut self, alternate: bool) -> &mut Self {
|
pub fn alternate(&mut self, alternate: bool) -> &mut Self {
|
||||||
if alternate {
|
if alternate {
|
||||||
self.flags |= 1 << rt::Flag::Alternate as u32
|
self.flags |= flags::ALTERNATE_FLAG;
|
||||||
} else {
|
} else {
|
||||||
self.flags &= !(1 << rt::Flag::Alternate as u32)
|
self.flags &= !flags::ALTERNATE_FLAG;
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -370,7 +401,7 @@ impl FormattingOptions {
|
||||||
/// printed around it.
|
/// printed around it.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub fn fill(&mut self, fill: char) -> &mut Self {
|
pub fn fill(&mut self, fill: char) -> &mut Self {
|
||||||
self.fill = fill;
|
self.flags = self.flags & (u32::MAX << 21) | fill as u32;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Sets or removes the alignment.
|
/// Sets or removes the alignment.
|
||||||
|
@ -379,7 +410,13 @@ impl FormattingOptions {
|
||||||
/// positioned if it is smaller than the width of the formatter.
|
/// positioned if it is smaller than the width of the formatter.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub fn align(&mut self, align: Option<Alignment>) -> &mut Self {
|
pub fn align(&mut self, align: Option<Alignment>) -> &mut Self {
|
||||||
self.align = align;
|
let align: u32 = match align {
|
||||||
|
Some(Alignment::Left) => flags::ALIGN_LEFT,
|
||||||
|
Some(Alignment::Right) => flags::ALIGN_RIGHT,
|
||||||
|
Some(Alignment::Center) => flags::ALIGN_CENTER,
|
||||||
|
None => flags::ALIGN_UNKNOWN,
|
||||||
|
};
|
||||||
|
self.flags = self.flags & !flags::ALIGN_BITS | align;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Sets or removes the width.
|
/// Sets or removes the width.
|
||||||
|
@ -390,7 +427,13 @@ impl FormattingOptions {
|
||||||
/// will be used to take up the required space.
|
/// will be used to take up the required space.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub fn width(&mut self, width: Option<u16>) -> &mut Self {
|
pub fn width(&mut self, width: Option<u16>) -> &mut Self {
|
||||||
self.width = width;
|
if let Some(width) = width {
|
||||||
|
self.flags |= flags::WIDTH_FLAG;
|
||||||
|
self.width = width;
|
||||||
|
} else {
|
||||||
|
self.flags &= !flags::WIDTH_FLAG;
|
||||||
|
self.width = 0;
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Sets or removes the precision.
|
/// Sets or removes the precision.
|
||||||
|
@ -404,77 +447,85 @@ impl FormattingOptions {
|
||||||
/// decimal point should be printed.
|
/// decimal point should be printed.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub fn precision(&mut self, precision: Option<u16>) -> &mut Self {
|
pub fn precision(&mut self, precision: Option<u16>) -> &mut Self {
|
||||||
self.precision = precision;
|
if let Some(precision) = precision {
|
||||||
|
self.flags |= flags::PRECISION_FLAG;
|
||||||
|
self.precision = precision;
|
||||||
|
} else {
|
||||||
|
self.flags &= !flags::PRECISION_FLAG;
|
||||||
|
self.precision = 0;
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Specifies whether the [`Debug`] trait should use lower-/upper-case
|
/// Specifies whether the [`Debug`] trait should use lower-/upper-case
|
||||||
/// hexadecimal or normal integers
|
/// hexadecimal or normal integers
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub fn debug_as_hex(&mut self, debug_as_hex: Option<DebugAsHex>) -> &mut Self {
|
pub fn debug_as_hex(&mut self, debug_as_hex: Option<DebugAsHex>) -> &mut Self {
|
||||||
self.flags = self.flags
|
let debug_as_hex = match debug_as_hex {
|
||||||
& !(1 << rt::Flag::DebugUpperHex as u32 | 1 << rt::Flag::DebugLowerHex as u32);
|
None => 0,
|
||||||
match debug_as_hex {
|
Some(DebugAsHex::Lower) => flags::DEBUG_LOWER_HEX_FLAG,
|
||||||
None => {}
|
Some(DebugAsHex::Upper) => flags::DEBUG_UPPER_HEX_FLAG,
|
||||||
Some(DebugAsHex::Upper) => self.flags |= 1 << rt::Flag::DebugUpperHex as u32,
|
};
|
||||||
Some(DebugAsHex::Lower) => self.flags |= 1 << rt::Flag::DebugLowerHex as u32,
|
self.flags = self.flags & !(flags::DEBUG_LOWER_HEX_FLAG | flags::DEBUG_UPPER_HEX_FLAG)
|
||||||
}
|
| debug_as_hex;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the current sign (the `+` or the `-` flag).
|
/// Returns the current sign (the `+` or the `-` flag).
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub const fn get_sign(&self) -> Option<Sign> {
|
pub const fn get_sign(&self) -> Option<Sign> {
|
||||||
const SIGN_PLUS_BITFIELD: u32 = 1 << rt::Flag::SignPlus as u32;
|
if self.flags & flags::SIGN_PLUS_FLAG != 0 {
|
||||||
const SIGN_MINUS_BITFIELD: u32 = 1 << rt::Flag::SignMinus as u32;
|
Some(Sign::Plus)
|
||||||
match self.flags & ((1 << rt::Flag::SignPlus as u32) | (1 << rt::Flag::SignMinus as u32)) {
|
} else if self.flags & flags::SIGN_MINUS_FLAG != 0 {
|
||||||
SIGN_PLUS_BITFIELD => Some(Sign::Plus),
|
Some(Sign::Minus)
|
||||||
SIGN_MINUS_BITFIELD => Some(Sign::Minus),
|
} else {
|
||||||
0 => None,
|
None
|
||||||
_ => panic!("Invalid sign bits set in flags"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Returns the current `0` flag.
|
/// Returns the current `0` flag.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub const fn get_sign_aware_zero_pad(&self) -> bool {
|
pub const fn get_sign_aware_zero_pad(&self) -> bool {
|
||||||
self.flags & (1 << rt::Flag::SignAwareZeroPad as u32) != 0
|
self.flags & flags::SIGN_AWARE_ZERO_PAD_FLAG != 0
|
||||||
}
|
}
|
||||||
/// Returns the current `#` flag.
|
/// Returns the current `#` flag.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub const fn get_alternate(&self) -> bool {
|
pub const fn get_alternate(&self) -> bool {
|
||||||
self.flags & (1 << rt::Flag::Alternate as u32) != 0
|
self.flags & flags::ALTERNATE_FLAG != 0
|
||||||
}
|
}
|
||||||
/// Returns the current fill character.
|
/// Returns the current fill character.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub const fn get_fill(&self) -> char {
|
pub const fn get_fill(&self) -> char {
|
||||||
self.fill
|
// SAFETY: We only ever put a valid `char` in the lower 21 bits of the flags field.
|
||||||
|
unsafe { char::from_u32_unchecked(self.flags & 0x1FFFFF) }
|
||||||
}
|
}
|
||||||
/// Returns the current alignment.
|
/// Returns the current alignment.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub const fn get_align(&self) -> Option<Alignment> {
|
pub const fn get_align(&self) -> Option<Alignment> {
|
||||||
self.align
|
match self.flags & flags::ALIGN_BITS {
|
||||||
|
flags::ALIGN_LEFT => Some(Alignment::Left),
|
||||||
|
flags::ALIGN_RIGHT => Some(Alignment::Right),
|
||||||
|
flags::ALIGN_CENTER => Some(Alignment::Center),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// Returns the current width.
|
/// Returns the current width.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub const fn get_width(&self) -> Option<u16> {
|
pub const fn get_width(&self) -> Option<u16> {
|
||||||
self.width
|
if self.flags & flags::WIDTH_FLAG != 0 { Some(self.width) } else { None }
|
||||||
}
|
}
|
||||||
/// Returns the current precision.
|
/// Returns the current precision.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub const fn get_precision(&self) -> Option<u16> {
|
pub const fn get_precision(&self) -> Option<u16> {
|
||||||
self.precision
|
if self.flags & flags::PRECISION_FLAG != 0 { Some(self.precision) } else { None }
|
||||||
}
|
}
|
||||||
/// Returns the current precision.
|
/// Returns the current precision.
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
pub const fn get_debug_as_hex(&self) -> Option<DebugAsHex> {
|
pub const fn get_debug_as_hex(&self) -> Option<DebugAsHex> {
|
||||||
const DEBUG_UPPER_BITFIELD: u32 = 1 << rt::Flag::DebugUpperHex as u32;
|
if self.flags & flags::DEBUG_LOWER_HEX_FLAG != 0 {
|
||||||
const DEBUG_LOWER_BITFIELD: u32 = 1 << rt::Flag::DebugLowerHex as u32;
|
Some(DebugAsHex::Lower)
|
||||||
match self.flags
|
} else if self.flags & flags::DEBUG_UPPER_HEX_FLAG != 0 {
|
||||||
& ((1 << rt::Flag::DebugUpperHex as u32) | (1 << rt::Flag::DebugLowerHex as u32))
|
Some(DebugAsHex::Upper)
|
||||||
{
|
} else {
|
||||||
DEBUG_UPPER_BITFIELD => Some(DebugAsHex::Upper),
|
None
|
||||||
DEBUG_LOWER_BITFIELD => Some(DebugAsHex::Lower),
|
|
||||||
0 => None,
|
|
||||||
_ => panic!("Invalid hex debug bits set in flags"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,27 +536,6 @@ impl FormattingOptions {
|
||||||
pub fn create_formatter<'a>(self, write: &'a mut (dyn Write + 'a)) -> Formatter<'a> {
|
pub fn create_formatter<'a>(self, write: &'a mut (dyn Write + 'a)) -> Formatter<'a> {
|
||||||
Formatter { options: self, buf: write }
|
Formatter { options: self, buf: write }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[unstable(
|
|
||||||
feature = "fmt_internals",
|
|
||||||
reason = "internal routines only exposed for testing",
|
|
||||||
issue = "none"
|
|
||||||
)]
|
|
||||||
/// Flags for formatting
|
|
||||||
pub fn flags(&mut self, flags: u32) {
|
|
||||||
self.flags = flags
|
|
||||||
}
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[unstable(
|
|
||||||
feature = "fmt_internals",
|
|
||||||
reason = "internal routines only exposed for testing",
|
|
||||||
issue = "none"
|
|
||||||
)]
|
|
||||||
/// Flags for formatting
|
|
||||||
pub fn get_flags(&self) -> u32 {
|
|
||||||
self.flags
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "formatting_options", issue = "118117")]
|
#[unstable(feature = "formatting_options", issue = "118117")]
|
||||||
|
@ -1479,15 +1509,25 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argument<'_>]) -> Result {
|
unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argument<'_>]) -> Result {
|
||||||
fmt.options.fill = arg.fill;
|
let (width, precision) =
|
||||||
fmt.options.align = arg.align.into();
|
// SAFETY: arg and args come from the same Arguments,
|
||||||
fmt.options.flags = arg.flags;
|
// which guarantees the indexes are always within bounds.
|
||||||
// SAFETY: arg and args come from the same Arguments,
|
unsafe { (getcount(args, &arg.width), getcount(args, &arg.precision)) };
|
||||||
// which guarantees the indexes are always within bounds.
|
|
||||||
unsafe {
|
#[cfg(bootstrap)]
|
||||||
fmt.options.width = getcount(args, &arg.width);
|
let options =
|
||||||
fmt.options.precision = getcount(args, &arg.precision);
|
*FormattingOptions { flags: flags::ALWAYS_SET | arg.flags << 21, width: 0, precision: 0 }
|
||||||
}
|
.align(match arg.align {
|
||||||
|
rt::Alignment::Left => Some(Alignment::Left),
|
||||||
|
rt::Alignment::Right => Some(Alignment::Right),
|
||||||
|
rt::Alignment::Center => Some(Alignment::Center),
|
||||||
|
rt::Alignment::Unknown => None,
|
||||||
|
})
|
||||||
|
.fill(arg.fill)
|
||||||
|
.width(width)
|
||||||
|
.precision(precision);
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
let options = FormattingOptions { flags: arg.flags, width, precision };
|
||||||
|
|
||||||
// Extract the correct argument
|
// Extract the correct argument
|
||||||
debug_assert!(arg.position < args.len());
|
debug_assert!(arg.position < args.len());
|
||||||
|
@ -1495,17 +1535,18 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argume
|
||||||
// which guarantees its index is always within bounds.
|
// which guarantees its index is always within bounds.
|
||||||
let value = unsafe { args.get_unchecked(arg.position) };
|
let value = unsafe { args.get_unchecked(arg.position) };
|
||||||
|
|
||||||
|
// Set all the formatting options.
|
||||||
|
fmt.options = options;
|
||||||
|
|
||||||
// Then actually do some printing
|
// Then actually do some printing
|
||||||
// SAFETY: this is a placeholder argument.
|
// SAFETY: this is a placeholder argument.
|
||||||
unsafe { value.fmt(fmt) }
|
unsafe { value.fmt(fmt) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(bootstrap)]
|
||||||
unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option<u16> {
|
unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option<u16> {
|
||||||
match *cnt {
|
match *cnt {
|
||||||
#[cfg(bootstrap)]
|
|
||||||
rt::Count::Is(n) => Some(n as u16),
|
rt::Count::Is(n) => Some(n as u16),
|
||||||
#[cfg(not(bootstrap))]
|
|
||||||
rt::Count::Is(n) => Some(n),
|
|
||||||
rt::Count::Implied => None,
|
rt::Count::Implied => None,
|
||||||
rt::Count::Param(i) => {
|
rt::Count::Param(i) => {
|
||||||
debug_assert!(i < args.len());
|
debug_assert!(i < args.len());
|
||||||
|
@ -1516,6 +1557,20 @@ unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option<u16> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> u16 {
|
||||||
|
match *cnt {
|
||||||
|
rt::Count::Is(n) => n,
|
||||||
|
rt::Count::Implied => 0,
|
||||||
|
rt::Count::Param(i) => {
|
||||||
|
debug_assert!(i < args.len());
|
||||||
|
// SAFETY: cnt and args come from the same Arguments,
|
||||||
|
// which guarantees this index is always within bounds.
|
||||||
|
unsafe { args.get_unchecked(i).as_u16().unwrap_unchecked() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Padding after the end of something. Returned by `Formatter::padding`.
|
/// Padding after the end of something. Returned by `Formatter::padding`.
|
||||||
#[must_use = "don't forget to write the post padding"]
|
#[must_use = "don't forget to write the post padding"]
|
||||||
pub(crate) struct PostPadding {
|
pub(crate) struct PostPadding {
|
||||||
|
@ -1629,40 +1684,28 @@ impl<'a> Formatter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The `width` field is more of a `min-width` parameter at this point.
|
// The `width` field is more of a `min-width` parameter at this point.
|
||||||
match self.options.width {
|
let min = self.options.width;
|
||||||
// If there's no minimum length requirements then we can just
|
if width >= usize::from(min) {
|
||||||
// write the bytes.
|
// We're over the minimum width, so then we can just write the bytes.
|
||||||
None => {
|
write_prefix(self, sign, prefix)?;
|
||||||
write_prefix(self, sign, prefix)?;
|
self.buf.write_str(buf)
|
||||||
self.buf.write_str(buf)
|
} else if self.sign_aware_zero_pad() {
|
||||||
}
|
|
||||||
// Check if we're over the minimum width, if so then we can also
|
|
||||||
// just write the bytes.
|
|
||||||
Some(min) if width >= usize::from(min) => {
|
|
||||||
write_prefix(self, sign, prefix)?;
|
|
||||||
self.buf.write_str(buf)
|
|
||||||
}
|
|
||||||
// The sign and prefix goes before the padding if the fill character
|
// The sign and prefix goes before the padding if the fill character
|
||||||
// is zero
|
// is zero
|
||||||
Some(min) if self.sign_aware_zero_pad() => {
|
let old_options = self.options;
|
||||||
let old_fill = crate::mem::replace(&mut self.options.fill, '0');
|
self.options.fill('0').align(Some(Alignment::Right));
|
||||||
let old_align =
|
write_prefix(self, sign, prefix)?;
|
||||||
crate::mem::replace(&mut self.options.align, Some(Alignment::Right));
|
let post_padding = self.padding(min - width as u16, Alignment::Right)?;
|
||||||
write_prefix(self, sign, prefix)?;
|
self.buf.write_str(buf)?;
|
||||||
let post_padding = self.padding(min - width as u16, Alignment::Right)?;
|
post_padding.write(self)?;
|
||||||
self.buf.write_str(buf)?;
|
self.options = old_options;
|
||||||
post_padding.write(self)?;
|
Ok(())
|
||||||
self.options.fill = old_fill;
|
} else {
|
||||||
self.options.align = old_align;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
// Otherwise, the sign and prefix goes after the padding
|
// Otherwise, the sign and prefix goes after the padding
|
||||||
Some(min) => {
|
let post_padding = self.padding(min - width as u16, Alignment::Right)?;
|
||||||
let post_padding = self.padding(min - width as u16, Alignment::Right)?;
|
write_prefix(self, sign, prefix)?;
|
||||||
write_prefix(self, sign, prefix)?;
|
self.buf.write_str(buf)?;
|
||||||
self.buf.write_str(buf)?;
|
post_padding.write(self)
|
||||||
post_padding.write(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1698,13 +1741,13 @@ impl<'a> Formatter<'a> {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn pad(&mut self, s: &str) -> Result {
|
pub fn pad(&mut self, s: &str) -> Result {
|
||||||
// Make sure there's a fast path up front.
|
// Make sure there's a fast path up front.
|
||||||
if self.options.width.is_none() && self.options.precision.is_none() {
|
if self.options.flags & (flags::WIDTH_FLAG | flags::PRECISION_FLAG) == 0 {
|
||||||
return self.buf.write_str(s);
|
return self.buf.write_str(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The `precision` field can be interpreted as a maximum width for the
|
// The `precision` field can be interpreted as a maximum width for the
|
||||||
// string being formatted.
|
// string being formatted.
|
||||||
let (s, char_count) = if let Some(max_char_count) = self.options.precision {
|
let (s, char_count) = if let Some(max_char_count) = self.options.get_precision() {
|
||||||
let mut iter = s.char_indices();
|
let mut iter = s.char_indices();
|
||||||
let remaining = match iter.advance_by(usize::from(max_char_count)) {
|
let remaining = match iter.advance_by(usize::from(max_char_count)) {
|
||||||
Ok(()) => 0,
|
Ok(()) => 0,
|
||||||
|
@ -1720,12 +1763,11 @@ impl<'a> Formatter<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// The `width` field is more of a minimum width parameter at this point.
|
// The `width` field is more of a minimum width parameter at this point.
|
||||||
if let Some(width) = self.options.width
|
if char_count < usize::from(self.options.width) {
|
||||||
&& char_count < usize::from(width)
|
|
||||||
{
|
|
||||||
// If we're under the minimum width, then fill up the minimum width
|
// If we're under the minimum width, then fill up the minimum width
|
||||||
// with the specified string + some alignment.
|
// with the specified string + some alignment.
|
||||||
let post_padding = self.padding(width - char_count as u16, Alignment::Left)?;
|
let post_padding =
|
||||||
|
self.padding(self.options.width - char_count as u16, Alignment::Left)?;
|
||||||
self.buf.write_str(s)?;
|
self.buf.write_str(s)?;
|
||||||
post_padding.write(self)
|
post_padding.write(self)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1744,19 +1786,20 @@ impl<'a> Formatter<'a> {
|
||||||
padding: u16,
|
padding: u16,
|
||||||
default: Alignment,
|
default: Alignment,
|
||||||
) -> result::Result<PostPadding, Error> {
|
) -> result::Result<PostPadding, Error> {
|
||||||
let align = self.align().unwrap_or(default);
|
let align = self.options.get_align().unwrap_or(default);
|
||||||
|
let fill = self.options.get_fill();
|
||||||
|
|
||||||
let (pre_pad, post_pad) = match align {
|
let padding_left = match align {
|
||||||
Alignment::Left => (0, padding),
|
Alignment::Left => 0,
|
||||||
Alignment::Right => (padding, 0),
|
Alignment::Right => padding,
|
||||||
Alignment::Center => (padding / 2, (padding + 1) / 2),
|
Alignment::Center => padding / 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
for _ in 0..pre_pad {
|
for _ in 0..padding_left {
|
||||||
self.buf.write_char(self.options.fill)?;
|
self.buf.write_char(fill)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(PostPadding::new(self.options.fill, post_pad))
|
Ok(PostPadding::new(fill, padding - padding_left))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes the formatted parts and applies the padding.
|
/// Takes the formatted parts and applies the padding.
|
||||||
|
@ -1768,12 +1811,16 @@ impl<'a> Formatter<'a> {
|
||||||
///
|
///
|
||||||
/// Any `numfmt::Part::Copy` parts in `formatted` must contain valid UTF-8.
|
/// Any `numfmt::Part::Copy` parts in `formatted` must contain valid UTF-8.
|
||||||
unsafe fn pad_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
|
unsafe fn pad_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
|
||||||
if let Some(mut width) = self.options.width {
|
if self.options.width == 0 {
|
||||||
|
// this is the common case and we take a shortcut
|
||||||
|
// SAFETY: Per the precondition.
|
||||||
|
unsafe { self.write_formatted_parts(formatted) }
|
||||||
|
} else {
|
||||||
// for the sign-aware zero padding, we render the sign first and
|
// for the sign-aware zero padding, we render the sign first and
|
||||||
// behave as if we had no sign from the beginning.
|
// behave as if we had no sign from the beginning.
|
||||||
let mut formatted = formatted.clone();
|
let mut formatted = formatted.clone();
|
||||||
let old_fill = self.options.fill;
|
let mut width = self.options.width;
|
||||||
let old_align = self.options.align;
|
let old_options = self.options;
|
||||||
if self.sign_aware_zero_pad() {
|
if self.sign_aware_zero_pad() {
|
||||||
// a sign always goes first
|
// a sign always goes first
|
||||||
let sign = formatted.sign;
|
let sign = formatted.sign;
|
||||||
|
@ -1782,8 +1829,7 @@ impl<'a> Formatter<'a> {
|
||||||
// remove the sign from the formatted parts
|
// remove the sign from the formatted parts
|
||||||
formatted.sign = "";
|
formatted.sign = "";
|
||||||
width = width.saturating_sub(sign.len() as u16);
|
width = width.saturating_sub(sign.len() as u16);
|
||||||
self.options.fill = '0';
|
self.options.fill('0').align(Some(Alignment::Right));
|
||||||
self.options.align = Some(Alignment::Right);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// remaining parts go through the ordinary padding process.
|
// remaining parts go through the ordinary padding process.
|
||||||
|
@ -1800,13 +1846,8 @@ impl<'a> Formatter<'a> {
|
||||||
}
|
}
|
||||||
post_padding.write(self)
|
post_padding.write(self)
|
||||||
};
|
};
|
||||||
self.options.fill = old_fill;
|
self.options = old_options;
|
||||||
self.options.align = old_align;
|
|
||||||
ret
|
ret
|
||||||
} else {
|
|
||||||
// this is the common case and we take a shortcut
|
|
||||||
// SAFETY: Per the precondition.
|
|
||||||
unsafe { self.write_formatted_parts(formatted) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1927,7 +1968,9 @@ impl<'a> Formatter<'a> {
|
||||||
or `sign_aware_zero_pad` methods instead"
|
or `sign_aware_zero_pad` methods instead"
|
||||||
)]
|
)]
|
||||||
pub fn flags(&self) -> u32 {
|
pub fn flags(&self) -> u32 {
|
||||||
self.options.flags
|
// Extract the debug upper/lower hex, zero pad, alternate, and plus/minus flags
|
||||||
|
// to stay compatible with older versions of Rust.
|
||||||
|
self.options.flags >> 21 & 0x3F
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the character used as 'fill' whenever there is alignment.
|
/// Returns the character used as 'fill' whenever there is alignment.
|
||||||
|
@ -1960,7 +2003,7 @@ impl<'a> Formatter<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||||
pub fn fill(&self) -> char {
|
pub fn fill(&self) -> char {
|
||||||
self.options.fill
|
self.options.get_fill()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a flag indicating what form of alignment was requested.
|
/// Returns a flag indicating what form of alignment was requested.
|
||||||
|
@ -1995,7 +2038,7 @@ impl<'a> Formatter<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "fmt_flags_align", since = "1.28.0")]
|
#[stable(feature = "fmt_flags_align", since = "1.28.0")]
|
||||||
pub fn align(&self) -> Option<Alignment> {
|
pub fn align(&self) -> Option<Alignment> {
|
||||||
self.options.align
|
self.options.get_align()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the optionally specified integer width that the output should be.
|
/// Returns the optionally specified integer width that the output should be.
|
||||||
|
@ -2025,7 +2068,11 @@ impl<'a> Formatter<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||||
pub fn width(&self) -> Option<usize> {
|
pub fn width(&self) -> Option<usize> {
|
||||||
self.options.width.map(|x| x as usize)
|
if self.options.flags & flags::WIDTH_FLAG == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(self.options.width as usize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the optionally specified precision for numeric types.
|
/// Returns the optionally specified precision for numeric types.
|
||||||
|
@ -2056,7 +2103,11 @@ impl<'a> Formatter<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||||
pub fn precision(&self) -> Option<usize> {
|
pub fn precision(&self) -> Option<usize> {
|
||||||
self.options.precision.map(|x| x as usize)
|
if self.options.flags & flags::PRECISION_FLAG == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(self.options.precision as usize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines if the `+` flag was specified.
|
/// Determines if the `+` flag was specified.
|
||||||
|
@ -2088,7 +2139,7 @@ impl<'a> Formatter<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||||
pub fn sign_plus(&self) -> bool {
|
pub fn sign_plus(&self) -> bool {
|
||||||
self.options.flags & (1 << rt::Flag::SignPlus as u32) != 0
|
self.options.flags & flags::SIGN_PLUS_FLAG != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines if the `-` flag was specified.
|
/// Determines if the `-` flag was specified.
|
||||||
|
@ -2117,7 +2168,7 @@ impl<'a> Formatter<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||||
pub fn sign_minus(&self) -> bool {
|
pub fn sign_minus(&self) -> bool {
|
||||||
self.options.flags & (1 << rt::Flag::SignMinus as u32) != 0
|
self.options.flags & flags::SIGN_MINUS_FLAG != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines if the `#` flag was specified.
|
/// Determines if the `#` flag was specified.
|
||||||
|
@ -2145,7 +2196,7 @@ impl<'a> Formatter<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||||
pub fn alternate(&self) -> bool {
|
pub fn alternate(&self) -> bool {
|
||||||
self.options.flags & (1 << rt::Flag::Alternate as u32) != 0
|
self.options.flags & flags::ALTERNATE_FLAG != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines if the `0` flag was specified.
|
/// Determines if the `0` flag was specified.
|
||||||
|
@ -2171,17 +2222,16 @@ impl<'a> Formatter<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||||
pub fn sign_aware_zero_pad(&self) -> bool {
|
pub fn sign_aware_zero_pad(&self) -> bool {
|
||||||
self.options.flags & (1 << rt::Flag::SignAwareZeroPad as u32) != 0
|
self.options.flags & flags::SIGN_AWARE_ZERO_PAD_FLAG != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Decide what public API we want for these two flags.
|
// FIXME: Decide what public API we want for these two flags.
|
||||||
// https://github.com/rust-lang/rust/issues/48584
|
// https://github.com/rust-lang/rust/issues/48584
|
||||||
fn debug_lower_hex(&self) -> bool {
|
fn debug_lower_hex(&self) -> bool {
|
||||||
self.options.flags & (1 << rt::Flag::DebugLowerHex as u32) != 0
|
self.options.flags & flags::DEBUG_LOWER_HEX_FLAG != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_upper_hex(&self) -> bool {
|
fn debug_upper_hex(&self) -> bool {
|
||||||
self.options.flags & (1 << rt::Flag::DebugUpperHex as u32) != 0
|
self.options.flags & flags::DEBUG_UPPER_HEX_FLAG != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [`DebugStruct`] builder designed to assist with creation of
|
/// Creates a [`DebugStruct`] builder designed to assist with creation of
|
||||||
|
@ -2761,7 +2811,7 @@ impl Debug for char {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl Display for char {
|
impl Display for char {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||||
if f.options.width.is_none() && f.options.precision.is_none() {
|
if f.options.flags & (flags::WIDTH_FLAG | flags::PRECISION_FLAG) == 0 {
|
||||||
f.write_char(*self)
|
f.write_char(*self)
|
||||||
} else {
|
} else {
|
||||||
f.pad(self.encode_utf8(&mut [0; MAX_LEN_UTF8]))
|
f.pad(self.encode_utf8(&mut [0; MAX_LEN_UTF8]))
|
||||||
|
@ -2792,26 +2842,24 @@ impl<T: ?Sized> Pointer for *const T {
|
||||||
///
|
///
|
||||||
/// [problematic]: https://github.com/rust-lang/rust/issues/95489
|
/// [problematic]: https://github.com/rust-lang/rust/issues/95489
|
||||||
pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Result {
|
pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Result {
|
||||||
let old_width = f.options.width;
|
let old_options = f.options;
|
||||||
let old_flags = f.options.flags;
|
|
||||||
|
|
||||||
// The alternate flag is already treated by LowerHex as being special-
|
// The alternate flag is already treated by LowerHex as being special-
|
||||||
// it denotes whether to prefix with 0x. We use it to work out whether
|
// it denotes whether to prefix with 0x. We use it to work out whether
|
||||||
// or not to zero extend, and then unconditionally set it to get the
|
// or not to zero extend, and then unconditionally set it to get the
|
||||||
// prefix.
|
// prefix.
|
||||||
if f.alternate() {
|
if f.options.get_alternate() {
|
||||||
f.options.flags |= 1 << (rt::Flag::SignAwareZeroPad as u32);
|
f.options.sign_aware_zero_pad(true);
|
||||||
|
|
||||||
if f.options.width.is_none() {
|
if f.options.get_width().is_none() {
|
||||||
f.options.width = Some((usize::BITS / 4) as u16 + 2);
|
f.options.width(Some((usize::BITS / 4) as u16 + 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f.options.flags |= 1 << (rt::Flag::Alternate as u32);
|
f.options.alternate(true);
|
||||||
|
|
||||||
let ret = LowerHex::fmt(&ptr_addr, f);
|
let ret = LowerHex::fmt(&ptr_addr, f);
|
||||||
|
|
||||||
f.options.width = old_width;
|
f.options = old_options;
|
||||||
f.options.flags = old_flags;
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,9 @@ use crate::ptr::NonNull;
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Placeholder {
|
pub struct Placeholder {
|
||||||
pub position: usize,
|
pub position: usize,
|
||||||
|
#[cfg(bootstrap)]
|
||||||
pub fill: char,
|
pub fill: char,
|
||||||
|
#[cfg(bootstrap)]
|
||||||
pub align: Alignment,
|
pub align: Alignment,
|
||||||
pub flags: u32,
|
pub flags: u32,
|
||||||
pub precision: Count,
|
pub precision: Count,
|
||||||
|
@ -19,6 +21,7 @@ pub struct Placeholder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Placeholder {
|
impl Placeholder {
|
||||||
|
#[cfg(bootstrap)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new(
|
pub const fn new(
|
||||||
position: usize,
|
position: usize,
|
||||||
|
@ -30,8 +33,15 @@ impl Placeholder {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { position, fill, align, flags, precision, width }
|
Self { position, fill, align, flags, precision, width }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
#[inline]
|
||||||
|
pub const fn new(position: usize, flags: u32, precision: Count, width: Count) -> Self {
|
||||||
|
Self { position, flags, precision, width }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(bootstrap)]
|
||||||
#[lang = "format_alignment"]
|
#[lang = "format_alignment"]
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum Alignment {
|
pub enum Alignment {
|
||||||
|
@ -58,17 +68,6 @@ pub enum Count {
|
||||||
Implied,
|
Implied,
|
||||||
}
|
}
|
||||||
|
|
||||||
// This needs to match the order of flags in compiler/rustc_ast_lowering/src/format.rs.
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub(super) enum Flag {
|
|
||||||
SignPlus,
|
|
||||||
SignMinus,
|
|
||||||
Alternate,
|
|
||||||
SignAwareZeroPad,
|
|
||||||
DebugLowerHex,
|
|
||||||
DebugUpperHex,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
enum ArgumentType<'a> {
|
enum ArgumentType<'a> {
|
||||||
Placeholder {
|
Placeholder {
|
||||||
|
|
|
@ -81,6 +81,7 @@ fn formatting_options_ctor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[allow(deprecated)]
|
||||||
fn formatting_options_flags() {
|
fn formatting_options_flags() {
|
||||||
use core::fmt::*;
|
use core::fmt::*;
|
||||||
for sign in [None, Some(Sign::Plus), Some(Sign::Minus)] {
|
for sign in [None, Some(Sign::Plus), Some(Sign::Minus)] {
|
||||||
|
@ -98,6 +99,25 @@ fn formatting_options_flags() {
|
||||||
assert_eq!(formatting_options.get_alternate(), alternate);
|
assert_eq!(formatting_options.get_alternate(), alternate);
|
||||||
assert_eq!(formatting_options.get_sign_aware_zero_pad(), sign_aware_zero_pad);
|
assert_eq!(formatting_options.get_sign_aware_zero_pad(), sign_aware_zero_pad);
|
||||||
assert_eq!(formatting_options.get_debug_as_hex(), debug_as_hex);
|
assert_eq!(formatting_options.get_debug_as_hex(), debug_as_hex);
|
||||||
|
|
||||||
|
let mut output = String::new();
|
||||||
|
let fmt = Formatter::new(&mut output, formatting_options);
|
||||||
|
assert_eq!(fmt.options(), formatting_options);
|
||||||
|
|
||||||
|
assert_eq!(fmt.sign_minus(), sign == Some(Sign::Minus));
|
||||||
|
assert_eq!(fmt.sign_plus(), sign == Some(Sign::Plus));
|
||||||
|
assert_eq!(fmt.alternate(), alternate);
|
||||||
|
assert_eq!(fmt.sign_aware_zero_pad(), sign_aware_zero_pad);
|
||||||
|
|
||||||
|
// The flags method is deprecated.
|
||||||
|
// This checks compatibility with older versions of Rust.
|
||||||
|
assert_eq!(fmt.flags() & 1 != 0, sign == Some(Sign::Plus));
|
||||||
|
assert_eq!(fmt.flags() & 2 != 0, sign == Some(Sign::Minus));
|
||||||
|
assert_eq!(fmt.flags() & 4 != 0, alternate);
|
||||||
|
assert_eq!(fmt.flags() & 8 != 0, sign_aware_zero_pad);
|
||||||
|
assert_eq!(fmt.flags() & 16 != 0, debug_as_hex == Some(DebugAsHex::Lower));
|
||||||
|
assert_eq!(fmt.flags() & 32 != 0, debug_as_hex == Some(DebugAsHex::Upper));
|
||||||
|
assert_eq!(fmt.flags() & 0xFFFF_FFC0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,10 @@
|
||||||
debug precision => _8;
|
debug precision => _8;
|
||||||
let _8: usize;
|
let _8: usize;
|
||||||
scope 5 (inlined Formatter::<'_>::precision) {
|
scope 5 (inlined Formatter::<'_>::precision) {
|
||||||
let mut _22: std::option::Option<u16>;
|
let mut _22: u32;
|
||||||
scope 6 (inlined Option::<u16>::map::<usize, {closure@Formatter<'_>::precision::{closure#0}}>) {
|
let mut _23: u32;
|
||||||
let mut _23: isize;
|
let mut _24: usize;
|
||||||
let _24: u16;
|
let mut _25: u16;
|
||||||
let mut _25: usize;
|
|
||||||
scope 7 {
|
|
||||||
scope 8 (inlined Formatter::<'_>::precision::{closure#0}) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +47,7 @@
|
||||||
StorageLive(_20);
|
StorageLive(_20);
|
||||||
StorageLive(_21);
|
StorageLive(_21);
|
||||||
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
||||||
_20 = BitAnd(move _21, const 1_u32);
|
_20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG);
|
||||||
StorageDead(_21);
|
StorageDead(_21);
|
||||||
_4 = Ne(move _20, const 0_u32);
|
_4 = Ne(move _20, const 0_u32);
|
||||||
StorageDead(_20);
|
StorageDead(_20);
|
||||||
|
@ -75,12 +69,12 @@
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
StorageLive(_6);
|
StorageLive(_6);
|
||||||
StorageLive(_24);
|
|
||||||
StorageLive(_22);
|
StorageLive(_22);
|
||||||
_22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option<u16>);
|
|
||||||
StorageLive(_23);
|
StorageLive(_23);
|
||||||
_23 = discriminant(_22);
|
_23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
||||||
switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10];
|
_22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
|
||||||
|
StorageDead(_23);
|
||||||
|
switchInt(move _22) -> [0: bb10, otherwise: bb11];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb4: {
|
bb4: {
|
||||||
|
@ -148,30 +142,31 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bb9: {
|
bb9: {
|
||||||
StorageDead(_23);
|
|
||||||
StorageDead(_22);
|
|
||||||
StorageDead(_24);
|
|
||||||
_7 = discriminant(_6);
|
_7 = discriminant(_6);
|
||||||
switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10];
|
switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb10: {
|
bb10: {
|
||||||
unreachable;
|
StorageDead(_22);
|
||||||
}
|
|
||||||
|
|
||||||
bb11: {
|
|
||||||
_6 = const Option::<usize>::None;
|
_6 = const Option::<usize>::None;
|
||||||
goto -> bb9;
|
goto -> bb9;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb12: {
|
bb11: {
|
||||||
_24 = move ((_22 as Some).0: u16);
|
StorageDead(_22);
|
||||||
|
StorageLive(_24);
|
||||||
StorageLive(_25);
|
StorageLive(_25);
|
||||||
_25 = copy _24 as usize (IntToInt);
|
_25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16);
|
||||||
_6 = Option::<usize>::Some(move _25);
|
_24 = move _25 as usize (IntToInt);
|
||||||
StorageDead(_25);
|
StorageDead(_25);
|
||||||
|
_6 = Option::<usize>::Some(move _24);
|
||||||
|
StorageDead(_24);
|
||||||
goto -> bb9;
|
goto -> bb9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb12: {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOC0 (size: 8, align: 4) {
|
ALLOC0 (size: 8, align: 4) {
|
||||||
|
|
|
@ -29,16 +29,10 @@
|
||||||
debug precision => _8;
|
debug precision => _8;
|
||||||
let _8: usize;
|
let _8: usize;
|
||||||
scope 5 (inlined Formatter::<'_>::precision) {
|
scope 5 (inlined Formatter::<'_>::precision) {
|
||||||
let mut _22: std::option::Option<u16>;
|
let mut _22: u32;
|
||||||
scope 6 (inlined Option::<u16>::map::<usize, {closure@Formatter<'_>::precision::{closure#0}}>) {
|
let mut _23: u32;
|
||||||
let mut _23: isize;
|
let mut _24: usize;
|
||||||
let _24: u16;
|
let mut _25: u16;
|
||||||
let mut _25: usize;
|
|
||||||
scope 7 {
|
|
||||||
scope 8 (inlined Formatter::<'_>::precision::{closure#0}) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +47,7 @@
|
||||||
StorageLive(_20);
|
StorageLive(_20);
|
||||||
StorageLive(_21);
|
StorageLive(_21);
|
||||||
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
||||||
_20 = BitAnd(move _21, const 1_u32);
|
_20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG);
|
||||||
StorageDead(_21);
|
StorageDead(_21);
|
||||||
_4 = Ne(move _20, const 0_u32);
|
_4 = Ne(move _20, const 0_u32);
|
||||||
StorageDead(_20);
|
StorageDead(_20);
|
||||||
|
@ -75,12 +69,12 @@
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
StorageLive(_6);
|
StorageLive(_6);
|
||||||
StorageLive(_24);
|
|
||||||
StorageLive(_22);
|
StorageLive(_22);
|
||||||
_22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option<u16>);
|
|
||||||
StorageLive(_23);
|
StorageLive(_23);
|
||||||
_23 = discriminant(_22);
|
_23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
||||||
switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10];
|
_22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
|
||||||
|
StorageDead(_23);
|
||||||
|
switchInt(move _22) -> [0: bb10, otherwise: bb11];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb4: {
|
bb4: {
|
||||||
|
@ -148,30 +142,31 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bb9: {
|
bb9: {
|
||||||
StorageDead(_23);
|
|
||||||
StorageDead(_22);
|
|
||||||
StorageDead(_24);
|
|
||||||
_7 = discriminant(_6);
|
_7 = discriminant(_6);
|
||||||
switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10];
|
switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb10: {
|
bb10: {
|
||||||
unreachable;
|
StorageDead(_22);
|
||||||
}
|
|
||||||
|
|
||||||
bb11: {
|
|
||||||
_6 = const Option::<usize>::None;
|
_6 = const Option::<usize>::None;
|
||||||
goto -> bb9;
|
goto -> bb9;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb12: {
|
bb11: {
|
||||||
_24 = move ((_22 as Some).0: u16);
|
StorageDead(_22);
|
||||||
|
StorageLive(_24);
|
||||||
StorageLive(_25);
|
StorageLive(_25);
|
||||||
_25 = copy _24 as usize (IntToInt);
|
_25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16);
|
||||||
_6 = Option::<usize>::Some(move _25);
|
_24 = move _25 as usize (IntToInt);
|
||||||
StorageDead(_25);
|
StorageDead(_25);
|
||||||
|
_6 = Option::<usize>::Some(move _24);
|
||||||
|
StorageDead(_24);
|
||||||
goto -> bb9;
|
goto -> bb9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb12: {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOC0 (size: 8, align: 4) {
|
ALLOC0 (size: 8, align: 4) {
|
||||||
|
|
|
@ -29,16 +29,10 @@
|
||||||
debug precision => _8;
|
debug precision => _8;
|
||||||
let _8: usize;
|
let _8: usize;
|
||||||
scope 5 (inlined Formatter::<'_>::precision) {
|
scope 5 (inlined Formatter::<'_>::precision) {
|
||||||
let mut _22: std::option::Option<u16>;
|
let mut _22: u32;
|
||||||
scope 6 (inlined Option::<u16>::map::<usize, {closure@Formatter<'_>::precision::{closure#0}}>) {
|
let mut _23: u32;
|
||||||
let mut _23: isize;
|
let mut _24: usize;
|
||||||
let _24: u16;
|
let mut _25: u16;
|
||||||
let mut _25: usize;
|
|
||||||
scope 7 {
|
|
||||||
scope 8 (inlined Formatter::<'_>::precision::{closure#0}) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +47,7 @@
|
||||||
StorageLive(_20);
|
StorageLive(_20);
|
||||||
StorageLive(_21);
|
StorageLive(_21);
|
||||||
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
||||||
_20 = BitAnd(move _21, const 1_u32);
|
_20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG);
|
||||||
StorageDead(_21);
|
StorageDead(_21);
|
||||||
_4 = Ne(move _20, const 0_u32);
|
_4 = Ne(move _20, const 0_u32);
|
||||||
StorageDead(_20);
|
StorageDead(_20);
|
||||||
|
@ -75,12 +69,12 @@
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
StorageLive(_6);
|
StorageLive(_6);
|
||||||
StorageLive(_24);
|
|
||||||
StorageLive(_22);
|
StorageLive(_22);
|
||||||
_22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option<u16>);
|
|
||||||
StorageLive(_23);
|
StorageLive(_23);
|
||||||
_23 = discriminant(_22);
|
_23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
||||||
switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10];
|
_22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
|
||||||
|
StorageDead(_23);
|
||||||
|
switchInt(move _22) -> [0: bb10, otherwise: bb11];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb4: {
|
bb4: {
|
||||||
|
@ -148,30 +142,31 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bb9: {
|
bb9: {
|
||||||
StorageDead(_23);
|
|
||||||
StorageDead(_22);
|
|
||||||
StorageDead(_24);
|
|
||||||
_7 = discriminant(_6);
|
_7 = discriminant(_6);
|
||||||
switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10];
|
switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb10: {
|
bb10: {
|
||||||
unreachable;
|
StorageDead(_22);
|
||||||
}
|
|
||||||
|
|
||||||
bb11: {
|
|
||||||
_6 = const Option::<usize>::None;
|
_6 = const Option::<usize>::None;
|
||||||
goto -> bb9;
|
goto -> bb9;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb12: {
|
bb11: {
|
||||||
_24 = move ((_22 as Some).0: u16);
|
StorageDead(_22);
|
||||||
|
StorageLive(_24);
|
||||||
StorageLive(_25);
|
StorageLive(_25);
|
||||||
_25 = copy _24 as usize (IntToInt);
|
_25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16);
|
||||||
_6 = Option::<usize>::Some(move _25);
|
_24 = move _25 as usize (IntToInt);
|
||||||
StorageDead(_25);
|
StorageDead(_25);
|
||||||
|
_6 = Option::<usize>::Some(move _24);
|
||||||
|
StorageDead(_24);
|
||||||
goto -> bb9;
|
goto -> bb9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb12: {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOC0 (size: 16, align: 8) {
|
ALLOC0 (size: 16, align: 8) {
|
||||||
|
|
|
@ -29,16 +29,10 @@
|
||||||
debug precision => _8;
|
debug precision => _8;
|
||||||
let _8: usize;
|
let _8: usize;
|
||||||
scope 5 (inlined Formatter::<'_>::precision) {
|
scope 5 (inlined Formatter::<'_>::precision) {
|
||||||
let mut _22: std::option::Option<u16>;
|
let mut _22: u32;
|
||||||
scope 6 (inlined Option::<u16>::map::<usize, {closure@Formatter<'_>::precision::{closure#0}}>) {
|
let mut _23: u32;
|
||||||
let mut _23: isize;
|
let mut _24: usize;
|
||||||
let _24: u16;
|
let mut _25: u16;
|
||||||
let mut _25: usize;
|
|
||||||
scope 7 {
|
|
||||||
scope 8 (inlined Formatter::<'_>::precision::{closure#0}) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +47,7 @@
|
||||||
StorageLive(_20);
|
StorageLive(_20);
|
||||||
StorageLive(_21);
|
StorageLive(_21);
|
||||||
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
||||||
_20 = BitAnd(move _21, const 1_u32);
|
_20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG);
|
||||||
StorageDead(_21);
|
StorageDead(_21);
|
||||||
_4 = Ne(move _20, const 0_u32);
|
_4 = Ne(move _20, const 0_u32);
|
||||||
StorageDead(_20);
|
StorageDead(_20);
|
||||||
|
@ -75,12 +69,12 @@
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
StorageLive(_6);
|
StorageLive(_6);
|
||||||
StorageLive(_24);
|
|
||||||
StorageLive(_22);
|
StorageLive(_22);
|
||||||
_22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option<u16>);
|
|
||||||
StorageLive(_23);
|
StorageLive(_23);
|
||||||
_23 = discriminant(_22);
|
_23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
|
||||||
switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10];
|
_22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
|
||||||
|
StorageDead(_23);
|
||||||
|
switchInt(move _22) -> [0: bb10, otherwise: bb11];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb4: {
|
bb4: {
|
||||||
|
@ -148,30 +142,31 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bb9: {
|
bb9: {
|
||||||
StorageDead(_23);
|
|
||||||
StorageDead(_22);
|
|
||||||
StorageDead(_24);
|
|
||||||
_7 = discriminant(_6);
|
_7 = discriminant(_6);
|
||||||
switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10];
|
switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb10: {
|
bb10: {
|
||||||
unreachable;
|
StorageDead(_22);
|
||||||
}
|
|
||||||
|
|
||||||
bb11: {
|
|
||||||
_6 = const Option::<usize>::None;
|
_6 = const Option::<usize>::None;
|
||||||
goto -> bb9;
|
goto -> bb9;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb12: {
|
bb11: {
|
||||||
_24 = move ((_22 as Some).0: u16);
|
StorageDead(_22);
|
||||||
|
StorageLive(_24);
|
||||||
StorageLive(_25);
|
StorageLive(_25);
|
||||||
_25 = copy _24 as usize (IntToInt);
|
_25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16);
|
||||||
_6 = Option::<usize>::Some(move _25);
|
_24 = move _25 as usize (IntToInt);
|
||||||
StorageDead(_25);
|
StorageDead(_25);
|
||||||
|
_6 = Option::<usize>::Some(move _24);
|
||||||
|
StorageDead(_24);
|
||||||
goto -> bb9;
|
goto -> bb9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb12: {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOC0 (size: 16, align: 8) {
|
ALLOC0 (size: 16, align: 8) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue