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