1use std::{
2    fs,
3    ffi::OsStr,
4    io,
5    path::Path,
6};
7
8use walkdir::WalkDir;
9
10#[test]
11fn fail() {
12    prepare_stderr_files("tests/compile-fail").unwrap();
13
14    let t = trybuild::TestCases::new();
15    t.compile_fail("tests/compile-fail/**/*.rs");
16}
17
18#[test]
19fn pass() {
20    let t = trybuild::TestCases::new();
21    t.pass("tests/compile-pass/**/*.rs");
22}
23
24// Compiler messages may change between versions
25// We don't want to have to track these too closely for `bitflags`, but
26// having some message to check makes sure user-facing errors are sensical.
27//
28// The approach we use is to run the test on all compilers, but only check stderr
29// output on beta (which is the next stable release). We do this by default ignoring
30// any `.stderr` files in the `compile-fail` directory, and copying `.stderr.beta` files
31// when we happen to be running on a beta compiler.
32fn prepare_stderr_files(path: impl AsRef<Path>) -> io::Result<()> {
33    for entry in WalkDir::new(path) {
34        let entry = entry?;
35
36        if entry.path().extension().and_then(OsStr::to_str) == Some("beta") {
37            let renamed = entry.path().with_extension("");
38
39            // Unconditionally remove a corresponding `.stderr` file for a `.stderr.beta`
40            // file if it exists. On `beta` compilers, we'll recreate it. On other compilers,
41            // we don't want to end up checking it anyways.
42            if renamed.exists() {
43                fs::remove_file(&renamed)?;
44            }
45
46            rename_beta_stderr(entry.path(), renamed)?;
47        }
48    }
49
50    Ok(())
51}
52
53#[rustversion::beta]
54fn rename_beta_stderr(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
55    fs::copy(from, to)?;
56
57    Ok(())
58}
59
60#[rustversion::not(beta)]
61fn rename_beta_stderr(_: impl AsRef<Path>, _: impl AsRef<Path>) -> io::Result<()> {
62    Ok(())
63}
64