• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::fs;
2 use std::io;
3 use std::process::Command;
4 use std::sync::Once;
5 
setup()6 pub fn setup() {
7     static BUILD: Once = Once::new();
8     BUILD.call_once(|| {
9         let status = Command::new("cargo")
10             .arg("build")
11             .status()
12             .expect("failed to build");
13         assert!(status.success());
14     });
15 }
16 
contains_panic(name: &str, code: &str) -> bool17 pub fn contains_panic(name: &str, code: &str) -> bool {
18     let tempdir = scratch::path("no-panic").join(name);
19     match fs::create_dir(&tempdir) {
20         Ok(()) => {}
21         Err(err) if err.kind() == io::ErrorKind::AlreadyExists => {}
22         err @ Err(_) => err.unwrap(),
23     }
24 
25     let prelude = stringify! {
26         use no_panic::no_panic;
27     };
28 
29     let rs = tempdir.join(format!("{}.rs", name));
30     fs::write(&rs, format!("{}{}", prelude, code)).unwrap();
31 
32     let status = Command::new("rustc")
33         .arg("--crate-name")
34         .arg(name)
35         .arg(rs)
36         .arg("--edition=2018")
37         .arg("-C")
38         .arg("opt-level=3")
39         .arg("--emit=asm")
40         .arg("--out-dir")
41         .arg(&tempdir)
42         .arg("--extern")
43         .arg(format!(
44             "no_panic=target/debug/{prefix}no_panic.{extension}",
45             prefix = std::env::consts::DLL_PREFIX,
46             extension = std::env::consts::DLL_EXTENSION,
47         ))
48         .arg("-D")
49         .arg("warnings")
50         .status()
51         .expect("failed to execute rustc");
52     assert!(status.success());
53 
54     let asm = tempdir.join(format!("{}.s", name));
55     let asm = fs::read_to_string(asm).unwrap();
56     asm.contains("detected panic in function")
57 }
58 
59 macro_rules! assert_no_panic {
60     ($(mod $name:ident { $($content:tt)* })*) => {
61         mod no_panic {
62             use crate::compiletest;
63             $(
64                 #[test]
65                 fn $name() {
66                     compiletest::setup();
67                     let name = stringify!($name);
68                     let content = stringify!($($content)*);
69                     assert!(!compiletest::contains_panic(name, content));
70                 }
71             )*
72         }
73     };
74 }
75 
76 macro_rules! assert_link_error {
77     ($(mod $name:ident { $($content:tt)* })*) => {
78         mod link_error {
79             use crate::compiletest;
80             $(
81                 #[test]
82                 fn $name() {
83                     compiletest::setup();
84                     let name = stringify!($name);
85                     let content = stringify!($($content)*);
86                     assert!(compiletest::contains_panic(name, content));
87                 }
88             )*
89         }
90     };
91 }
92