Skip to content

Commit efeeca4

Browse files
committed
Simplify format_args!() expansion.
1 parent 61707d3 commit efeeca4

File tree

8 files changed

+100
-111
lines changed

8 files changed

+100
-111
lines changed

compiler/rustc_ast_lowering/src/format.rs

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -524,19 +524,6 @@ fn expand_format_args<'hir>(
524524
let zero = ctx.expr_usize(macsp, 0);
525525
pieces.push(make_piece(ctx, sym::num, zero, macsp));
526526

527-
// ```
528-
// unsafe { <core::fmt::rt::Template>::new(const { &[pieces…] }) }
529-
// ```
530-
let template_new =
531-
ctx.expr_lang_item_type_relative(macsp, hir::LangItem::FormatTemplate, sym::new);
532-
let pieces = ctx.expr_array_ref(macsp, ctx.arena.alloc_from_iter(pieces));
533-
let pieces = ctx.expr_const(macsp, pieces);
534-
let template = ctx.expr(
535-
macsp,
536-
hir::ExprKind::Call(ctx.arena.alloc(template_new), ctx.arena.alloc_from_iter([pieces])),
537-
);
538-
let template = ctx.expr_unsafe(macsp, ctx.arena.alloc(template));
539-
540527
// Ensure all argument indexes actually fit in 10 bits, as we truncated them to 10 bits before.
541528
if argmap.len() >= 1 << 10 {
542529
ctx.dcx().emit_err(TooManyFormatArguments { span: fmt.span });
@@ -615,20 +602,35 @@ fn expand_format_args<'hir>(
615602
};
616603

617604
// Generate:
618-
// <core::fmt::Arguments>::new(
619-
// template,
620-
// &args,
621-
// )
605+
// unsafe {
606+
// <core::fmt::Arguments>::new(
607+
// const { &[pieces…] },
608+
// &args,
609+
// )
610+
// }
611+
let pieces = ctx.expr_array_ref(macsp, ctx.arena.alloc_from_iter(pieces));
612+
let pieces = ctx.expr_const(macsp, pieces);
622613
let call = {
623614
let new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
624615
macsp,
625616
hir::LangItem::FormatArguments,
626617
sym::new,
627618
));
628619
let args = ctx.expr_ref(macsp, args);
629-
let new_args = ctx.arena.alloc_from_iter([template, args]);
630-
hir::ExprKind::Call(new, new_args)
620+
let new_args = ctx.arena.alloc_from_iter([pieces, args]);
621+
ctx.expr_call(macsp, new, new_args)
631622
};
623+
let call = hir::ExprKind::Block(
624+
ctx.arena.alloc(hir::Block {
625+
stmts: &[],
626+
expr: Some(call),
627+
hir_id: ctx.next_id(),
628+
rules: hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated),
629+
span: macsp,
630+
targeted_by_break: false,
631+
}),
632+
None,
633+
);
632634

