aboutsummaryrefslogtreecommitdiff
path: root/tests/compiletest/mod.rs
blob: f4e26c13931524639f98a33f66ff7c977979fa63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use std::fs;
use std::process::Command;
use std::sync::Once;

pub fn setup() {
    static BUILD: Once = Once::new();
    BUILD.call_once(|| {
        let status = Command::new("cargo")
            .arg("build")
            .status()
            .expect("failed to build");
        assert!(status.success());
    });
}

pub fn contains_panic(name: &str, code: &str) -> bool {
    let tempdir = tempfile::tempdir().unwrap();

    let prelude = stringify! {
        use no_panic::no_panic;
    };

    let rs = tempdir.path().join(format!("{}.rs", name));
    fs::write(&rs, format!("{}{}", prelude, code)).unwrap();

    let status = Command::new("rustc")
        .arg("--crate-name")
        .arg(name)
        .arg(rs)
        .arg("--edition=2018")
        .arg("-C")
        .arg("opt-level=3")
        .arg("--emit=asm")
        .arg("--out-dir")
        .arg(tempdir.path())
        .arg("--extern")
        .arg("no_panic=target/debug/libno_panic.so")
        .status()
        .expect("failed to execute rustc");
    assert!(status.success());

    let asm = tempdir.path().join(format!("{}.s", name));
    let asm = fs::read_to_string(asm).unwrap();
    asm.contains("detected panic in function")
}

macro_rules! assert_no_panic {
    ($(mod $name:ident { $($content:tt)* })*) => {
        mod no_panic {
            use crate::compiletest;
            $(
                #[test]
                fn $name() {
                    compiletest::setup();
                    let name = stringify!($name);
                    let content = stringify!($($content)*);
                    assert!(!compiletest::contains_panic(name, content));
                }
            )*
        }
    };
}

macro_rules! assert_link_error {
    ($(mod $name:ident { $($content:tt)* })*) => {
        mod link_error {
            use crate::compiletest;
            $(
                #[test]
                fn $name() {
                    compiletest::setup();
                    let name = stringify!($name);
                    let content = stringify!($($content)*);
                    assert!(compiletest::contains_panic(name, content));
                }
            )*
        }
    };
}