diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs
index 9b295339d9450..afcf8b15cd800 100644
--- a/compiler/rustc_ast_lowering/src/format.rs
+++ b/compiler/rustc_ast_lowering/src/format.rs
@@ -446,7 +446,30 @@ fn expand_format_args<'hir>(
         && argmap.iter().enumerate().all(|(i, (&(j, _), _))| i == j)
         && arguments.iter().skip(1).all(|arg| !may_contain_yield_point(&arg.expr));
 
-    let args = if use_simple_array {
+    let args = if arguments.is_empty() {
+        // Generate:
+        //    &<core::fmt::Argument>::none()
+        //
+        // Note:
+        //     `none()` just returns `[]`. We use `none()` rather than `[]` to limit the lifetime.
+        //
+        //     This makes sure that this still fails to compile, even when the argument is inlined:
+        //
+        //     ```
+        //     let f = format_args!("{}", "a");
+        //     println!("{f}"); // error E0716
+        //     ```
+        //
+        //     Cases where keeping the object around is allowed, such as `format_args!("a")`,
+        //     are handled above by the `allow_const` case.
+        let none_fn = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
+            macsp,
+            hir::LangItem::FormatArgument,
+            sym::none,
+        ));
+        let none = ctx.expr_call(macsp, none_fn, &[]);
+        ctx.expr(macsp, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, none))
+    } else if use_simple_array {
         // Generate:
         //     &[
         //         <core::fmt::Argument>::new_display(&arg0),
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 117e2774bd87a..60efcb768cb07 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1033,6 +1033,7 @@ symbols! {
         non_exhaustive_omitted_patterns_lint,
         non_lifetime_binders,
         non_modrs_mods,
+        none,
         nontemporal_store,
         noop_method_borrow,
         noop_method_clone,
diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs
index 0596f6c30ce6d..d37888c27bde3 100644
--- a/library/core/src/fmt/rt.rs
+++ b/library/core/src/fmt/rt.rs
@@ -152,6 +152,21 @@ impl<'a> Argument<'a> {
             None
         }
     }
+
+    /// Used by `format_args` when all arguments are gone after inlining,
+    /// when using `&[]` would incorrectly allow for a bigger lifetime.
+    ///
+    /// This fails without format argument inlining, and that shouldn't be different
+    /// when the argument is inlined:
+    ///
+    /// ```compile_fail,E0716
+    /// let f = format_args!("{}", "a");
+    /// println!("{f}");
+    /// ```
+    #[inline(always)]
+    pub fn none() -> [Self; 0] {
+        []
+    }
 }
 
 /// This struct represents the unsafety of constructing an `Arguments`.