633635
if !let_statements.is_empty() {
634636
// Generate:

compiler/rustc_const_eval/src/check_consts/ops.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,9 +345,7 @@ fn build_error_for_const_call<'tcx>(
345345
note_trait_if_possible(&mut err, self_ty, tcx.require_lang_item(LangItem::Deref, span));
346346
err
347347
}
348-
_ if tcx.is_diagnostic_item(sym::FmtTemplateNew, callee)
349-
|| tcx.is_diagnostic_item(sym::FmtArgumentsFromStrNonconst, callee) =>
350-
{
348+
_ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::FmtArgumentsNew) => {
351349
ccx.dcx().create_err(errors::NonConstFmtMacroCall {
352350
span,
353351
kind: ccx.const_kind(),

compiler/rustc_hir/src/lang_items.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,6 @@ language_item_table! {
329329
FormatArgument, sym::format_argument, format_argument, Target::Struct, GenericRequirement::None;
330330
FormatArguments, sym::format_arguments, format_arguments, Target::Struct, GenericRequirement::None;
331331
FormatPiece, sym::format_piece, format_piece, Target::Union, GenericRequirement::None;
332-
FormatTemplate, sym::format_template, format_template, Target::Struct, GenericRequirement::None;
333332

334333
ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None;
335334
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,7 @@ symbols! {
235235
Error,
236236
File,
237237
FileType,
238-
FmtArgumentsFromStrNonconst,
239-
FmtTemplateNew,
238+
FmtArgumentsNew,
240239
FmtWrite,
241240
Fn,
242241
FnMut,
@@ -1095,7 +1094,6 @@ symbols! {
10951094
format_arguments,
10961095
format_macro,
10971096
format_piece,
1098-
format_template,
10991097
framework,
11001098
freeze,
11011099
freeze_impls,

library/core/src/fmt/rt.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use crate::marker::PhantomData;
1212
use crate::mem;
1313
use crate::ptr::NonNull;
1414

15-
#[lang = "format_template"]
1615
#[derive(Copy, Clone)]
1716
pub struct Template<'a> {
1817
pub(super) pieces: NonNull<rt::Piece>,
@@ -24,7 +23,6 @@ unsafe impl Sync for Template<'_> {}
2423

2524
impl<'a> Template<'a> {
2625
#[inline]
27-
#[rustc_diagnostic_item = "FmtTemplateNew"]
2826
pub unsafe fn new<const N: usize>(pieces: &'a [rt::Piece; N]) -> Self {
2927
Self { pieces: NonNull::from_ref(pieces).cast(), lifetime: PhantomData }
3028
}
@@ -232,31 +230,32 @@ impl Argument<'_> {
232230

233231
/// Used by the format_args!() macro to create a fmt::Arguments object.
234232
#[doc(hidden)]
233+
#[rustc_diagnostic_item = "FmtArgumentsNew"]
235234
impl<'a> Arguments<'a> {
236235
#[inline]
237-
pub const fn new<const N: usize>(
238-
template: rt::Template<'a>,
239-
args: &'a [rt::Argument<'a>; N],
236+
pub unsafe fn new<const N: usize, const M: usize>(
237+
pieces: &'a [rt::Piece; N],
238+
args: &'a [rt::Argument<'a>; M],
240239
) -> Arguments<'a> {
241-
Arguments { template, args: NonNull::from_ref(args).cast() }
240+
Arguments {
241+
// SAFETY: Responsibility of the caller.
242+
template: unsafe { Template::new(pieces) },
243+
args: NonNull::from_ref(args).cast(),
244+
}
242245
}
243246

244247
#[inline]
245248
pub const fn from_str(s: &'static str) -> Arguments<'a> {
246249
// SAFETY: This is the "static str" representation of fmt::Arguments.
247250
unsafe {
248-
Arguments {
249-
template: rt::Template::new_str_len(s.len()),
250-
args: mem::transmute(s.as_ptr()),
251-
}
251+
Arguments { template: Template::new_str_len(s.len()), args: mem::transmute(s.as_ptr()) }
252252
}
253253
}
254254

255255
// Same as `from_str`, but not const.
256256
// Used by format_args!() expansion when arguments are inlined,
257257
// e.g. format_args!("{}", 123), which is not allowed in const.
258258
#[inline]
259-
#[rustc_diagnostic_item = "FmtArgumentsFromStrNonconst"]
260259
pub fn from_str_nonconst(s: &'static str) -> Arguments<'a> {
261260
Arguments::from_str(s)
262261
}

tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff

Lines changed: 56 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,22 @@
1717
let mut _17: &std::boxed::Box<dyn std::fmt::Display>;
1818
let mut _18: core::fmt::rt::Argument<'_>;
1919
let mut _19: &u32;
20-
let mut _20: core::fmt::rt::Template<'_>;
21-
let mut _21: &[core::fmt::rt::Piece; 7];
22-
let _22: &[core::fmt::rt::Piece; 7];
23-
let mut _23: &[core::fmt::rt::Argument<'_>; 2];
24-
let _24: &[core::fmt::rt::Argument<'_>; 2];
25-
let mut _25: &std::boxed::Box<dyn std::fmt::Display>;
26-
let mut _26: &u32;
27-
let mut _27: bool;
20+
let mut _20: &[core::fmt::rt::Piece; 7];
21+
let _21: &[core::fmt::rt::Piece; 7];
22+
let mut _22: &[core::fmt::rt::Argument<'_>; 2];
23+
let _23: &[core::fmt::rt::Argument<'_>; 2];
24+
let mut _24: &std::boxed::Box<dyn std::fmt::Display>;
25+
let mut _25: &u32;
26+
let mut _26: bool;
27+
let mut _27: isize;
2828
let mut _28: isize;
2929
let mut _29: isize;
30-
let mut _30: isize;
31-
+ let _31: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>;
32-
+ let _32: u32;
30+
+ let _30: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>;
31+
+ let _31: u32;
3332
scope 1 {
3433
- debug foo => _1;
35-
+ debug ((foo: Foo<T>).0: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>) => _31;
36-
+ debug ((foo: Foo<T>).1: u32) => _32;
34+
+ debug ((foo: Foo<T>).0: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>) => _30;
35+
+ debug ((foo: Foo<T>).1: u32) => _31;
3736
let _5: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>;
3837
scope 2 {
3938
debug x => _5;
@@ -44,12 +43,12 @@
4443
debug x => _8;
4544
let _8: std::boxed::Box<dyn std::fmt::Display>;
4645
let _12: (&std::boxed::Box<dyn std::fmt::Display>, &u32);
47-
+ let _33: &std::boxed::Box<dyn std::fmt::Display>;
48-
+ let _34: &u32;
46+
+ let _32: &std::boxed::Box<dyn std::fmt::Display>;
47+
+ let _33: &u32;
4948
scope 5 {
5049
- debug args => _12;
51-
+ debug ((args: (&Box<dyn std::fmt::Display>, &u32)).0: &std::boxed::Box<dyn std::fmt::Display>) => _33;
52-
+ debug ((args: (&Box<dyn std::fmt::Display>, &u32)).1: &u32) => _34;
50+
+ debug ((args: (&Box<dyn std::fmt::Display>, &u32)).0: &std::boxed::Box<dyn std::fmt::Display>) => _32;
51+
+ debug ((args: (&Box<dyn std::fmt::Display>, &u32)).1: &u32) => _33;
5352
let _15: [core::fmt::rt::Argument<'_>; 2];
5453
scope 6 {
5554
debug args => _15;
@@ -61,10 +60,10 @@
6160
}
6261

6362
bb0: {
64-
_27 = const false;
63+
_26 = const false;
6564
- StorageLive(_1);
65+
+ StorageLive(_30);
6666
+ StorageLive(_31);
67-
+ StorageLive(_32);
6867
+ nop;
6968
StorageLive(_2);
7069
StorageLive(_3);
@@ -78,19 +77,19 @@
7877
_2 = Result::<Box<dyn std::fmt::Display>, <T as Err>::Err>::Ok(move _3);
7978
StorageDead(_3);
8079
- _1 = Foo::<T> { x: move _2, y: const 7_u32 };
81-
+ _31 = move _2;
82-
+ _32 = const 7_u32;
80+
+ _30 = move _2;
81+
+ _31 = const 7_u32;
8382
+ nop;
8483
StorageDead(_2);
8584
StorageLive(_5);
86-
_27 = const true;
85+
_26 = const true;
8786
- _5 = move (_1.0: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>);
88-
+ _5 = move _31;
87+
+ _5 = move _30;
8988
StorageLive(_6);
9089
- _6 = copy (_1.1: u32);
91-
+ _6 = copy _32;
90+
+ _6 = copy _31;
9291
_7 = discriminant(_5);
93-
switchInt(move _7) -> [0: bb2, otherwise: bb8];
92+
switchInt(move _7) -> [0: bb2, otherwise: bb7];
9493
}
9594

9695
bb2: {
@@ -100,35 +99,35 @@
10099
StorageLive(_10);
101100
StorageLive(_11);
102101
- StorageLive(_12);
102+
+ StorageLive(_32);
103103
+ StorageLive(_33);
104-
+ StorageLive(_34);
105104
+ nop;
106105
StorageLive(_13);
107106
_13 = &_8;
108107
StorageLive(_14);
109108
_14 = &_6;
110109
- _12 = (move _13, move _14);
111-
+ _33 = move _13;
112-
+ _34 = move _14;
110+
+ _32 = move _13;
111+
+ _33 = move _14;
113112
+ nop;
114113
StorageDead(_14);
115114
StorageDead(_13);
116115
StorageLive(_15);
117116
StorageLive(_16);
118117
StorageLive(_17);
119-
- _25 = copy (_12.0: &std::boxed::Box<dyn std::fmt::Display>);
120-
+ _25 = copy _33;
121-
_17 = &(*_25);
118+
- _24 = copy (_12.0: &std::boxed::Box<dyn std::fmt::Display>);
119+
+ _24 = copy _32;
120+
_17 = &(*_24);
122121
_16 = core::fmt::rt::Argument::<'_>::new_display::<Box<dyn std::fmt::Display>>(move _17) -> [return: bb3, unwind unreachable];
123122
}
124123

125124
bb3: {
126125
StorageDead(_17);
127126
StorageLive(_18);
128127
StorageLive(_19);
129-
- _26 = copy (_12.1: &u32);
130-
+ _26 = copy _34;
131-
_19 = &(*_26);
128+
- _25 = copy (_12.1: &u32);
129+
+ _25 = copy _33;
130+
_19 = &(*_25);
132131
_18 = core::fmt::rt::Argument::<'_>::new_display::<u32>(move _19) -> [return: bb4, unwind unreachable];
133132
}
134133

@@ -139,71 +138,65 @@
139138
StorageDead(_16);
140139
StorageLive(_20);
141140
StorageLive(_21);
141+
_21 = const foo::<T>::{constant#0}::<&[core::fmt::rt::Piece; 7]>;
142+
_20 = &(*_21);
142143
StorageLive(_22);
143-
_22 = const foo::<T>::{constant#0}::<&[core::fmt::rt::Piece; 7]>;
144-
_21 = &(*_22);
145-
_20 = core::fmt::rt::Template::<'_>::new::<7>(move _21) -> [return: bb5, unwind unreachable];
144+
StorageLive(_23);
145+
_23 = &_15;
146+
_22 = &(*_23);
147+
_11 = core::fmt::rt::<impl Arguments<'_>>::new::<7, 2>(move _20, move _22) -> [return: bb5, unwind unreachable];
146148
}
147149

148150
bb5: {
151+
StorageDead(_23);
149152
StorageDead(_22);
150153
StorageDead(_21);
151-
StorageLive(_23);
152-
StorageLive(_24);
153-
_24 = &_15;
154-
_23 = &(*_24);
155-
_11 = core::fmt::rt::<impl Arguments<'_>>::new::<2>(move _20, move _23) -> [return: bb6, unwind unreachable];
156-
}
157-
158-
bb6: {
159-
StorageDead(_24);
160-
StorageDead(_23);
161154
StorageDead(_20);
162-
_10 = _eprint(move _11) -> [return: bb7, unwind unreachable];
155+
_10 = _eprint(move _11) -> [return: bb6, unwind unreachable];
163156
}
164157

165-
bb7: {
158+
bb6: {
166159
StorageDead(_11);
167160
StorageDead(_15);
168161
- StorageDead(_12);
162+
+ StorageDead(_32);
169163
+ StorageDead(_33);
170-
+ StorageDead(_34);
171164
+ nop;
172165
StorageDead(_10);
173166
_9 = const ();
174167
StorageDead(_9);
175168
_0 = const ();
176-
drop(_8) -> [return: bb9, unwind unreachable];
169+
drop(_8) -> [return: bb8, unwind unreachable];
177170
}
178171

179-
bb8: {
172+
bb7: {
180173
_0 = const ();
181-
goto -> bb10;
174+
goto -> bb9;
182175
}
183176

184-
bb9: {
177+
bb8: {
185178
StorageDead(_8);
186-
goto -> bb10;
179+
goto -> bb9;
187180
}
188181

189-
bb10: {
182+
bb9: {
190183
StorageDead(_6);
191-
_28 = discriminant(_5);
192-
switchInt(move _28) -> [0: bb11, otherwise: bb12];
184+
_27 = discriminant(_5);
185+
switchInt(move _27) -> [0: bb10, otherwise: bb11];
193186
}
194187

195-
bb11: {
196-
_27 = const false;
188+
bb10: {
189+
_26 = const false;
197190
StorageDead(_5);
198191
- StorageDead(_1);
192+
+ StorageDead(_30);
199193
+ StorageDead(_31);
200-
+ StorageDead(_32);
201194
+ nop;
202195
return;
203196
}
204197

205-
bb12: {
206-
drop(_5) -> [return: bb11, unwind unreachable];
198+
bb11: {
199+
drop(_5) -> [return: bb10, unwind unreachable];
207200
}
208201
}
209202

0 commit comments

Comments
 (0)