Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 37 additions & 21 deletions compiler/rustc_ast_lowering/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
enum ArgumentType {
Format(FormatTrait),
Format { how: FormatTrait, simple: bool },
Usize,
}

Expand All @@ -241,18 +241,32 @@ fn make_argument<'hir>(
sp,
hir::LangItem::FormatArgument,
match ty {
Format(Display) => sym::new_display,
Format(Debug) => match ctx.tcx.sess.opts.unstable_opts.fmt_debug {
FmtDebug::Full | FmtDebug::Shallow => sym::new_debug,
Format { how: Display, simple: false } => sym::new_display,
Format { how: Display, simple: true } => sym::new_display_simple,
Format { how: Debug, simple } => match ctx.tcx.sess.opts.unstable_opts.fmt_debug {
FmtDebug::Full | FmtDebug::Shallow => {
if simple {
sym::new_debug_simple
} else {
sym::new_debug
}
}
FmtDebug::None => sym::new_debug_noop,
},
Format(LowerExp) => sym::new_lower_exp,
Format(UpperExp) => sym::new_upper_exp,
Format(Octal) => sym::new_octal,
Format(Pointer) => sym::new_pointer,
Format(Binary) => sym::new_binary,
Format(LowerHex) => sym::new_lower_hex,
Format(UpperHex) => sym::new_upper_hex,
Format { how: LowerExp, simple: false } => sym::new_lower_exp,
Format { how: LowerExp, simple: true } => sym::new_lower_exp_simple,
Format { how: UpperExp, simple: false } => sym::new_upper_exp,
Format { how: UpperExp, simple: true } => sym::new_upper_exp_simple,
Format { how: Octal, simple: false } => sym::new_octal,
Format { how: Octal, simple: true } => sym::new_octal_simple,
Format { how: Pointer, simple: false } => sym::new_pointer,
Format { how: Pointer, simple: true } => sym::new_pointer_simple,
Format { how: Binary, simple: false } => sym::new_binary,
Format { how: Binary, simple: true } => sym::new_binary_simple,
Format { how: LowerHex, simple: false } => sym::new_lower_hex,
Format { how: LowerHex, simple: true } => sym::new_lower_hex_simple,
Format { how: UpperHex, simple: false } => sym::new_upper_hex,
Format { how: UpperHex, simple: true } => sym::new_upper_hex_simple,
Usize => sym::from_usize,
},
));
Expand Down Expand Up @@ -360,16 +374,6 @@ fn expand_format_args<'hir>(
let i = bytecode.len();
bytecode.push(0xC0);

let position = argmap
.insert_full(
(
p.argument.index.unwrap_or(usize::MAX),
ArgumentType::Format(p.format_trait),
),
p.span,
)
.0 as u64;

// This needs to match the constants in library/core/src/fmt/mod.rs.
let o = &p.format_options;
let align = match o.alignment {
Expand All @@ -389,6 +393,18 @@ fn expand_format_args<'hir>(
| (o.width.is_some() as u32) << 27
| (o.precision.is_some() as u32) << 28
| align << 29;

let is_simple = flags == default_flags;
let position = argmap
.insert_full(
(
p.argument.index.unwrap_or(usize::MAX),
ArgumentType::Format { how: p.format_trait, simple: is_simple },
),
p.span,
)
.0 as u64;

if flags != default_flags {
bytecode[i] |= 1;
bytecode.extend_from_slice(&flags.to_le_bytes());
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1557,18 +1557,27 @@ symbols! {
never_type_fallback,
new,
new_binary,
new_binary_simple,
new_const,
new_debug,
new_debug_noop,
new_debug_simple,
new_display,
new_display_simple,
new_lower_exp,
new_lower_exp_simple,
new_lower_hex,
new_lower_hex_simple,
new_octal,
new_octal_simple,
new_pointer,
new_pointer_simple,
new_range,
new_unchecked,
new_upper_exp,
new_upper_exp_simple,
new_upper_hex,
new_upper_hex_simple,
new_v1,
new_v1_formatted,
next,
Expand Down
68 changes: 30 additions & 38 deletions library/core/src/fmt/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,58 +73,50 @@ macro_rules! argument_new {
},
#[cfg(any(sanitize = "cfi", sanitize = "kcfi"))]
formatter: |ptr: NonNull<()>, fmt: &mut Formatter<'_>| {
let func = $f;
let f: fn(&$t, &mut Formatter<'_>) -> Result = $f;
// SAFETY: This is the same type as the `value` field.
let r = unsafe { ptr.cast::<$t>().as_ref() };
(func)(r, fmt)
f(r, fmt)
},
_lifetime: PhantomData,
},
}
};
}

macro_rules! argument_constructor {
($name:ident => $trait:path) => {
#[inline]
pub const fn $name<T: $trait>(x: &T) -> Argument<'_> {
argument_new!(T, x, <T as $trait>::fmt)
}

#[inline]
pub const fn ${concat($name, _simple)}<T: $trait>(x: &T) -> Argument<'_> {
argument_new!(T, x, |x, f| {
let mut f = f.with_options(FormattingOptions::new());
<T as $trait>::fmt(x, &mut f)
})
}
};
}

impl Argument<'_> {
#[inline]
pub const fn new_display<T: Display>(x: &T) -> Argument<'_> {
argument_new!(T, x, <T as Display>::fmt)
}
#[inline]
pub const fn new_debug<T: Debug>(x: &T) -> Argument<'_> {
argument_new!(T, x, <T as Debug>::fmt)
}
argument_constructor!(new_display => Display);
argument_constructor!(new_debug => Debug);
argument_constructor!(new_octal => Octal);
argument_constructor!(new_lower_hex => LowerHex);
argument_constructor!(new_upper_hex => UpperHex);
argument_constructor!(new_pointer => Pointer);
argument_constructor!(new_binary => Binary);
argument_constructor!(new_lower_exp => LowerExp);
argument_constructor!(new_upper_exp => UpperExp);

#[inline]
pub const fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> {
argument_new!(T, x, |_: &T, _| Ok(()))
}
#[inline]
pub const fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
argument_new!(T, x, <T as Octal>::fmt)
}
#[inline]
pub const fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> {
argument_new!(T, x, <T as LowerHex>::fmt)
}
#[inline]
pub const fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> {
argument_new!(T, x, <T as UpperHex>::fmt)
}
#[inline]
pub const fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> {
argument_new!(T, x, <T as Pointer>::fmt)
}
#[inline]
pub const fn new_binary<T: Binary>(x: &T) -> Argument<'_> {
argument_new!(T, x, <T as Binary>::fmt)
}
#[inline]
pub const fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> {
argument_new!(T, x, <T as LowerExp>::fmt)
}
#[inline]
pub const fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> {
argument_new!(T, x, <T as UpperExp>::fmt)
}

#[inline]
#[track_caller]
pub const fn from_usize(x: &usize) -> Argument<'_> {
Expand Down
Loading