Skip to content

Commit

Permalink
Emit less MIR for format_args! with just a str literal
Browse files Browse the repository at this point in the history
  • Loading branch information
saethlin committed Apr 24, 2023
1 parent 915aa06 commit 9f7e7f0
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 16 deletions.
29 changes: 26 additions & 3 deletions compiler/rustc_ast_lowering/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc_ast::*;
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir as hir;
use rustc_span::{
hygiene::DesugaringKind,
sym,
symbol::{kw, Ident},
Span, Symbol,
Expand Down Expand Up @@ -425,14 +426,36 @@ fn expand_format_args<'hir>(

if allow_const && arguments.is_empty() && argmap.is_empty() {
// Generate:
// <core::fmt::Arguments>::new_const(lit_pieces)
let new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
// const { <core::fmt::Arguments>::new_const(lit_pieces) }
let span = ctx.mark_span_with_reason(
DesugaringKind::FormatArgs,
macsp,
ctx.allow_format_args.clone(),
);
let new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
span,
hir::LangItem::FormatArguments,
sym::new_const,
));
let new_args = ctx.arena.alloc_from_iter([lit_pieces]);
return hir::ExprKind::Call(new, new_args);
let call = hir::ExprKind::Call(new, new_args);

let node_id = ctx.next_node_id();
let call_expr = hir::Expr { hir_id: ctx.lower_node_id(node_id), kind: call, span };

let parent_def_id = ctx.current_hir_id_owner;
let node_id = ctx.next_node_id();
let def_id = ctx.create_def(
parent_def_id.def_id,
node_id,
hir::definitions::DefPathData::AnonConst,
span,
);
return hir::ExprKind::ConstBlock(hir::AnonConst {
def_id,
hir_id: ctx.lower_node_id(node_id),
body: ctx.lower_body(|_this| (&[], call_expr)),
});
}

// If the args array contains exactly all the original arguments once,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
allow_gen_future: Some([sym::gen_future, sym::closure_track_caller][..].into()),
allow_into_future: Some([sym::into_future][..].into()),
allow_format_args: Some([sym::const_fmt_arguments_new, sym::fmt_internals][..].into()),
generics_def_id_map: Default::default(),
};
lctx.with_hir_id_owner(owner, |lctx| f(lctx));
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ struct LoweringContext<'a, 'hir> {
allow_try_trait: Option<Lrc<[Symbol]>>,
allow_gen_future: Option<Lrc<[Symbol]>>,
allow_into_future: Option<Lrc<[Symbol]>>,
allow_format_args: Option<Lrc<[Symbol]>>,

/// Mapping from generics `def_id`s to TAIT generics `def_id`s.
/// For each captured lifetime (e.g., 'a), we create a new lifetime parameter that is a generic
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/hygiene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,7 @@ pub enum DesugaringKind {
ForLoop,
WhileLoop,
Replace,
FormatArgs,
}

impl DesugaringKind {
Expand All @@ -1168,6 +1169,7 @@ impl DesugaringKind {
DesugaringKind::ForLoop => "`for` loop",
DesugaringKind::WhileLoop => "`while` loop",
DesugaringKind::Replace => "drop and replace",
DesugaringKind::FormatArgs => "`format_args!` expansion",
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ symbols! {
const_eval_select,
const_evaluatable_checked,
const_extern_fn,
const_fmt_arguments_new,
const_fn,
const_fn_floating_point_arithmetic,
const_fn_fn_ptr_basics,
Expand Down Expand Up @@ -718,6 +719,7 @@ symbols! {
fmaf32,
fmaf64,
fmt,
fmt_internals,
fmul_fast,
fn_align,
fn_must_use,
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,8 @@ impl<'a> Arguments<'a> {
#[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
pub const fn new_const(pieces: &'a [&'static str]) -> Self {
if pieces.len() > 1 {
panic!("invalid args");
// panic! expands to a call to this function, so we do this to avoid recursion.
crate::panicking::panic("invalid args");
}
Arguments { pieces, fmt: None, args: &[] }
}
Expand Down
1 change: 0 additions & 1 deletion tests/ui/borrowck/issue-64453.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ struct Value;

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

fn from_string(_: String) -> Value {
Value
Expand Down
13 changes: 2 additions & 11 deletions tests/ui/borrowck/issue-64453.stderr
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
error: `Arguments::<'a>::new_const` is not yet stable as a const fn
--> $DIR/issue-64453.rs:4:31
|
LL | static settings_dir: String = format!("");
| ^^^^^^^^^^^
|
= help: add `#![feature(const_fmt_arguments_new)]` to the crate attributes to enable
= 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)

error[E0015]: cannot call non-const fn `format` in statics
--> $DIR/issue-64453.rs:4:31
|
Expand All @@ -18,12 +9,12 @@ LL | static settings_dir: String = format!("");
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)

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

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

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

0 comments on commit 9f7e7f0

Please sign in to comment.