Rollup merge of #110770 - m-ou-se:fmt-temp-lifetime, r=oli-obk
Limit lifetime of format_args!() with inlined args. Fixes #110769
This commit is contained in:
commit
e4c82501c2
@ -446,7 +446,30 @@ fn expand_format_args<'hir>(
|
|||||||
&& argmap.iter().enumerate().all(|(i, (&(j, _), _))| i == j)
|
&& argmap.iter().enumerate().all(|(i, (&(j, _), _))| i == j)
|
||||||
&& arguments.iter().skip(1).all(|arg| !may_contain_yield_point(&arg.expr));
|
&& 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:
|
// Generate:
|
||||||
// &[
|
// &[
|
||||||
// <core::fmt::Argument>::new_display(&arg0),
|
// <core::fmt::Argument>::new_display(&arg0),
|
||||||
|
@ -1033,6 +1033,7 @@
|
|||||||
non_exhaustive_omitted_patterns_lint,
|
non_exhaustive_omitted_patterns_lint,
|
||||||
non_lifetime_binders,
|
non_lifetime_binders,
|
||||||
non_modrs_mods,
|
non_modrs_mods,
|
||||||
|
none,
|
||||||
nontemporal_store,
|
nontemporal_store,
|
||||||
noop_method_borrow,
|
noop_method_borrow,
|
||||||
noop_method_clone,
|
noop_method_clone,
|
||||||
|
@ -152,6 +152,21 @@ pub(super) fn as_usize(&self) -> Option<usize> {
|
|||||||
None
|
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`.
|
/// This struct represents the unsafety of constructing an `Arguments`.
|
||||||
|
Loading…
Reference in New Issue
Block a user