about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-06-15 17:43:01 +0000
committerbors <bors@rust-lang.org>2022-06-15 17:43:01 +0000
commitca983054e19afd74d63c3ed37997f3bf30fe85d0 (patch)
tree546b0a775403d50050a89ac8f6b747bffe678094 /src
parentc3605f8c8020dbbe8f0d1961c7b33c4c4b78ad0d (diff)
parent605c64a91e5a748b29224887a63e6220ebac91f9 (diff)
downloadrust-ca983054e19afd74d63c3ed37997f3bf30fe85d0.tar.gz
rust-ca983054e19afd74d63c3ed37997f3bf30fe85d0.zip
Auto merge of #97665 - c410-f3r:assert-compiler, r=oli-obk
[RFC 2011] Minimal initial implementation

Tracking issue: #44838
Third step of #96496

Implementation has ~290 LOC with the bare minimum to be in a functional state. Currently only searches for binary operations to mimic what `assert_eq!` and `assert_ne!` already do.

r? `@oli-obk`
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/macros/assert-trailing-junk.rs3
-rw-r--r--src/test/ui/macros/assert-trailing-junk.with-generic-asset.stderr (renamed from src/test/ui/macros/assert-trailing-junk.stderr)14
-rw-r--r--src/test/ui/macros/assert-trailing-junk.without-generic-asset.stderr54
-rw-r--r--src/test/ui/macros/assert.rs3
-rw-r--r--src/test/ui/macros/assert.with-generic-asset.stderr (renamed from src/test/ui/macros/assert.stderr)8
-rw-r--r--src/test/ui/macros/assert.without-generic-asset.stderr28
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs143
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs43
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs13
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs14
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/auxiliary/common.rs25
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.rs9
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.stdout29
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs8
14 files changed, 379 insertions, 15 deletions
diff --git a/src/test/ui/macros/assert-trailing-junk.rs b/src/test/ui/macros/assert-trailing-junk.rs
index cd7faf9bf8b..da725e19e2a 100644
--- a/src/test/ui/macros/assert-trailing-junk.rs
+++ b/src/test/ui/macros/assert-trailing-junk.rs
@@ -1,3 +1,6 @@
+// revisions: with-generic-asset without-generic-asset
+// [with-generic-asset] compile-flags: --cfg feature="generic_assert"
+
 // Ensure assert macro does not ignore trailing garbage.
 //
 // See https://github.com/rust-lang/rust/issues/60024 for details.
diff --git a/src/test/ui/macros/assert-trailing-junk.stderr b/src/test/ui/macros/assert-trailing-junk.with-generic-asset.stderr
index eb001429c55..09dd16a0b0d 100644
--- a/src/test/ui/macros/assert-trailing-junk.stderr
+++ b/src/test/ui/macros/assert-trailing-junk.with-generic-asset.stderr
@@ -1,17 +1,17 @@
 error: expected one of `,`, `.`, `?`, or an operator, found `some`
-  --> $DIR/assert-trailing-junk.rs:6:18
+  --> $DIR/assert-trailing-junk.rs:9:18
    |
 LL |     assert!(true some extra junk, "whatever");
    |                  ^^^^ expected one of `,`, `.`, `?`, or an operator
 
 error: expected one of `,`, `.`, `?`, or an operator, found `some`
-  --> $DIR/assert-trailing-junk.rs:9:18
+  --> $DIR/assert-trailing-junk.rs:12:18
    |
 LL |     assert!(true some extra junk);
    |                  ^^^^ expected one of `,`, `.`, `?`, or an operator
 
 error: no rules expected the token `blah`
-  --> $DIR/assert-trailing-junk.rs:12:30
+  --> $DIR/assert-trailing-junk.rs:15:30
    |
 LL |     assert!(true, "whatever" blah);
    |                             -^^^^ no rules expected this token in macro call
@@ -19,7 +19,7 @@ LL |     assert!(true, "whatever" blah);
    |                             help: missing comma here
 
 error: unexpected string literal
-  --> $DIR/assert-trailing-junk.rs:15:18
+  --> $DIR/assert-trailing-junk.rs:18:18
    |
 LL |     assert!(true "whatever" blah);
    |                 -^^^^^^^^^^
