default behavior without any commands is to:
1. Run `rustc -Zunpretty=normal` on the source file.
2. Run `rustc -Zunpretty=normal` on the output of the previous step.
3. The output of the previous two steps should be the same.
4. Run `rustc -Zno-codegen` on the output to make sure that it can type check
(this is similar to running `cargo check`).
If any of the commands above fail, then the test fails.
The directives for pretty-printing tests are:
- `pretty-mode` specifies the mode pretty-print tests should run in (that is,
the argument to `-Zunpretty`). The default is `normal` if not specified.
- `pretty-compare-only` causes a pretty test to only compare the pretty-printed
output (stopping after step 3 from above). It will not try to compile the
expanded output to type check it. This is needed for a pretty-mode that does
not expand to valid Rust, or for other situations where the expanded output
cannot be compiled.
- `pp-exact` is used to ensure a pretty-print test results in specific output.
If specified without a value, then it means the pretty-print output should
match the original source. If specified with a value, as in `//@
pp-exact:foo.pp`, it will ensure that the pretty-printed output matches the
contents of the given file. Otherwise, if `pp-exact` is not specified, then
the pretty-printed output will be pretty-printed one more time, and the output
of the two pretty-printing rounds will be compared to ensure that the
pretty-printed output converges to a steady state.
### Incremental tests
The tests in [`tests/incremental`] exercise incremental compilation. They use
[`revisions` directive](#revisions) to tell compiletest to run the compiler in a
series of steps.
Compiletest starts with an empty directory with the `-C incremental` flag, and
then runs the compiler for each revision, reusing the incremental results from
previous steps.
The revisions should start with:
* `rpass` — the test should compile and run successfully
* `rfail` — the test should compile successfully, but the executable should fail to run
* `cfail` — the test should fail to compile
To make the revisions unique, you should add a suffix like `rpass1` and
`rpass2`.
To simulate changing the source, compiletest also passes a `--cfg` flag with the
current revision name.
For example, this will run twice, simulating changing a function:
```rust,ignore
//@ revisions: rpass1 rpass2
#[cfg(rpass1)]
fn foo() {
println!("one");
}
#[cfg(rpass2)]
fn foo() {
println!("two");
}
fn main() { foo(); }
```
`cfail` tests support the `forbid-output` directive to specify that a certain
substring must not appear anywhere in the compiler output. This can be useful to
ensure certain errors do not appear, but this can be fragile as error messages
change over time, and a test may no longer be checking the right thing but will
still pass.
`cfail` tests support the `should-ice` directive to specify that a test should
cause an Internal Compiler Error (ICE). This is a highly specialized directive
to check that the incremental cache continues to work after an ICE.
### Debuginfo tests
The tests in [`tests/debuginfo`] test debuginfo generation. They build a
program, launch a debugger, and issue commands to the debugger. A single test
can work with cdb, gdb, and lldb.
Most tests should have the `//@ compile-flags: -g` directive or something
similar to generate the appropriate debuginfo.
To set a breakpoint on a line, add a `// #break` comment on the line.
The debuginfo tests consist of a series of debugger commands along with
"check" lines which specify output that is expected from the debugger.
The commands are comments of the form `// $DEBUGGER-command:$COMMAND` where
`$DEBUGGER` is the debugger being used and `$COMMAND` is the debugger command
to execute.
The debugger values can be:
- `cdb`
- `gdb`
- `gdbg` — GDB without Rust support (versions older than 7.11)
- `gdbr` — GDB with Rust support
- `lldb`
- `lldbg` — LLDB without Rust support