about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-05-26 01:10:39 +0000
committerbors <bors@rust-lang.org>2024-05-26 01:10:39 +0000
commit75e2c5dcd0ddce0fe0eb3d4a2195cd51073c729b (patch)
tree3514db09772b2f31f920e8feb3570a5802b83f02
parent0a59f113629aafb6e5ee55ad04a2d451a11d8466 (diff)
parent9763222f592dad3e3fdda987491da3878f1c1410 (diff)
downloadrust-75e2c5dcd0ddce0fe0eb3d4a2195cd51073c729b.tar.gz
rust-75e2c5dcd0ddce0fe0eb3d4a2195cd51073c729b.zip
Auto merge of #125518 - saethlin:check-arguments-new-in-const, r=joboet
Move the checks for Arguments constructors to inline const

Thanks `@Skgland` for pointing out this opportunity: https://github.com/rust-lang/rust/pull/117804#discussion_r1612964362
-rw-r--r--library/core/src/fmt/mod.rs18
-rw-r--r--tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff130
-rw-r--r--tests/pretty/issue-4264.pp2
-rw-r--r--tests/run-make/symbol-mangling-hashed/Makefile4
-rw-r--r--tests/ui/consts/const-eval/format.rs4
-rw-r--r--tests/ui/consts/const-eval/format.stderr4
6 files changed, 75 insertions, 87 deletions
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 1324fb6e056..c25bc5a1b13 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -338,23 +338,19 @@ pub struct Arguments<'a> {
 impl<'a> Arguments<'a> {
     #[inline]
     #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
-    pub const fn new_const(pieces: &'a [&'static str]) -> Self {
-        if pieces.len() > 1 {
-            // Since panic!() expands to panic_fmt(format_args!()), using panic! here is both a
-            // bit silly and also significantly increases the amount of MIR generated by panics.
-            crate::panicking::panic_nounwind("invalid args");
-        }
+    pub const fn new_const<const N: usize>(pieces: &'a [&'static str; N]) -> Self {
+        const { assert!(N <= 1) };
         Arguments { pieces, fmt: None, args: &[] }
     }
 
     /// When using the format_args!() macro, this function is used to generate the
     /// Arguments structure.
     #[inline]
-    pub fn new_v1(pieces: &'a [&'static str], args: &'a [rt::Argument<'a>]) -> Arguments<'a> {
-        if pieces.len() < args.len() || pieces.len() > args.len() + 1 {
-            // See Arguments::new_const for why we don't use panic!.
-            crate::panicking::panic_nounwind("invalid args");
-        }
+    pub fn new_v1<const P: usize, const A: usize>(
+        pieces: &'a [&'static str; P],
+        args: &'a [rt::Argument<'a>; A],
+    ) -> Arguments<'a> {
+        const { assert!(P >= A && P <= A + 1, "invalid args") }
         Arguments { pieces, fmt: None, args }
     }
 
diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff
index 0d518f78f6b..819f3f86d14 100644
--- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff
+++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff
@@ -11,30 +11,28 @@
       let _9: ();
       let _10: ();
       let mut _11: std::fmt::Arguments<'_>;
