Skip to content

Commit 9f7e7f0

Browse files
committed
Emit less MIR for format_args! with just a str literal
1 parent 915aa06 commit 9f7e7f0

File tree

8 files changed

+36
-16
lines changed

8 files changed

+36
-16
lines changed

compiler/rustc_ast_lowering/src/format.rs

+26-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_ast::*;
55
use rustc_data_structures::fx::FxIndexMap;
66
use rustc_hir as hir;
77
use rustc_span::{
8+
hygiene::DesugaringKind,
89
sym,
910
symbol::{kw, Ident},
1011
Span, Symbol,
@@ -425,14 +426,36 @@ fn expand_format_args<'hir>(
425426

426427
if allow_const && arguments.is_empty() && argmap.is_empty() {
427428
// Generate:
428-
// <core::fmt::Arguments>::new_const(lit_pieces)
429-
let new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
429+
// const { <core::fmt::Arguments>::new_const(lit_pieces) }
430+
let span = ctx.mark_span_with_reason(
431+
DesugaringKind::FormatArgs,
430432
macsp,
433+
ctx.allow_format_args.clone(),
434+
);
435+
let new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
436+
span,
431437
hir::LangItem::FormatArguments,
432438
sym::new_const,
433439
));
434440
let new_args = ctx.arena.alloc_from_iter([lit_pieces]);
435-
return hir::ExprKind::Call(new, new_args);
441+
let call = hir::ExprKind::Call(new, new_args);
442+
443+
let node_id = ctx.next_node_id();
444+
let call_expr = hir::Expr { hir_id: ctx.lower_node_id(node_id), kind: call, span };
445+
446+
let parent_def_id = ctx.current_hir_id_owner;
447+
let node_id = ctx.next_node_id();
448+
let def_id = ctx.create_def(
449+
parent_def_id.def_id,
450+
node_id,
451+
hir::definitions::DefPathData::AnonConst,
452+
span,
453+
);
454+
return hir::ExprKind::ConstBlock(hir::AnonConst {
455+
def_id,
456+
hir_id: ctx.lower_node_id(node_id),
457+
body: ctx.lower_body(|_this| (&[], call_expr)),
458+
});
436459
}
437460

438461
// If the args array contains exactly all the original arguments once,

compiler/rustc_ast_lowering/src/item.rs

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8484
allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
8585
allow_gen_future: Some([sym::gen_future, sym::closure_track_caller][..].into()),
8686
allow_into_future: Some([sym::into_future][..].into()),
87+
allow_format_args: Some([sym::const_fmt_arguments_new, sym::fmt_internals][..].into()),
8788
generics_def_id_map: Default::default(),
8889
};
8990
lctx.with_hir_id_owner(owner, |lctx| f(lctx));

compiler/rustc_ast_lowering/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ struct LoweringContext<'a, 'hir> {
137137
allow_try_trait: Option<Lrc<[Symbol]>>,
138138
allow_gen_future: Option<Lrc<[Symbol]>>,
139139
allow_into_future: Option<Lrc<[Symbol]>>,
140+
allow_format_args: Option<Lrc<[Symbol]>>,
140141

141142
/// Mapping from generics `def_id`s to TAIT generics `def_id`s.
142143
/// For each captured lifetime (e.g., 'a), we create a new lifetime parameter that is a generic

compiler/rustc_span/src/hygiene.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,7 @@ pub enum DesugaringKind {
11521152
ForLoop,
11531153
WhileLoop,
11541154
Replace,
1155+
FormatArgs,
11551156
}
11561157

11571158
impl DesugaringKind {
@@ -1168,6 +1169,7 @@ impl DesugaringKind {
11681169
DesugaringKind::ForLoop => "`for` loop",
11691170
DesugaringKind::WhileLoop => "`while` loop",
11701171
DesugaringKind::Replace => "drop and replace",
1172+
DesugaringKind::FormatArgs => "`format_args!` expansion",
11711173
}
11721174
}
11731175
}

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ symbols! {
511511
const_eval_select,
512512
const_evaluatable_checked,
513513
const_extern_fn,
514+
const_fmt_arguments_new,
514515
const_fn,
515516
const_fn_floating_point_arithmetic,
516517
const_fn_fn_ptr_basics,
@@ -718,6 +719,7 @@ symbols! {
718719
fmaf32,
719720
fmaf64,
720721
fmt,
722+
fmt_internals,
721723
fmul_fast,
722724
fn_align,
723725
fn_must_use,

library/core/src/fmt/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,8 @@ impl<'a> Arguments<'a> {
393393
#[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
394394
pub const fn new_const(pieces: &'a [&'static str]) -> Self {
395395
if pieces.len() > 1 {
396-
panic!("invalid args");
396+
// panic! expands to a call to this function, so we do this to avoid recursion.
397+
crate::panicking::panic("invalid args");
397398
}
398399
Arguments { pieces, fmt: None, args: &[] }
399400
}

tests/ui/borrowck/issue-64453.rs

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ struct Value;
33

44
static settings_dir: String = format!("");
55
//~^ ERROR cannot call non-const fn
6-
//~| ERROR is not yet stable as a const
76

87
fn from_string(_: String) -> Value {
98
Value

tests/ui/borrowck/issue-64453.stderr

+2-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
error: `Arguments::<'a>::new_const` is not yet stable as a const fn
2-
--> $DIR/issue-64453.rs:4:31
3-
|
4-
LL | static settings_dir: String = format!("");
5-
| ^^^^^^^^^^^
6-
|
7-
= help: add `#![feature(const_fmt_arguments_new)]` to the crate attributes to enable
8-
= note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
9-
101
error[E0015]: cannot call non-const fn `format` in statics
112
--> $DIR/issue-64453.rs:4:31
123
|
@@ -18,12 +9,12 @@ LL | static settings_dir: String = format!("");
189
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
1910

2011
error[E0507]: cannot move out of static item `settings_dir`
21-
--> $DIR/issue-64453.rs:14:37
12+
--> $DIR/issue-64453.rs:13:37
2213
|
2314
LL | let settings_data = from_string(settings_dir);
2415
| ^^^^^^^^^^^^ move occurs because `settings_dir` has type `String`, which does not implement the `Copy` trait
2516

26-
error: aborting due to 3 previous errors
17+
error: aborting due to 2 previous errors
2718

2819
Some errors have detailed explanations: E0015, E0507.
2920
For more information about an error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)