@@ -265,6 +265,26 @@ pub struct ArgumentV1<'a> {
265
265
formatter : fn ( & Opaque , & mut Formatter < ' _ > ) -> Result ,
266
266
}
267
267
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
+
268
288
// This guarantees a single stable value for the function pointer associated with
269
289
// indices/counts in the formatting infrastructure.
270
290
//
@@ -337,22 +357,37 @@ impl<'a> Arguments<'a> {
337
357
#[ inline]
338
358
#[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
339
359
#[ 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 > {
344
361
if pieces. len ( ) < args. len ( ) || pieces. len ( ) > args. len ( ) + 1 {
345
362
panic ! ( "invalid args" ) ;
346
363
}
347
364
Arguments { pieces, fmt : None , args }
348
365
}
349
366
350
367
/// 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) ]
356
391
#[ doc( hidden) ]
357
392
#[ inline]
358
393
#[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
0 commit comments