1 | use super::Error; |
2 | use crate::parser::Comments; |
3 | use crate::parser::MaybeSpanned; |
4 | use crate::Errored; |
5 | use std::fmt::Display; |
6 | use std::process::ExitStatus; |
7 | |
8 | /// When to run rustfix on tests |
9 | #[derive (Copy, Clone, Debug, PartialEq, Eq)] |
10 | pub enum RustfixMode { |
11 | /// Do not run rustfix on the test |
12 | Disabled, |
13 | /// Apply only `MachineApplicable` suggestions emitted by the test |
14 | MachineApplicable, |
15 | /// Apply all suggestions emitted by the test |
16 | Everything, |
17 | } |
18 | |
19 | impl RustfixMode { |
20 | pub(crate) fn enabled(self) -> bool { |
21 | self != RustfixMode::Disabled |
22 | } |
23 | } |
24 | |
25 | #[derive (Copy, Clone, Debug)] |
26 | /// Decides what is expected of each test's exit status. |
27 | pub enum Mode { |
28 | /// The test passes a full execution of the rustc driver |
29 | Pass, |
30 | /// The test produces an executable binary that can get executed on the host |
31 | Run { |
32 | /// The expected exit code |
33 | exit_code: i32, |
34 | }, |
35 | /// The rustc driver panicked |
36 | Panic, |
37 | /// The rustc driver emitted an error |
38 | Fail { |
39 | /// Whether failing tests must have error patterns. Set to false if you just care about .stderr output. |
40 | require_patterns: bool, |
41 | /// When to run rustfix on the test |
42 | rustfix: RustfixMode, |
43 | }, |
44 | /// Run the tests, but always pass them as long as all annotations are satisfied and stderr files match. |
45 | Yolo { |
46 | /// When to run rustfix on the test |
47 | rustfix: RustfixMode, |
48 | }, |
49 | } |
50 | |
51 | impl Mode { |
52 | pub(crate) fn ok(self, status: ExitStatus) -> Result<(), Error> { |
53 | let expected = match self { |
54 | Mode::Run { exit_code } => exit_code, |
55 | Mode::Pass => 0, |
56 | Mode::Panic => 101, |
57 | Mode::Fail { .. } => 1, |
58 | Mode::Yolo { .. } => return Ok(()), |
59 | }; |
60 | if status.code() == Some(expected) { |
61 | Ok(()) |
62 | } else { |
63 | Err(Error::ExitStatus { |
64 | mode: self, |
65 | status, |
66 | expected, |
67 | }) |
68 | } |
69 | } |
70 | pub(crate) fn maybe_override( |
71 | self, |
72 | comments: &Comments, |
73 | revision: &str, |
74 | ) -> Result<MaybeSpanned<Self>, Errored> { |
75 | let mode = comments.find_one_for_revision(revision, "mode changes" , |r| r.mode)?; |
76 | Ok(mode.map_or(MaybeSpanned::new_config(self), Into::into)) |
77 | } |
78 | } |
79 | |
80 | impl Display for Mode { |
81 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
82 | match self { |
83 | Mode::Run { exit_code: &i32 } => write!(f, "run( {exit_code})" ), |
84 | Mode::Pass => write!(f, "pass" ), |
85 | Mode::Panic => write!(f, "panic" ), |
86 | Mode::Fail { |
87 | require_patterns: _, |
88 | rustfix: _, |
89 | } => write!(f, "fail" ), |
90 | Mode::Yolo { rustfix: _ } => write!(f, "yolo" ), |
91 | } |
92 | } |
93 | } |
94 | |