Skip to content

Commit e1092d4

Browse files
committed
Make format_args!("literal") const.
1 parent 95fb131 commit e1092d4

File tree

6 files changed

+62
-29
lines changed

6 files changed

+62
-29
lines changed

compiler/rustc_builtin_macros/src/format.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,7 @@ impl<'a, 'b> Context<'a, 'b> {
761761
/// Actually builds the expression which the format_args! block will be
762762
/// expanded to.
763763
fn into_expr(self) -> P<ast::Expr> {
764+
let is_literal = self.str_pieces.len() == 1 && self.args.is_empty();
764765
let mut locals =
765766
Vec::with_capacity((0..self.args.len()).map(|i| self.arg_unique_types[i].len()).sum());
766767
let mut counts = Vec::with_capacity(self.count_args.len());
@@ -846,7 +847,9 @@ impl<'a, 'b> Context<'a, 'b> {
846847
let args_slice = self.ecx.expr_addr_of(self.macsp, result);
847848

848849
// Now create the fmt::Arguments struct with all our locals we created.
849-
let (fn_name, fn_args) = if self.all_pieces_simple {
850+
let (fn_name, fn_args) = if is_literal {
851+
("new_literal", vec![pieces])
852+
} else if self.all_pieces_simple {
850853
("new_v1", vec![pieces, args_slice])
851854
} else {
852855
// Build up the static array which will store our precompiled

library/core/src/fmt/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,15 @@ enum FlagV1 {
332332
}
333333

334334
impl<'a> Arguments<'a> {
335+
/// When using the format_args!() macro, this function is used to generate the
336+
/// Arguments structure in case it's just a single string literal.
337+
#[doc(hidden)]
338+
#[inline]
339+
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
340+
pub const fn new_literal(pieces: &'a [&'static str; 1]) -> Arguments<'a> {
341+
Arguments { pieces, fmt: None, args: &[] }
342+
}
343+
335344
/// When using the format_args!() macro, this function is used to generate the
336345
/// Arguments structure.
337346
#[doc(hidden)]

src/test/pretty/dollar-crate.pp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,5 @@
99
// pp-exact:dollar-crate.pp
1010

1111
fn main() {
12-
{
13-
::std::io::_print(::core::fmt::Arguments::new_v1(&["rust\n"],
14-
&match () {
15-
() => [],
16-
}));
17-
};
12+
{ ::std::io::_print(::core::fmt::Arguments::new_literal(&["rust\n"])); };
1813
}

src/test/pretty/issue-4264.pp

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,15 @@
3232
({
3333
let res =
3434
((::alloc::fmt::format as
35-
for<'r> fn(Arguments<'r>) -> String {format})(((::core::fmt::Arguments::new_v1
35+
for<'r> fn(Arguments<'r>) -> String {format})(((::core::fmt::Arguments::new_literal
3636
as
37-
fn(&[&'static str], &[ArgumentV1]) -> Arguments {Arguments::new_v1})((&([("test"
38-
as
39-
&str)]
40-
as
41-
[&str; 1])
42-
as
43-
&[&str; 1]),
44-
(&(match (()
45-
as
46-
())
47-
{
48-
()
49-
=>
50-
([]
51-
as
52-
[ArgumentV1; 0]),
53-
}
54-
as
55-
[ArgumentV1; 0])
56-
as
57-
&[ArgumentV1; 0]))
37+
fn(&[&'static str; 1]) -> Arguments {Arguments::new_literal})((&([("test"
38+
as
39+
&str)]
40+
as
41+
[&str; 1])
42+
as
43+
&[&str; 1]))
5844
as
5945
Arguments))
6046
as String);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![crate_type = "lib"]
2+
3+
const A: std::fmt::Arguments = format_args!("literal");
4+
5+
const B: std::fmt::Arguments = format_args!("{}", 123);
6+
//~^ ERROR calls in constants are limited to
7+
//~| ERROR calls in constants are limited to
8+
//~| ERROR temporary value
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
2+
--> $DIR/format_args.rs:5:32
3+
|
4+
LL | const B: std::fmt::Arguments = format_args!("{}", 123);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
10+
--> $DIR/format_args.rs:5:32
11+
|
12+
LL | const B: std::fmt::Arguments = format_args!("{}", 123);
13+
| ^^^^^^^^^^^^^^^^^^^^^^^
14+
|
15+
= note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
16+
17+
error[E0716]: temporary value dropped while borrowed
18+
--> $DIR/format_args.rs:5:32
19+
|
20+
LL | const B: std::fmt::Arguments = format_args!("{}", 123);
21+
| ^^^^^^^^^^^^^^^^^^^^^^-
22+
| | |
23+
| | temporary value is freed at the end of this statement
24+
| creates a temporary which is freed while still in use
25+
| using this value as a constant requires that borrow lasts for `'static`
26+
|
27+
= note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
28+
29+
error: aborting due to 3 previous errors
30+
31+
Some errors have detailed explanations: E0015, E0716.
32+
For more information about an error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)