This repository was archived by the owner on May 28, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 3 files changed +40
-1
lines changed Expand file tree Collapse file tree 3 files changed +40
-1
lines changed Original file line number Diff line number Diff line change @@ -446,7 +446,30 @@ fn expand_format_args<'hir>(
446446 && argmap. iter ( ) . enumerate ( ) . all ( |( i, ( & ( j, _) , _) ) | i == j)
447447 && arguments. iter ( ) . skip ( 1 ) . all ( |arg| !may_contain_yield_point ( & arg. expr ) ) ;
448448
449- let args = if use_simple_array {
449+ let args = if arguments. is_empty ( ) {
450+ // Generate:
451+ // &<core::fmt::Argument>::none()
452+ //
453+ // Note:
454+ // `none()` just returns `[]`. We use `none()` rather than `[]` to limit the lifetime.
455+ //
456+ // This makes sure that this still fails to compile, even when the argument is inlined:
457+ //
458+ // ```
459+ // let f = format_args!("{}", "a");
460+ // println!("{f}"); // error E0716
461+ // ```
462+ //
463+ // Cases where keeping the object around is allowed, such as `format_args!("a")`,
464+ // are handled above by the `allow_const` case.
465+ let none_fn = ctx. arena . alloc ( ctx. expr_lang_item_type_relative (
466+ macsp,
467+ hir:: LangItem :: FormatArgument ,
468+ sym:: none,
469+ ) ) ;
470+ let none = ctx. expr_call ( macsp, none_fn, & [ ] ) ;
471+ ctx. expr ( macsp, hir:: ExprKind :: AddrOf ( hir:: BorrowKind :: Ref , hir:: Mutability :: Not , none) )
472+ } else if use_simple_array {
450473 // Generate:
451474 // &[
452475 // <core::fmt::Argument>::new_display(&arg0),
Original file line number Diff line number Diff line change @@ -1033,6 +1033,7 @@ symbols! {
10331033 non_exhaustive_omitted_patterns_lint,
10341034 non_lifetime_binders,
10351035 non_modrs_mods,
1036+ none,
10361037 nontemporal_store,
10371038 noop_method_borrow,
10381039 noop_method_clone,
Original file line number Diff line number Diff line change @@ -152,6 +152,21 @@ impl<'a> Argument<'a> {
152152 None
153153 }
154154 }
155+
156+ /// Used by `format_args` when all arguments are gone after inlining,
157+ /// when using `&[]` would incorrectly allow for a bigger lifetime.
158+ ///
159+ /// This fails without format argument inlining, and that shouldn't be different
160+ /// when the argument is inlined:
161+ ///
162+ /// ```compile_fail,E0716
163+ /// let f = format_args!("{}", "a");
164+ /// println!("{f}");
165+ /// ```
166+ #[ inline( always) ]
167+ pub fn none ( ) -> [ Self ; 0 ] {
168+ [ ]
169+ }
155170}
156171
157172/// This struct represents the unsafety of constructing an `Arguments`.
You can’t perform that action at this time.
0 commit comments