]> git.lizzy.rs Git - rust.git/blob - src/tools/compiletest/src/common.rs
Auto merge of #79445 - SNCPlay42:struct-tail-recursion-limit, r=oli-obk
[rust.git] / src / tools / compiletest / src / common.rs
1 pub use self::Mode::*;
2
3 use std::ffi::OsString;
4 use std::fmt;
5 use std::path::{Path, PathBuf};
6 use std::str::FromStr;
7
8 use crate::util::PathBufExt;
9 use test::ColorConfig;
10
11 #[derive(Clone, Copy, PartialEq, Debug)]
12 pub enum Mode {
13     CompileFail,
14     RunFail,
15     RunPassValgrind,
16     Pretty,
17     DebugInfo,
18     Codegen,
19     Rustdoc,
20     RustdocJson,
21     CodegenUnits,
22     Incremental,
23     RunMake,
24     Ui,
25     JsDocTest,
26     MirOpt,
27     Assembly,
28 }
29
30 impl Mode {
31     pub fn disambiguator(self) -> &'static str {
32         // Pretty-printing tests could run concurrently, and if they do,
33         // they need to keep their output segregated.
34         match self {
35             Pretty => ".pretty",
36             _ => "",
37         }
38     }
39 }
40
41 impl FromStr for Mode {
42     type Err = ();
43     fn from_str(s: &str) -> Result<Mode, ()> {
44         match s {
45             "compile-fail" => Ok(CompileFail),
46             "run-fail" => Ok(RunFail),
47             "run-pass-valgrind" => Ok(RunPassValgrind),
48             "pretty" => Ok(Pretty),
49             "debuginfo" => Ok(DebugInfo),
50             "codegen" => Ok(Codegen),
51             "rustdoc" => Ok(Rustdoc),
52             "rustdoc-json" => Ok(RustdocJson),
53             "codegen-units" => Ok(CodegenUnits),
54             "incremental" => Ok(Incremental),
55             "run-make" => Ok(RunMake),
56             "ui" => Ok(Ui),
57             "js-doc-test" => Ok(JsDocTest),
58             "mir-opt" => Ok(MirOpt),
59             "assembly" => Ok(Assembly),
60             _ => Err(()),
61         }
62     }
63 }
64
65 impl fmt::Display for Mode {
66     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67         let s = match *self {
68             CompileFail => "compile-fail",
69             RunFail => "run-fail",
70             RunPassValgrind => "run-pass-valgrind",
71             Pretty => "pretty",
72             DebugInfo => "debuginfo",
73             Codegen => "codegen",
74             Rustdoc => "rustdoc",
75             RustdocJson => "rustdoc-json",
76             CodegenUnits => "codegen-units",
77             Incremental => "incremental",
78             RunMake => "run-make",
79             Ui => "ui",
80             JsDocTest => "js-doc-test",
81             MirOpt => "mir-opt",
82             Assembly => "assembly",
83         };
84         fmt::Display::fmt(s, f)
85     }
86 }
87
88 #[derive(Clone, Copy, PartialEq, Debug, Hash)]
89 pub enum PassMode {
90     Check,
91     Build,
92     Run,
93 }
94
95 impl FromStr for PassMode {
96     type Err = ();
97     fn from_str(s: &str) -> Result<Self, ()> {
98         match s {
99             "check" => Ok(PassMode::Check),
100             "build" => Ok(PassMode::Build),
101             "run" => Ok(PassMode::Run),
102             _ => Err(()),
103         }
104     }
105 }
106
107 impl fmt::Display for PassMode {
108     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109         let s = match *self {
110             PassMode::Check => "check",
111             PassMode::Build => "build",
112             PassMode::Run => "run",
113         };
114         fmt::Display::fmt(s, f)
115     }
116 }
117
118 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
119 pub enum FailMode {
120     Check,
121     Build,
122     Run,
123 }
124
125 #[derive(Clone, Debug, PartialEq)]
126 pub enum CompareMode {
127     Nll,
128     Polonius,
129     Chalk,
130 }
131
132 impl CompareMode {
133     pub(crate) fn to_str(&self) -> &'static str {
134         match *self {
135             CompareMode::Nll => "nll",
136             CompareMode::Polonius => "polonius",
137             CompareMode::Chalk => "chalk",
138         }
139     }
140
141     pub fn parse(s: String) -> CompareMode {
142         match s.as_str() {
143             "nll" => CompareMode::Nll,
144             "polonius" => CompareMode::Polonius,
145             "chalk" => CompareMode::Chalk,
146             x => panic!("unknown --compare-mode option: {}", x),
147         }
148     }
149 }
150
151 #[derive(Clone, Copy, Debug, PartialEq)]
152 pub enum Debugger {
153     Cdb,
154     Gdb,
155     Lldb,
156 }
157
158 impl Debugger {
159     fn to_str(&self) -> &'static str {
160         match self {
161             Debugger::Cdb => "cdb",
162             Debugger::Gdb => "gdb",
163             Debugger::Lldb => "lldb",
164         }
165     }
166 }
167
168 impl fmt::Display for Debugger {
169     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170         fmt::Display::fmt(self.to_str(), f)
171     }
172 }
173
174 /// Configuration for compiletest
175 #[derive(Debug, Clone)]
176 pub struct Config {
177     /// `true` to to overwrite stderr/stdout files instead of complaining about changes in output.
178     pub bless: bool,
179
180     /// The library paths required for running the compiler.
181     pub compile_lib_path: PathBuf,
182
183     /// The library paths required for running compiled programs.
184     pub run_lib_path: PathBuf,
185
186     /// The rustc executable.
187     pub rustc_path: PathBuf,
188
189     /// The rustdoc executable.
190     pub rustdoc_path: Option<PathBuf>,
191
192     /// The rust-demangler executable.
193     pub rust_demangler_path: Option<PathBuf>,
194
195     /// The Python executable to use for LLDB.
196     pub lldb_python: String,
197
198     /// The Python executable to use for htmldocck.
199     pub docck_python: String,
200
201     /// The LLVM `FileCheck` binary path.
202     pub llvm_filecheck: Option<PathBuf>,
203
204     /// Path to LLVM's bin directory.
205     pub llvm_bin_dir: Option<PathBuf>,
206
207     /// The valgrind path.
208     pub valgrind_path: Option<String>,
209
210     /// Whether to fail if we can't run run-pass-valgrind tests under valgrind
211     /// (or, alternatively, to silently run them like regular run-pass tests).
212     pub force_valgrind: bool,
213
214     /// The path to the Clang executable to run Clang-based tests with. If
215     /// `None` then these tests will be ignored.
216     pub run_clang_based_tests_with: Option<String>,
217
218     /// The directory containing the tests to run
219     pub src_base: PathBuf,
220
221     /// The directory where programs should be built
222     pub build_base: PathBuf,
223
224     /// The name of the stage being built (stage1, etc)
225     pub stage_id: String,
226
227     /// The test mode, compile-fail, run-fail, ui
228     pub mode: Mode,
229
230     /// The test suite (essentially which directory is running, but without the
231     /// directory prefix such as src/test)
232     pub suite: String,
233
234     /// The debugger to use in debuginfo mode. Unset otherwise.
235     pub debugger: Option<Debugger>,
236
237     /// Run ignored tests
238     pub run_ignored: bool,
239
240     /// Only run tests that match this filter
241     pub filter: Option<String>,
242
243     /// Exactly match the filter, rather than a substring
244     pub filter_exact: bool,
245
246     /// Force the pass mode of a check/build/run-pass test to this mode.
247     pub force_pass_mode: Option<PassMode>,
248
249     /// Write out a parseable log of tests that were run
250     pub logfile: Option<PathBuf>,
251
252     /// A command line to prefix program execution with,
253     /// for running under valgrind
254     pub runtool: Option<String>,
255
256     /// Flags to pass to the compiler when building for the host
257     pub host_rustcflags: Option<String>,
258
259     /// Flags to pass to the compiler when building for the target
260     pub target_rustcflags: Option<String>,
261
262     /// Target system to be tested
263     pub target: String,
264
265     /// Host triple for the compiler being invoked
266     pub host: String,
267
268     /// Path to / name of the Microsoft Console Debugger (CDB) executable
269     pub cdb: Option<OsString>,
270
271     /// Version of CDB
272     pub cdb_version: Option<[u16; 4]>,
273
274     /// Path to / name of the GDB executable
275     pub gdb: Option<String>,
276
277     /// Version of GDB, encoded as ((major * 1000) + minor) * 1000 + patch
278     pub gdb_version: Option<u32>,
279
280     /// Whether GDB has native rust support
281     pub gdb_native_rust: bool,
282
283     /// Version of LLDB
284     pub lldb_version: Option<u32>,
285
286     /// Whether LLDB has native rust support
287     pub lldb_native_rust: bool,
288
289     /// Version of LLVM
290     pub llvm_version: Option<u32>,
291
292     /// Is LLVM a system LLVM
293     pub system_llvm: bool,
294
295     /// Path to the android tools
296     pub android_cross_path: PathBuf,
297
298     /// Extra parameter to run adb on arm-linux-androideabi
299     pub adb_path: String,
300
301     /// Extra parameter to run test suite on arm-linux-androideabi
302     pub adb_test_dir: String,
303
304     /// status whether android device available or not
305     pub adb_device_status: bool,
306
307     /// the path containing LLDB's Python module
308     pub lldb_python_dir: Option<String>,
309
310     /// Explain what's going on
311     pub verbose: bool,
312
313     /// Print one character per test instead of one line
314     pub quiet: bool,
315
316     /// Whether to use colors in test.
317     pub color: ColorConfig,
318
319     /// where to find the remote test client process, if we're using it
320     pub remote_test_client: Option<PathBuf>,
321
322     /// mode describing what file the actual ui output will be compared to
323     pub compare_mode: Option<CompareMode>,
324
325     /// If true, this will generate a coverage file with UI test files that run `MachineApplicable`
326     /// diagnostics but are missing `run-rustfix` annotations. The generated coverage file is
327     /// created in `/<build_base>/rustfix_missing_coverage.txt`
328     pub rustfix_coverage: bool,
329
330     // Configuration for various run-make tests frobbing things like C compilers
331     // or querying about various LLVM component information.
332     pub cc: String,
333     pub cxx: String,
334     pub cflags: String,
335     pub ar: String,
336     pub linker: Option<String>,
337     pub llvm_components: String,
338
339     /// Path to a NodeJS executable. Used for JS doctests, emscripten and WASM tests
340     pub nodejs: Option<String>,
341 }
342
343 #[derive(Debug, Clone)]
344 pub struct TestPaths {
345     pub file: PathBuf,         // e.g., compile-test/foo/bar/baz.rs
346     pub relative_dir: PathBuf, // e.g., foo/bar
347 }
348
349 /// Used by `ui` tests to generate things like `foo.stderr` from `foo.rs`.
350 pub fn expected_output_path(
351     testpaths: &TestPaths,
352     revision: Option<&str>,
353     compare_mode: &Option<CompareMode>,
354     kind: &str,
355 ) -> PathBuf {
356     assert!(UI_EXTENSIONS.contains(&kind));
357     let mut parts = Vec::new();
358
359     if let Some(x) = revision {
360         parts.push(x);
361     }
362     if let Some(ref x) = *compare_mode {
363         parts.push(x.to_str());
364     }
365     parts.push(kind);
366
367     let extension = parts.join(".");
368     testpaths.file.with_extension(extension)
369 }
370
371 pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT];
372 pub const UI_STDERR: &str = "stderr";
373 pub const UI_STDOUT: &str = "stdout";
374 pub const UI_FIXED: &str = "fixed";
375 pub const UI_RUN_STDERR: &str = "run.stderr";
376 pub const UI_RUN_STDOUT: &str = "run.stdout";
377
378 /// Absolute path to the directory where all output for all tests in the given
379 /// `relative_dir` group should reside. Example:
380 ///   /path/to/build/host-triple/test/ui/relative/
381 /// This is created early when tests are collected to avoid race conditions.
382 pub fn output_relative_path(config: &Config, relative_dir: &Path) -> PathBuf {
383     config.build_base.join(relative_dir)
384 }
385
386 /// Generates a unique name for the test, such as `testname.revision.mode`.
387 pub fn output_testname_unique(
388     config: &Config,
389     testpaths: &TestPaths,
390     revision: Option<&str>,
391 ) -> PathBuf {
392     let mode = config.compare_mode.as_ref().map_or("", |m| m.to_str());
393     let debugger = config.debugger.as_ref().map_or("", |m| m.to_str());
394     PathBuf::from(&testpaths.file.file_stem().unwrap())
395         .with_extra_extension(revision.unwrap_or(""))
396         .with_extra_extension(mode)
397         .with_extra_extension(debugger)
398 }
399
400 /// Absolute path to the directory where all output for the given
401 /// test/revision should reside. Example:
402 ///   /path/to/build/host-triple/test/ui/relative/testname.revision.mode/
403 pub fn output_base_dir(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf {
404     output_relative_path(config, &testpaths.relative_dir)
405         .join(output_testname_unique(config, testpaths, revision))
406 }
407
408 /// Absolute path to the base filename used as output for the given
409 /// test/revision. Example:
410 ///   /path/to/build/host-triple/test/ui/relative/testname.revision.mode/testname
411 pub fn output_base_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf {
412     output_base_dir(config, testpaths, revision).join(testpaths.file.file_stem().unwrap())
413 }