File tree 6 files changed +116
-33
lines changed
6 files changed +116
-33
lines changed Original file line number Diff line number Diff line change 97
97
#![ feature( exact_size_is_empty) ]
98
98
#![ feature( exclusive_range_pattern) ]
99
99
#![ feature( extend_one) ]
100
+ #![ feature( fmt_as_str) ]
100
101
#![ feature( fmt_internals) ]
101
102
#![ feature( fn_traits) ]
102
103
#![ feature( fundamental) ]
Original file line number Diff line number Diff line change @@ -101,9 +101,21 @@ macro_rules! vec {
101
101
/// ```
102
102
#[ macro_export]
103
103
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
104
+ #[ allow_internal_unstable( fmt_as_str) ]
104
105
macro_rules! format {
105
106
( $( $arg: tt) * ) => { {
106
- let res = $crate:: fmt:: format( $crate:: __export:: format_args!( $( $arg) * ) ) ;
107
- res
107
+ // NOTE: `format_args!` borrows from temporaries. This means that
108
+ // `match` is necessary to extend the lifetime of the temporaries until after
109
+ // the `Arguments` is no longer used. The same pattern is used
110
+ // inside `format_args!` itself.
111
+ let r = match $crate:: __export:: format_args!( $( $arg) * ) {
112
+ // HACK: We hope that constant propagation will make LLVM optimize out
113
+ // this match.
114
+ args => match args. as_str( ) {
115
+ Some ( s) => $crate:: borrow:: ToOwned :: to_owned( s) ,
116
+ None => $crate:: fmt:: format( args) ,
117
+ }
118
+ } ;
119
+ r
108
120
} }
109
121
}
Original file line number Diff line number Diff line change
1
+ // min-llvm-version: 10.0.0
2
+ // compile-flags: -C opt-level=3
3
+ #![ crate_type = "rlib" ]
4
+ #![ feature( format_args_capture) ]
5
+
6
+ // Make sure allocation not happen when result of `format!` is unused and
7
+ // there are no formatting arguments.
8
+
9
+ // CHECK-LABEL: @format_wo_fmt_args
10
+ // CHECK-NEXT: {{"_ZN[^:]+"}}:
11
+ // CHECK-NEXT: ret
12
+ #[ no_mangle]
13
+ pub fn format_wo_fmt_args ( ) {
14
+ format ! ( "" ) ;
15
+ format ! ( "a long story" ) ;
16
+ format ! ( "a long story {{" ) ;
17
+ }
18
+
19
+ // CHECK-LABEL: @format_wo_fmt_args_ret
20
+ // CHECK-NOT: Arguments
21
+ #[ no_mangle]
22
+ pub fn format_wo_fmt_args_ret ( ) -> String {
23
+ format ! ( "a long story" )
24
+ }
25
+
26
+ // CHECK-LABEL: @format_w_fmt_args_ret_1
27
+ // CHECK: alloc::fmt::format
28
+ #[ no_mangle]
29
+ pub fn format_w_fmt_args_ret_1 ( n : usize ) -> String {
30
+ format ! ( "a long story: {}" , n)
31
+ }
32
+
33
+ // CHECK-LABEL: @format_w_fmt_args_ret_2
34
+ // CHECK: core::fmt::ArgumentV1::from_usize
35
+ // CHECK: alloc::fmt::format
36
+ #[ no_mangle]
37
+ pub fn format_w_fmt_args_ret_2 ( n : usize , width : usize ) -> String {
38
+ format ! ( "a long story {n:width$}" )
39
+ }
Original file line number Diff line number Diff line change 30
30
31
31
32
32
({
33
- let res =
34
- ((::alloc::fmt::format as
35
- for<' r> fn(Arguments<' r>) -> String {format })(((::core::fmt::Arguments::new_v1
36
- 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]))
58
- as
59
- Arguments))
60
- as String);
61
- (res as String)
33
+ let r =
34
+ (match ((::core::fmt::Arguments::new_v1 as
35
+ fn(&[&' static str], &[ArgumentV1]) -> Arguments {Arguments::new_v1})((&([("test"
36
+ as
37
+ &str)]
38
+ as
39
+ [&str; 1])
40
+ as
41
+ &[&str; 1]),
42
+ (&(match (()
43
+ as
44
+ ())
45
+ {
46
+ ()
47
+ =>
48
+ ([]
49
+ as
50
+ [ArgumentV1; 0]),
51
+ }
52
+ as
53
+ [ArgumentV1; 0])
54
+ as
55
+ &[ArgumentV1; 0]))
56
+ as Arguments) {
57
+ args =>
58
+ (match ((args as Arguments).as_str() as
59
+ Option<&str>) {
60
+ Some(s) =>
61
+ ((::alloc::borrow::ToOwned::to_owned as
62
+ for<' r> fn(&' r str) -> <str as ToOwned>::Owned {<str as ToOwned>::to_owned})((s
63
+ as
64
+ &str))
65
+ as String),
66
+ None =>
67
+ ((::alloc::fmt::format as
68
+ for<' r> fn(Arguments<' r>) -> String {format})((args
69
+ as
70
+ Arguments))
71
+ as String),
72
+ } as String),
73
+ } as String);
74
+ (r as String)
62
75
} as String);
63
76
} as ())
64
77
pub type Foo = [i32; (3 as usize)];
Original file line number Diff line number Diff line change @@ -4,6 +4,8 @@ struct Value;
4
4
static settings_dir: String = format ! ( "" ) ;
5
5
//~^ ERROR calls in statics are limited to constant functions
6
6
//~| ERROR calls in statics are limited to constant functions
7
+ //~| ERROR calls in statics are limited to constant functions
8
+ //~| ERROR calls in statics are limited to constant functions
7
9
8
10
fn from_string ( _: String ) -> Value {
9
11
Value
Original file line number Diff line number Diff line change 1
1
error[E0507]: cannot move out of static item `settings_dir`
2
- --> $DIR/issue-64453.rs:14 :37
2
+ --> $DIR/issue-64453.rs:16 :37
3
3
|
4
4
LL | let settings_data = from_string(settings_dir);
5
5
| ^^^^^^^^^^^^ move occurs because `settings_dir` has type `String`, which does not implement the `Copy` trait
@@ -20,7 +20,23 @@ LL | static settings_dir: String = format!("");
20
20
|
21
21
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
22
22
23
- error: aborting due to 3 previous errors
23
+ error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
24
+ --> $DIR/issue-64453.rs:4:31
25
+ |
26
+ LL | static settings_dir: String = format!("");
27
+ | ^^^^^^^^^^^
28
+ |
29
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
30
+
31
+ error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
32
+ --> $DIR/issue-64453.rs:4:31
33
+ |
34
+ LL | static settings_dir: String = format!("");
35
+ | ^^^^^^^^^^^
36
+ |
37
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
38
+
39
+ error: aborting due to 5 previous errors
24
40
25
41
Some errors have detailed explanations: E0015, E0507.
26
42
For more information about an error, try `rustc --explain E0015`.
You can’t perform that action at this time.
0 commit comments