@@ -265,6 +265,26 @@ pub struct ArgumentV1<'a> {
265265 formatter : fn ( & Opaque , & mut Formatter < ' _ > ) -> Result ,
266266}
267267
268+ /// This struct represents the unsafety of constructing an `Arguments`.
269+ /// It exists, rather than an unsafe function, in order to simplify the expansion
270+ /// of `format_args!(..)` and reduce the scope of the `unsafe` block.
271+ #[ allow( missing_debug_implementations) ]
272+ #[ doc( hidden) ]
273+ #[ non_exhaustive]
274+ #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
275+ pub struct UnsafeArg ;
276+
277+ impl UnsafeArg {
278+ /// See documentation where `UnsafeArg` is required to know when it is safe to
279+ /// create and use `UnsafeArg`.
280+ #[ doc( hidden) ]
281+ #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
282+ #[ inline( always) ]
283+ pub unsafe fn new ( ) -> Self {
284+ Self
285+ }
286+ }
287+
268288// This guarantees a single stable value for the function pointer associated with
269289// indices/counts in the formatting infrastructure.
270290//
@@ -337,22 +357,37 @@ impl<'a> Arguments<'a> {
337357 #[ inline]
338358 #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
339359 #[ rustc_const_unstable( feature = "const_fmt_arguments_new" , issue = "none" ) ]
340- pub const unsafe fn new_v1 (
341- pieces : & ' a [ & ' static str ] ,
342- args : & ' a [ ArgumentV1 < ' a > ] ,
343- ) -> Arguments < ' a > {
360+ pub const fn new_v1 ( pieces : & ' a [ & ' static str ] , args : & ' a [ ArgumentV1 < ' a > ] ) -> Arguments < ' a > {
344361 if pieces. len ( ) < args. len ( ) || pieces. len ( ) > args. len ( ) + 1 {
345362 panic ! ( "invalid args" ) ;
346363 }
347364 Arguments { pieces, fmt : None , args }
348365 }
349366
350367 /// This function is used to specify nonstandard formatting parameters.
351- /// The `pieces` array must be at least as long as `fmt` to construct
352- /// a valid Arguments structure. Also, any `Count` within `fmt` that is
353- /// `CountIsParam` or `CountIsNextParam` has to point to an argument
354- /// created with `argumentusize`. However, failing to do so doesn't cause
355- /// unsafety, but will ignore invalid .
368+ ///
369+ /// An `UnsafeArg` is required because the following invariants must be held
370+ /// in order for this function to be safe:
371+ /// 1. The `pieces` slice must be at least as long as `fmt`.
372+ /// 2. Every [`rt::v1::Argument::position`] value within `fmt` must be a
373+ /// valid index of `args`.
374+ /// 3. Every [`Count::Param`] within `fmt` must contain a valid index of
375+ /// `args`.
376+ #[ cfg( not( bootstrap) ) ]
377+ #[ doc( hidden) ]
378+ #[ inline]
379+ #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
380+ #[ rustc_const_unstable( feature = "const_fmt_arguments_new" , issue = "none" ) ]
381+ pub const fn new_v1_formatted (
382+ pieces : & ' a [ & ' static str ] ,
383+ args : & ' a [ ArgumentV1 < ' a > ] ,
384+ fmt : & ' a [ rt:: v1:: Argument ] ,
385+ _unsafe_arg : UnsafeArg ,
386+ ) -> Arguments < ' a > {
387+ Arguments { pieces, fmt : Some ( fmt) , args }
388+ }
389+
390+ #[ cfg( bootstrap) ]
356391 #[ doc( hidden) ]
357392 #[ inline]
358393 #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
0 commit comments