@@ -27,7 +27,7 @@ LL |     assert!(true "whatever" blah);
    |                 help: try adding a comma
 
 error: no rules expected the token `blah`
-  --> $DIR/assert-trailing-junk.rs:15:29
+  --> $DIR/assert-trailing-junk.rs:18:29
    |
 LL |     assert!(true "whatever" blah);
    |                            -^^^^ no rules expected this token in macro call
@@ -35,7 +35,7 @@ LL |     assert!(true "whatever" blah);
    |                            help: missing comma here
 
 error: macro requires an expression as an argument
-  --> $DIR/assert-trailing-junk.rs:19:5
+  --> $DIR/assert-trailing-junk.rs:22:5
    |
 LL |     assert!(true;);
    |     ^^^^^^^^^^^^-^
@@ -43,7 +43,7 @@ LL |     assert!(true;);
    |                 help: try removing semicolon
 
 error: unexpected string literal
-  --> $DIR/assert-trailing-junk.rs:22:27
+  --> $DIR/assert-trailing-junk.rs:25:27
    |
 LL |     assert!(false || true "error message");
    |                          -^^^^^^^^^^^^^^^
diff --git a/src/test/ui/macros/assert-trailing-junk.without-generic-asset.stderr b/src/test/ui/macros/assert-trailing-junk.without-generic-asset.stderr
new file mode 100644
index 00000000000..09dd16a0b0d
--- /dev/null
+++ b/src/test/ui/macros/assert-trailing-junk.without-generic-asset.stderr
@@ -0,0 +1,54 @@
+error: expected one of `,`, `.`, `?`, or an operator, found `some`
+  --> $DIR/assert-trailing-junk.rs:9:18
+   |
+LL |     assert!(true some extra junk, "whatever");
+   |                  ^^^^ expected one of `,`, `.`, `?`, or an operator
+
+error: expected one of `,`, `.`, `?`, or an operator, found `some`
+  --> $DIR/assert-trailing-junk.rs:12:18
+   |
+LL |     assert!(true some extra junk);
+   |                  ^^^^ expected one of `,`, `.`, `?`, or an operator
+
+error: no rules expected the token `blah`
+  --> $DIR/assert-trailing-junk.rs:15:30
+   |
+LL |     assert!(true, "whatever" blah);
+   |                             -^^^^ no rules expected this token in macro call
+   |                             |
+   |                             help: missing comma here
+
+error: unexpected string literal
+  --> $DIR/assert-trailing-junk.rs:18:18
+   |
+LL |     assert!(true "whatever" blah);
+   |                 -^^^^^^^^^^
+   |                 |
+   |                 help: try adding a comma
+
+error: no rules expected the token `blah`
+  --> $DIR/assert-trailing-junk.rs:18:29
+   |
+LL |     assert!(true "whatever" blah);
+   |                            -^^^^ no rules expected this token in macro call
+   |                            |
+   |                            help: missing comma here
+
+error: macro requires an expression as an argument
+  --> $DIR/assert-trailing-junk.rs:22:5
+   |
+LL |     assert!(true;);
+   |     ^^^^^^^^^^^^-^
+   |                 |
+   |                 help: try removing semicolon
+
+error: unexpected string literal
+  --> $DIR/assert-trailing-junk.rs:25:27
+   |
+LL |     assert!(false || true "error message");
+   |                          -^^^^^^^^^^^^^^^
+   |                          |
+   |                          help: try adding a comma
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/macros/assert.rs b/src/test/ui/macros/assert.rs
index 71b0dbb19e2..a314db907b8 100644
--- a/src/test/ui/macros/assert.rs
+++ b/src/test/ui/macros/assert.rs
@@ -1,3 +1,6 @@
+// revisions: with-generic-asset without-generic-asset
+// [with-generic-asset] compile-flags: --cfg feature="generic_assert"
+
 fn main() {
     assert!();  //~ ERROR requires a boolean expression
     assert!(struct); //~ ERROR expected expression
diff --git a/src/test/ui/macros/assert.stderr b/src/test/ui/macros/assert.with-generic-asset.stderr
index 57e5c77a566..51d8f28a35c 100644
--- a/src/test/ui/macros/assert.stderr
+++ b/src/test/ui/macros/assert.with-generic-asset.stderr
@@ -1,17 +1,17 @@
 error: macro requires a boolean expression as an argument
-  --> $DIR/assert.rs:2:5
+  --> $DIR/assert.rs:5:5
    |
 LL |     assert!();
    |     ^^^^^^^^^ boolean expression required
 
 error: expected expression, found keyword `struct`
-  --> $DIR/assert.rs:3:13
+  --> $DIR/assert.rs:6:13
    |
 LL |     assert!(struct);
    |             ^^^^^^ expected expression
 
 error: macro requires a boolean expression as an argument
-  --> $DIR/assert.rs:4:5
+  --> $DIR/assert.rs:7:5
    |
 LL |     debug_assert!();
    |     ^^^^^^^^^^^^^^^ boolean expression required
@@ -19,7 +19,7 @@ LL |     debug_assert!();
    = note: this error originates in the macro `debug_assert` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected expression, found keyword `struct`
-  --> $DIR/assert.rs:5:19
+  --> $DIR/assert.rs:8:19
    |
 LL |     debug_assert!(struct);
    |                   ^^^^^^ expected expression
diff --git a/src/test/ui/macros/assert.without-generic-asset.stderr b/src/test/ui/macros/assert.without-generic-asset.stderr
new file mode 100644
index 00000000000..51d8f28a35c
--- /dev/null
+++ b/src/test/ui/macros/assert.without-generic-asset.stderr
@@ -0,0 +1,28 @@
+error: macro requires a boolean expression as an argument
+  --> $DIR/assert.rs:5:5
+   |
+LL |     assert!();
+   |     ^^^^^^^^^ boolean expression required
+
+error: expected expression, found keyword `struct`
+  --> $DIR/assert.rs:6:13
+   |
+LL |     assert!(struct);
+   |             ^^^^^^ expected expression
+
+error: macro requires a boolean expression as an argument
+  --> $DIR/assert.rs:7:5
+   |
+LL |     debug_assert!();
+   |     ^^^^^^^^^^^^^^^ boolean expression required
+   |
+   = note: this error originates in the macro `debug_assert` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected expression, found keyword `struct`
+  --> $DIR/assert.rs:8:19
+   |
+LL |     debug_assert!(struct);
+   |                   ^^^^^^ expected expression
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs
new file mode 100644
index 00000000000..c0e9f29fdbc
--- /dev/null
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs
@@ -0,0 +1,143 @@
+// edition:2021
+// ignore-tidy-linelength
+// only-x86_64
+// run-pass
+
+#![allow(path_statements, unused_allocation)]
+#![feature(box_syntax, core_intrinsics, generic_assert, generic_assert_internals)]
+
+macro_rules! test {
+  (
+    let mut $elem_ident:ident = $elem_expr:expr;
+    [ $($assert:tt)* ] => $msg:literal
+  ) => {
+    {
+      #[allow(unused_assignments, unused_mut, unused_variables)]
+      let rslt = std::panic::catch_unwind(|| {
+        let mut $elem_ident = $elem_expr;
+        assert!($($assert)*);
+      });
+      let err = rslt.unwrap_err();
+      if let Some(elem) = err.downcast_ref::<String>() {
+        assert_eq!(elem, &$msg);
+      }
+      else if let Some(elem) = err.downcast_ref::<&str>() {
+        assert_eq!(elem, &$msg);
+      }
+      else {
+        panic!("assert!( ... ) should return a string");
+      }
+    }
+  }
+}
+
+macro_rules! tests {
+  (
+    let mut $elem_ident:ident = $elem_expr:expr;
+
+    $(
+      [ $($elem_assert:tt)* ] => $elem_msg:literal
+    )+
+  ) => {
+    $(
+      test!(
+        let mut $elem_ident = $elem_expr;
+        [ $($elem_assert)* ] => $elem_msg
+      );
+    )+
+  }
+}
+
+const FOO: Foo = Foo { bar: 1 };
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+struct Foo {
+  bar: i32
+}
+
+fn main() {
+  // ***** Allowed *****
+
+  tests!(
+    let mut elem = 1i32;
+
+    // binary
+    [ elem + 1 == 3 ] => "Assertion failed: elem + 1 == 3\nWith captures:\n  elem = 1\n"
+  );
+
+  // ***** Disallowed *****
+
+  tests!(
+    let mut elem = 1i32;
+
+    // assign
+    [ { let local = elem; local } == 3 ] => "Assertion failed: { let local = elem; local } == 3"
+
+    // assign op
+    [ { elem += 1; elem } == 3 ] => "Assertion failed: { elem += 1; elem } == 3"
+
+    // async
+    [ { let _ = async { elem }; elem } == 3 ] => "Assertion failed: { let _ = async { elem }; elem } == 3"
+
+    // await
+
+    // block
+    [ { elem } == 3 ] => "Assertion failed: { elem } == 3"
+
+    // box
+    [ box elem == box 3 ] => "Assertion failed: box elem == box 3"
+
+    // break
+    [ loop { break elem; } ==  3 ] => "Assertion failed: loop { break elem; } == 3"
+
+    // closure
+    [(|| elem)() ==  3 ] => "Assertion failed: (|| elem)() == 3"
+
+    // const block
+
+    // continue
+
+    // err
+
+    // field
+    [ FOO.bar ==  3 ] => "Assertion failed: FOO.bar == 3"
+
+    // for loop
+    [ { for _ in 0..elem { elem; } elem } ==  3 ] => "Assertion failed: { for _ in 0..elem { elem; } elem } == 3"
+
+    // if
+    [ if true { elem } else { elem } == 3 ] => "Assertion failed: if true { elem } else { elem } == 3"
+
+    // inline asm
+
+    // let
+    [ if let true = true { elem } else { elem } == 3 ] => "Assertion failed: if let true = true { elem } else { elem } == 3"
+
+    // lit
+
+    // loop
+    [ loop { elem; break elem; } == 3 ] => "Assertion failed: loop { elem; break elem; } == 3"
+
+    // mac call
+
+    // match
+    [ match elem { _ => elem } == 3 ] => "Assertion failed: match elem { _ => elem, } == 3"
+
+    // ret
+    [ (|| { return elem; })() == 3 ] => "Assertion failed: (|| { return elem; })() == 3"
+
+    // try
+    [ (|| { Some(Some(elem)?) })() == Some(3) ] => "Assertion failed: (|| { Some(Some(elem)?) })() == Some(3)"
+
+    // try block
+
+    // underscore
+
+    // while
+    [ { while false { elem; break; } elem } == 3 ] => "Assertion failed: { while false { elem; break; } elem } == 3"
+
+    // yeet
+
+    // yield
+  );
+}
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs
new file mode 100644
index 00000000000..86697c58fbc
--- /dev/null
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs
@@ -0,0 +1,43 @@
+// aux-build:common.rs
+// ignore-tidy-linelength
+// only-x86_64
+// run-pass
+
+#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
+
+extern crate common;
+
+#[derive(Clone, Copy, PartialEq)]
+struct CopyNoDebug(i32);
+
+#[derive(Debug, PartialEq)]
+struct NoCopyDebug(i32);
+
+#[derive(PartialEq)]
+struct NoCopyNoDebug(i32);
+
+fn main() {
+  // Has Copy but does not have Debug
+  common::test!(
+    let mut copy_no_debug = CopyNoDebug(1);
+    [ copy_no_debug == CopyNoDebug(3) ] => "Assertion failed: copy_no_debug == CopyNoDebug(3)\nWith captures:\n  copy_no_debug = N/A\n"
+  );
+
+  // Does not have Copy but has Debug
+  common::test!(
+    let mut no_copy_debug = NoCopyDebug(1);
+    [ no_copy_debug == NoCopyDebug(3) ] => "Assertion failed: no_copy_debug == NoCopyDebug(3)\nWith captures:\n  no_copy_debug = N/A\n"
+  );
+
+  // Does not have Copy and does not have Debug
+  common::test!(
+    let mut no_copy_no_debug = NoCopyNoDebug(1);
+    [ no_copy_no_debug == NoCopyNoDebug(3) ] => "Assertion failed: no_copy_no_debug == NoCopyNoDebug(3)\nWith captures:\n  no_copy_no_debug = N/A\n"
+  );
+
+  // Unevaluated (Expression short-circuited)
+  common::test!(
+    let mut elem = true;
+    [ false && elem ] => "Assertion failed: false && elem\nWith captures:\n  elem = N/A\n"
+  );
+}
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs
new file mode 100644
index 00000000000..6a1435f792b
--- /dev/null
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs
@@ -0,0 +1,13 @@
+// compile-flags: --test
+// run-pass
+
+#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
+
+#[should_panic(expected = "Custom user message")]
+#[test]
+fn test() {
+  assert!(1 == 3, "Custom user message");
+}
+
+fn main() {
+}
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs
new file mode 100644
index 00000000000..06c4993ec30
--- /dev/null
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs
@@ -0,0 +1,14 @@
+// aux-build:common.rs
+// only-x86_64
+// run-pass
+
+#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
+
+extern crate common;
+
+fn main() {
+  common::test!(
+    let mut _nothing = ();
+    [ 1 == 3 ] => "Assertion failed: 1 == 3"
+  );
+}
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/auxiliary/common.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/auxiliary/common.rs
new file mode 100644
index 00000000000..903ed507c2e
--- /dev/null
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/auxiliary/common.rs
@@ -0,0 +1,25 @@
+#[macro_export]
+macro_rules! test {
+  (
+    let mut $elem_ident:ident = $elem_expr:expr;
+    [ $($assert:tt)* ] => $msg:literal
+  ) => {
+    {
+      #[allow(unused_assignments, unused_mut, unused_variables)]
+      let rslt = std::panic::catch_unwind(|| {
+        let mut $elem_ident = $elem_expr;
+        assert!($($assert)*);
+      });
+      let err = rslt.unwrap_err();
+      if let Some(elem) = err.downcast_ref::<String>() {
+        assert_eq!(elem, &$msg);
+      }
+      else if let Some(elem) = err.downcast_ref::<&str>() {
+        assert_eq!(elem, &$msg);
+      }
+      else {
+        panic!("assert!( ... ) should return a string");
+      }
+    }
+  }
+}
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.rs
new file mode 100644
index 00000000000..1db9d33c72a
--- /dev/null
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.rs
@@ -0,0 +1,9 @@
+// check-pass
+// compile-flags: -Z unpretty=expanded
+
+#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
+
+fn main() {
+    let elem = 1i32;
+    assert!(elem == 1);
+}
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.stdout b/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.stdout
new file mode 100644
index 00000000000..a590eb32232
--- /dev/null
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.stdout
@@ -0,0 +1,29 @@
+#![feature(prelude_import)]
+#![no_std]
+// check-pass
+// compile-flags: -Z unpretty=expanded
+
+#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+fn main() {
+    let elem = 1i32;
+    {
+        #[allow(unused_imports)]
+        use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
+        let mut __capture0 = ::core::asserting::Capture::new();
+        let __local_bind0 = &elem;
+        if !(*{
+                                (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
+                                __local_bind0
+                            } == 1) {
+                {
+                    ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: elem == 1\nWith captures:\n  elem = ",
+                                        "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
+                }
+            }
+    };
+}
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs
index f70ca87e304..01860adaac2 100644
--- a/src/test/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs
@@ -1,8 +1,7 @@
 // compile-flags: --test
+// ignore-tidy-linelength
 // run-pass
 
-// `generic_assert` is completely unimplemented and doesn't generate any logic, thus the
-// reason why this test currently passes
 #![feature(core_intrinsics, generic_assert, generic_assert_internals)]
 
 use std::fmt::{Debug, Formatter};
@@ -16,10 +15,11 @@ impl Debug for CopyDebug {
   }
 }
 
+#[should_panic(expected = "Assertion failed: copy_debug == CopyDebug(3)\nWith captures:\n  copy_debug = With great power comes great electricity bills\n")]
 #[test]
 fn test() {
-  let _copy_debug = CopyDebug(1);
-  assert!(_copy_debug == CopyDebug(3));
+  let copy_debug = CopyDebug(1);
+  assert!(copy_debug == CopyDebug(3));
 }
 
 fn main() {