]> git.lizzy.rs Git - rust.git/blob - tests/compiletest.rs
Save a created event for zero-size reborrows
[rust.git] / tests / compiletest.rs
1 use colored::*;
2 use regex::Regex;
3 use std::env;
4 use std::path::PathBuf;
5 use ui_test::{Config, Mode, OutputConflictHandling};
6
7 fn miri_path() -> PathBuf {
8     PathBuf::from(option_env!("MIRI").unwrap_or(env!("CARGO_BIN_EXE_miri")))
9 }
10
11 fn run_tests(mode: Mode, path: &str, target: Option<String>) {
12     let in_rustc_test_suite = option_env!("RUSTC_STAGE").is_some();
13
14     // Add some flags we always want.
15     let mut flags = Vec::new();
16     flags.push("--edition".to_owned());
17     flags.push("2018".to_owned());
18     if in_rustc_test_suite {
19         // Less aggressive warnings to make the rustc toolstate management less painful.
20         // (We often get warnings when e.g. a feature gets stabilized or some lint gets added/improved.)
21         flags.push("-Astable-features".to_owned());
22     } else {
23         flags.push("-Dwarnings".to_owned());
24         flags.push("-Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
25     }
26     if let Ok(sysroot) = env::var("MIRI_SYSROOT") {
27         flags.push("--sysroot".to_string());
28         flags.push(sysroot);
29     }
30     if let Ok(extra_flags) = env::var("MIRIFLAGS") {
31         for flag in extra_flags.split_whitespace() {
32             flags.push(flag.to_string());
33         }
34     }
35     flags.push("-Zui-testing".to_string());
36     if let Some(target) = &target {
37         flags.push("--target".to_string());
38         flags.push(target.clone());
39     }
40
41     let skip_ui_checks = in_rustc_test_suite || env::var_os("MIRI_SKIP_UI_CHECKS").is_some();
42
43     let output_conflict_handling = match (env::var_os("MIRI_BLESS").is_some(), skip_ui_checks) {
44         (false, false) => OutputConflictHandling::Error,
45         (true, false) => OutputConflictHandling::Bless,
46         (false, true) => OutputConflictHandling::Ignore,
47         (true, true) => panic!("cannot use MIRI_BLESS and MIRI_SKIP_UI_CHECKS at the same time"),
48     };
49
50     let config = Config {
51         args: flags,
52         target,
53         stderr_filters: STDERR.clone(),
54         stdout_filters: STDOUT.clone(),
55         root_dir: PathBuf::from(path),
56         mode,
57         program: miri_path(),
58         output_conflict_handling,
59     };
60     ui_test::run_tests(config)
61 }
62
63 macro_rules! regexes {
64     ($name:ident: $($regex:expr => $replacement:expr,)*) => {lazy_static::lazy_static! {
65         static ref $name: Vec<(Regex, &'static str)> = vec![
66             $((Regex::new($regex).unwrap(), $replacement),)*
67         ];
68     }};
69 }
70
71 regexes! {
72     STDOUT:
73     // Windows file paths
74     r"\\"                           => "/",
75 }
76
77 regexes! {
78     STDERR:
79     // erase line and column info
80     r"\.rs:[0-9]+:[0-9]+"            => ".rs:LL:CC",
81     // erase alloc ids
82     "alloc[0-9]+"                    => "ALLOC",
83     // erase Stacked Borrows tags
84     "<[0-9]+>"                       => "<TAG>",
85     // erase whitespace that differs between platforms
86     r" +at (.*\.rs)"                 => " at $1",
87     // erase generics in backtraces
88     "([0-9]+: .*)::<.*>"             => "$1",
89     // erase addresses in backtraces
90     "([0-9]+: ) +0x[0-9a-f]+ - (.*)" => "$1$2",
91     // erase long hexadecimals
92     r"0x[0-9a-fA-F]+[0-9a-fA-F]{2,2}" => "$$HEX",
93     // erase clocks
94     r"VClock\(\[[^\]]+\]\)"      => "VClock",
95     // erase specific alignments
96     "alignment [0-9]+"               => "alignment ALIGN",
97     // erase thread caller ids
98     r"\(call [0-9]+\)"              => "(call ID)",
99     // erase platform module paths
100     "sys::[a-z]+::"                  => "sys::PLATFORM::",
101     // Windows file paths
102     r"\\"                           => "/",
103     // erase platform file paths
104     "sys/[a-z]+/"                    => "sys/PLATFORM/",
105     // erase error annotations in tests
106     r"\s*//~.*"                      => "",
107 }
108
109 fn ui(mode: Mode, path: &str) {
110     let target = get_target();
111
112     let msg = format!(
113         "## Running ui tests in {path} against miri for {}",
114         target.as_deref().unwrap_or("host")
115     );
116     eprintln!("{}", msg.green().bold());
117
118     run_tests(mode, path, target);
119 }
120
121 fn get_target() -> Option<String> {
122     env::var("MIRI_TEST_TARGET").ok()
123 }
124
125 fn main() {
126     // Add a test env var to do environment communication tests.
127     env::set_var("MIRI_ENV_VAR_TEST", "0");
128     // Let the tests know where to store temp files (they might run for a different target, which can make this hard to find).
129     env::set_var("MIRI_TEMP", env::temp_dir());
130
131     ui(Mode::Pass, "tests/run-pass");
132     ui(Mode::Panic, "tests/run-fail");
133     ui(Mode::Fail, "tests/compile-fail");
134 }