hkalbasi_rustc_ap_miropt_test_tools/
lib.rs1use std::fs;
2use std::path::Path;
3
4pub struct MiroptTestFiles {
5 pub expected_file: std::path::PathBuf,
6 pub from_file: String,
7 pub to_file: Option<String>,
8 pub passes: Vec<String>,
10}
11
12pub enum PanicStrategy {
13 Unwind,
14 Abort,
15}
16
17pub fn output_file_suffix(
18 testfile: &Path,
19 bit_width: u32,
20 panic_strategy: PanicStrategy,
21) -> String {
22 let mut each_bit_width = false;
23 let mut each_panic_strategy = false;
24 for line in fs::read_to_string(testfile).unwrap().lines() {
25 if line == "// EMIT_MIR_FOR_EACH_BIT_WIDTH" {
26 each_bit_width = true;
27 }
28 if line == "// EMIT_MIR_FOR_EACH_PANIC_STRATEGY" {
29 each_panic_strategy = true;
30 }
31 }
32
33 let mut suffix = String::new();
34 if each_bit_width {
35 suffix.push_str(&format!(".{}bit", bit_width));
36 }
37 if each_panic_strategy {
38 match panic_strategy {
39 PanicStrategy::Unwind => suffix.push_str(".panic-unwind"),
40 PanicStrategy::Abort => suffix.push_str(".panic-abort"),
41 }
42 }
43 suffix
44}
45
46pub fn files_for_miropt_test(
47 testfile: &std::path::Path,
48 bit_width: u32,
49 panic_strategy: PanicStrategy,
50) -> Vec<MiroptTestFiles> {
51 let mut out = Vec::new();
52 let test_file_contents = fs::read_to_string(&testfile).unwrap();
53
54 let test_dir = testfile.parent().unwrap();
55 let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace('-', "_");
56
57 let suffix = output_file_suffix(testfile, bit_width, panic_strategy);
58
59 for l in test_file_contents.lines() {
60 if l.starts_with("// EMIT_MIR ") {
61 let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
62 let mut test_names = test_name.split(' ');
63 let test_name = test_names.next().unwrap();
65 let mut expected_file;
66 let from_file;
67 let to_file;
68 let mut passes = Vec::new();
69
70 if test_name.ends_with(".diff") {
71 let trimmed = test_name.trim_end_matches(".diff");
72 passes.push(trimmed.split('.').last().unwrap().to_owned());
73 let test_against = format!("{}.after.mir", trimmed);
74 from_file = format!("{}.before.mir", trimmed);
75 expected_file = format!("{}{}.diff", trimmed, suffix);
76 assert!(test_names.next().is_none(), "two mir pass names specified for MIR diff");
77 to_file = Some(test_against);
78 } else if let Some(first_pass) = test_names.next() {
79 let second_pass = test_names.next().unwrap();
80 if let Some((first_pass_name, _)) = first_pass.split_once('.') {
81 passes.push(first_pass_name.to_owned());
82 }
83 if let Some((second_pass_name, _)) = second_pass.split_once('.') {
84 passes.push(second_pass_name.to_owned());
85 }
86 assert!(test_names.next().is_none(), "three mir pass names specified for MIR diff");
87
88 expected_file =
89 format!("{}{}.{}-{}.diff", test_name, suffix, first_pass, second_pass);
90 let second_file = format!("{}.{}.mir", test_name, second_pass);
91 from_file = format!("{}.{}.mir", test_name, first_pass);
92 to_file = Some(second_file);
93 } else {
94 let ext_re = regex::Regex::new(r#"(\.(mir|dot|html))$"#).unwrap();
95 let cap = ext_re
96 .captures_iter(test_name)
97 .next()
98 .expect("test_name has an invalid extension");
99 let extension = cap.get(1).unwrap().as_str();
100
101 expected_file =
102 format!("{}{}{}", test_name.trim_end_matches(extension), suffix, extension,);
103 from_file = test_name.to_string();
104 assert!(test_names.next().is_none(), "two mir pass names specified for MIR dump");
105 to_file = None;
106 passes.push(
109 test_name.split('.').rev().nth(2).expect("invalid test format").to_string(),
110 );
111 };
112 if !expected_file.starts_with(&test_crate) {
113 expected_file = format!("{}.{}", test_crate, expected_file);
114 }
115 let expected_file = test_dir.join(expected_file);
116
117 out.push(MiroptTestFiles { expected_file, from_file, to_file, passes });
118 }
119 }
120
121 out
122}