forked from FuelLabs/sway
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tests.rs
111 lines (94 loc) · 3.9 KB
/
tests.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::path::PathBuf;
// -------------------------------------------------------------------------------------------------
// Utility for finding test files and running FileCheck. See actual pass invocations below.
fn run_tests<F: Fn(&mut sway_ir::Context) -> bool>(sub_dir: &str, opt_fn: F) {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let dir: PathBuf = format!("{}/tests/{}", manifest_dir, sub_dir).into();
for entry in std::fs::read_dir(dir).unwrap() {
let path = entry.unwrap().path();
let input_bytes = std::fs::read(&path).unwrap();
let input = String::from_utf8_lossy(&input_bytes);
let chkr = filecheck::CheckerBuilder::new()
.text(&input)
.unwrap()
.finish();
assert!(
!chkr.is_empty(),
"No filecheck directives found in test: {}",
path.display()
);
let mut ir = sway_ir::parser::parse(&input).unwrap_or_else(|parse_err| {
println!("{parse_err}");
panic!()
});
// The tests should return true, indicating they made modifications.
assert!(
opt_fn(&mut ir),
"Pass returned false (no changes made to {}).",
path.display()
);
let ir = ir.verify().unwrap_or_else(|err| {
println!("{err}");
panic!();
});
let output = sway_ir::printer::to_string(&ir);
match chkr.explain(&output, filecheck::NO_VARIABLES) {
Ok((success, report)) if !success => {
println!("--- FILECHECK FAILED FOR {}", path.display());
println!("{report}");
panic!()
}
Err(e) => {
panic!("filecheck directive error while checking: {e}");
}
_ => (),
}
}
}
// -------------------------------------------------------------------------------------------------
#[test]
fn inline() {
run_tests("inline", |ir: &mut sway_ir::Context| {
let main_fn = ir
.functions
.iter()
.find_map(|(idx, fc)| if fc.name == "main" { Some(idx) } else { None })
.unwrap();
sway_ir::optimize::inline_all_function_calls(ir, &sway_ir::function::Function(main_fn))
.unwrap()
})
}
// -------------------------------------------------------------------------------------------------
// Clippy suggests using the map iterator below directly instead of collecting from it first, but
// if we try that then we have borrowing issues with `ir` which is used within the closure.
#[allow(clippy::needless_collect)]
#[test]
fn constants() {
run_tests("constants", |ir: &mut sway_ir::Context| {
let fn_idcs: Vec<_> = ir.functions.iter().map(|func| func.0).collect();
fn_idcs.into_iter().fold(false, |acc, fn_idx| {
sway_ir::optimize::combine_constants(ir, &sway_ir::function::Function(fn_idx)).unwrap()
|| acc
})
})
}
// -------------------------------------------------------------------------------------------------
#[allow(clippy::needless_collect)]
#[test]
fn simplify_cfg() {
run_tests("simplify_cfg", |ir: &mut sway_ir::Context| {
let fn_idcs: Vec<_> = ir.functions.iter().map(|func| func.0).collect();
fn_idcs.into_iter().fold(false, |acc, fn_idx| {
sway_ir::optimize::simplify_cfg(ir, &sway_ir::function::Function(fn_idx)).unwrap()
|| acc
})
})
}
// -------------------------------------------------------------------------------------------------
#[test]
fn serialize() {
// This isn't running a pass, it's just confirming that the IR can be loaded and printed, and
// FileCheck can just confirm certain instructions came out OK.
run_tests("serialize", |_: &mut sway_ir::Context| true)
}
// -------------------------------------------------------------------------------------------------