-      let mut _12: &[&str];
-      let mut _13: &[&str; 3];
-      let _14: &[&str; 3];
-      let _15: [&str; 3];
-      let mut _16: &[core::fmt::rt::Argument<'_>];
-      let mut _17: &[core::fmt::rt::Argument<'_>; 2];
-      let _18: &[core::fmt::rt::Argument<'_>; 2];
-      let _19: [core::fmt::rt::Argument<'_>; 2];
-      let mut _20: core::fmt::rt::Argument<'_>;
-      let mut _21: &std::boxed::Box<dyn std::fmt::Display>;
-      let _22: &std::boxed::Box<dyn std::fmt::Display>;
-      let mut _23: core::fmt::rt::Argument<'_>;
-      let mut _24: &u32;
-      let _25: &u32;
-      let mut _27: bool;
+      let mut _12: &[&str; 3];
+      let _13: &[&str; 3];
+      let _14: [&str; 3];
+      let mut _15: &[core::fmt::rt::Argument<'_>; 2];
+      let _16: &[core::fmt::rt::Argument<'_>; 2];
+      let _17: [core::fmt::rt::Argument<'_>; 2];
+      let mut _18: core::fmt::rt::Argument<'_>;
+      let mut _19: &std::boxed::Box<dyn std::fmt::Display>;
+      let _20: &std::boxed::Box<dyn std::fmt::Display>;
+      let mut _21: core::fmt::rt::Argument<'_>;
+      let mut _22: &u32;
+      let _23: &u32;
+      let mut _25: bool;
+      let mut _26: isize;
+      let mut _27: isize;
       let mut _28: isize;
-      let mut _29: isize;
-      let mut _30: isize;
-+     let _31: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>;
-+     let _32: u32;
++     let _29: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>;
++     let _30: u32;
       scope 1 {
 -         debug foo => _1;
-+         debug ((foo: Foo<T>).0: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>) => _31;
-+         debug ((foo: Foo<T>).1: u32) => _32;
++         debug ((foo: Foo<T>).0: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>) => _29;
++         debug ((foo: Foo<T>).1: u32) => _30;
           let _5: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>;
           scope 2 {
               debug x => _5;
@@ -44,17 +42,17 @@
                   scope 4 {
                       debug x => _8;
                       let _8: std::boxed::Box<dyn std::fmt::Display>;
-                      let mut _26: &[&str; 3];
+                      let mut _24: &[&str; 3];
                   }
               }
           }
       }
   
       bb0: {
-          _27 = const false;
+          _25 = const false;
 -         StorageLive(_1);
-+         StorageLive(_31);
-+         StorageLive(_32);
++         StorageLive(_29);
++         StorageLive(_30);
 +         nop;
           StorageLive(_2);
           StorageLive(_3);
@@ -68,83 +66,77 @@
           _2 = Result::<Box<dyn std::fmt::Display>, <T as Err>::Err>::Ok(move _3);
           StorageDead(_3);
 -         _1 = Foo::<T> { x: move _2, y: const 7_u32 };
-+         _31 = move _2;
-+         _32 = const 7_u32;
++         _29 = move _2;
++         _30 = const 7_u32;
 +         nop;
           StorageDead(_2);
           StorageLive(_5);
-          _27 = const true;
+          _25 = const true;
 -         _5 = move (_1.0: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>);
-+         _5 = move _31;
++         _5 = move _29;
           StorageLive(_6);
 -         _6 = (_1.1: u32);
-+         _6 = _32;
++         _6 = _30;
           _7 = discriminant(_5);
           switchInt(move _7) -> [0: bb2, otherwise: bb7];
       }
   
       bb2: {
           StorageLive(_8);
-          _27 = const false;
+          _25 = const false;
           _8 = move ((_5 as Ok).0: std::boxed::Box<dyn std::fmt::Display>);
           StorageLive(_9);
           StorageLive(_10);
           StorageLive(_11);
           StorageLive(_12);
           StorageLive(_13);
-          StorageLive(_14);
-          _26 = const foo::<T>::promoted[0];
-          _14 = &(*_26);
-          _13 = &(*_14);
-          _12 = move _13 as &[&str] (PointerCoercion(Unsize));
-          StorageDead(_13);
+          _24 = const foo::<T>::promoted[0];
+          _13 = &(*_24);
+          _12 = &(*_13);
+          StorageLive(_15);
           StorageLive(_16);
           StorageLive(_17);
           StorageLive(_18);
           StorageLive(_19);
           StorageLive(_20);
-          StorageLive(_21);
-          StorageLive(_22);
-          _22 = &_8;
-          _21 = &(*_22);
-          _20 = core::fmt::rt::Argument::<'_>::new_display::<Box<dyn std::fmt::Display>>(move _21) -> [return: bb3, unwind unreachable];
+          _20 = &_8;
+          _19 = &(*_20);
+          _18 = core::fmt::rt::Argument::<'_>::new_display::<Box<dyn std::fmt::Display>>(move _19) -> [return: bb3, unwind unreachable];
       }
   
       bb3: {
-          StorageDead(_21);
+          StorageDead(_19);
+          StorageLive(_21);
+          StorageLive(_22);
           StorageLive(_23);
-          StorageLive(_24);
-          StorageLive(_25);
-          _25 = &_6;
-          _24 = &(*_25);
-          _23 = core::fmt::rt::Argument::<'_>::new_display::<u32>(move _24) -> [return: bb4, unwind unreachable];
+          _23 = &_6;
+          _22 = &(*_23);
+          _21 = core::fmt::rt::Argument::<'_>::new_display::<u32>(move _22) -> [return: bb4, unwind unreachable];
       }
   
       bb4: {
-          StorageDead(_24);
-          _19 = [move _20, move _23];
-          StorageDead(_23);
-          StorageDead(_20);
-          _18 = &_19;
-          _17 = &(*_18);
-          _16 = move _17 as &[core::fmt::rt::Argument<'_>] (PointerCoercion(Unsize));
-          StorageDead(_17);
-          _11 = Arguments::<'_>::new_v1(move _12, move _16) -> [return: bb5, unwind unreachable];
+          StorageDead(_22);
+          _17 = [move _18, move _21];
+          StorageDead(_21);
+          StorageDead(_18);
+          _16 = &_17;
+          _15 = &(*_16);
+          _11 = Arguments::<'_>::new_v1::<3, 2>(move _12, move _15) -> [return: bb5, unwind unreachable];
       }
   
       bb5: {
-          StorageDead(_16);
+          StorageDead(_15);
           StorageDead(_12);
           _10 = _eprint(move _11) -> [return: bb6, unwind unreachable];
       }
   
       bb6: {
           StorageDead(_11);
-          StorageDead(_25);
-          StorageDead(_22);
-          StorageDead(_19);
-          StorageDead(_18);
-          StorageDead(_14);
+          StorageDead(_23);
+          StorageDead(_20);
+          StorageDead(_17);
+          StorageDead(_16);
+          StorageDead(_13);
           StorageDead(_10);
           _9 = const ();
           StorageDead(_9);
@@ -164,22 +156,22 @@
   
       bb9: {
           StorageDead(_6);
-          _28 = discriminant(_5);
-          switchInt(move _28) -> [0: bb11, otherwise: bb13];
+          _26 = discriminant(_5);
+          switchInt(move _26) -> [0: bb11, otherwise: bb13];
       }
   
       bb10: {
-          _27 = const false;
+          _25 = const false;
           StorageDead(_5);
 -         StorageDead(_1);
-+         StorageDead(_31);
-+         StorageDead(_32);
++         StorageDead(_29);
++         StorageDead(_30);
 +         nop;
           return;
       }
   
       bb11: {
-          switchInt(_27) -> [0: bb10, otherwise: bb12];
+          switchInt(_25) -> [0: bb10, otherwise: bb12];
       }
   
       bb12: {
diff --git a/tests/pretty/issue-4264.pp b/tests/pretty/issue-4264.pp
index 4d43db5716e..018ccf82dae 100644
--- a/tests/pretty/issue-4264.pp
+++ b/tests/pretty/issue-4264.pp
@@ -34,7 +34,7 @@ fn bar() ({
             ((::alloc::fmt::format as
                     for<'a> fn(Arguments<'a>) -> String {format})(((format_arguments::new_const
                         as
-                        fn(&[&'static str]) -> Arguments<'_> {Arguments::<'_>::new_const})((&([("test"
+                        fn(&[&'static str; 1]) -> Arguments<'_> {Arguments::<'_>::new_const::<1>})((&([("test"
                                     as &str)] as [&str; 1]) as &[&str; 1])) as Arguments<'_>))
                 as String);
         (res as String)
diff --git a/tests/run-make/symbol-mangling-hashed/Makefile b/tests/run-make/symbol-mangling-hashed/Makefile
index 68894b2192a..c95036ead95 100644
--- a/tests/run-make/symbol-mangling-hashed/Makefile
+++ b/tests/run-make/symbol-mangling-hashed/Makefile
@@ -35,10 +35,10 @@ all:
     # Check hashed symbol name
 
 	[ "$$($(NM) $(TMPDIR)/$(DYLIB_NAME) | grep -c hello)" -eq "0" ]
-	[ "$$($(NM) $(TMPDIR)/$(DYLIB_NAME) | grep _RNxC7a_dylib | grep -c ' T ')" -eq "1" ]
+	[ "$$($(NM) $(TMPDIR)/$(DYLIB_NAME) | grep _RNxC7a_dylib | grep -c ' T ')" -eq "2" ]
 
 	[ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep b_dylib | grep -c hello)" -eq "1" ]
-	[ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep _RNxC6a_rlib | grep -c ' T ')" -eq "1" ]
+	[ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep _RNxC6a_rlib | grep -c ' T ')" -eq "2" ]
 	[ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep _RNxC7a_dylib | grep -c ' U ')" -eq "1" ]
 
 	[ "$$($(NM) $(TMPDIR)/$(BIN_NAME) | grep _RNxC6a_rlib | grep -c ' U ')" -eq "1" ]
diff --git a/tests/ui/consts/const-eval/format.rs b/tests/ui/consts/const-eval/format.rs
index 5bdb2bf1954..b12df824a33 100644
--- a/tests/ui/consts/const-eval/format.rs
+++ b/tests/ui/consts/const-eval/format.rs
@@ -1,13 +1,13 @@
 const fn failure() {
     panic!("{:?}", 0);
     //~^ ERROR cannot call non-const formatting macro in constant functions
-    //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions
+    //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1::<1, 1>` in constant functions
 }
 
 const fn print() {
     println!("{:?}", 0);
     //~^ ERROR cannot call non-const formatting macro in constant functions
-    //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions
+    //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1::<2, 1>` in constant functions
     //~| ERROR cannot call non-const fn `_print` in constant functions
 }
 
diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr
index 434b0744304..ce3f9f2190e 100644
--- a/tests/ui/consts/const-eval/format.stderr
+++ b/tests/ui/consts/const-eval/format.stderr
@@ -7,7 +7,7 @@ LL |     panic!("{:?}", 0);
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
    = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions
+error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1::<1, 1>` in constant functions
   --> $DIR/format.rs:2:5
    |
 LL |     panic!("{:?}", 0);
@@ -25,7 +25,7 @@ LL |     println!("{:?}", 0);
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions
+error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1::<2, 1>` in constant functions
   --> $DIR/format.rs:8:5
    |
 LL |     println!("{:?}", 0);