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