Skip to content

Commit

Permalink
Port tests/run-make/sysroot-crates-are-unstable to rmake
Browse files Browse the repository at this point in the history
  • Loading branch information
Zalathar committed Jun 11, 2024
1 parent 6a207f4 commit 591e2e3
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 79 deletions.
5 changes: 5 additions & 0 deletions src/tools/run-make-support/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ impl Command {
output
}

#[track_caller]
pub fn run_unchecked(&mut self) -> CompletedProcess {
self.command_output()
}

#[track_caller]
pub(crate) fn command_output(&mut self) -> CompletedProcess {
// let's make sure we piped all the input and outputs
Expand Down
13 changes: 12 additions & 1 deletion src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
});
}

pub fn read_dir<F: Fn(&Path)>(dir: impl AsRef<Path>, callback: F) {
pub fn read_dir(dir: impl AsRef<Path>, mut callback: impl FnMut(&Path)) {
for entry in fs::read_dir(dir).unwrap() {
callback(&entry.unwrap().path());
}
Expand Down Expand Up @@ -414,6 +414,17 @@ macro_rules! impl_common_helpers {
self.cmd.run_fail()
}

/// Run the constructed command, but don't check its result status.
/// The caller is responsible for performing any necessary checks.
///
/// Prefer to call [`run`](Self::run) or [`run_fail`](Self::run_fail)
/// if possible.
#[must_use]
#[track_caller]
pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
self.cmd.run_unchecked()
}

/// Set the path where the command will be run.
pub fn current_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.current_dir(path);
Expand Down
1 change: 0 additions & 1 deletion src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ run-make/symbols-include-type-name/Makefile
run-make/symlinked-extern/Makefile
run-make/symlinked-libraries/Makefile
run-make/symlinked-rlib/Makefile
run-make/sysroot-crates-are-unstable/Makefile
run-make/target-cpu-native/Makefile
run-make/target-specs/Makefile
run-make/target-without-atomic-cas/Makefile
Expand Down
2 changes: 0 additions & 2 deletions tests/run-make/sysroot-crates-are-unstable/Makefile

This file was deleted.

108 changes: 108 additions & 0 deletions tests/run-make/sysroot-crates-are-unstable/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//! Checks that all unstable library crates in the sysroot are actually treated
//! as unstable.
#![deny(warnings)]

use run_make_support::{env_var, read_dir, rustc};
use std::path::{Path, PathBuf};
use std::str;

#[derive(Debug)]
struct Lib {
name: String,
path: PathBuf,
}

fn check_lib(lib: &Lib) -> Result<(), ()> {
let Lib { name, path } = lib;

println!("verifying that sysroot crate '{name}' is an unstable crate");

let output = rustc()
.input("-")
.crate_type("rlib")
.target(&env_var("TARGET"))
.extern_(name, path)
.stdin(format!("extern crate {name};"))
.run_unchecked();

if !output.status().success()
&& output.stderr_utf8().contains("use of unstable library feature")
{
return Ok(());
}

eprintln!();
eprintln!("CRATE IS NOT UNSTABLE: `{name}` at {path:?}");
eprintln!("output status: `{}`", output.status());
eprintln!("=== STDOUT ===");
eprint!("{}", output.stdout_utf8());
eprintln!("==============");
eprintln!("=== STDERR ===");
eprint!("{}", output.stderr_utf8());
eprintln!("==============");

Err(())
}

fn get_all_libs(libs_dir: &Path) -> Vec<Lib> {
let mut libs = vec![];
read_dir(libs_dir, |file| {
if !file.is_file() {
return;
};

// Treat a file as a library if it begins with `lib` and ends with `.rlib`.
// The library name is the part before the first hyphen (if any).
// FIXME: Use a `try` block once they're stable.
let Some(lib_name) = Some(file).and_then(|file| {
file.file_name()?
.to_str()?
.strip_prefix("lib")?
.strip_suffix(".rlib")?
.split('-')
.next()
}) else {
return;
};

libs.push(Lib { name: lib_name.to_owned(), path: file.to_owned() });
});
libs
}

fn sysroot() -> PathBuf {
let sysroot = rustc().print("sysroot").run().stdout_utf8().lines().next().unwrap().to_owned();
assert!(!sysroot.is_empty());
PathBuf::from(sysroot)
}

fn is_stable_crate(name: &str) -> bool {
matches!(name, "std" | "alloc" | "core" | "proc_macro")
}

fn main() {
// Generate a list of all library crates in the sysroot.
let sysroot_libs_dir = sysroot().join("lib/rustlib").join(env_var("TARGET")).join("lib");
let sysroot_libs = get_all_libs(&sysroot_libs_dir);

// Self-check: If we didn't find `core`, we probably checked the wrong directory.
assert!(
sysroot_libs.iter().any(|lib| lib.name == "core"),
"couldn't find `core` in {sysroot_libs_dir:?}:\n{sysroot_libs:#?}"
);

let unstable_sysroot_libs =
sysroot_libs.iter().filter(|lib| !is_stable_crate(&lib.name)).collect::<Vec<_>>();
// Self-check: There should be at least one unstable lib in the directory.
assert!(
!unstable_sysroot_libs.is_empty(),
"couldn't find any unstable libs in {sysroot_libs_dir:?}:\n{sysroot_libs:#?}"
);

// Check all of the crates before actually failing, so that we report all
// errors instead of just the first one.
let results = unstable_sysroot_libs.iter().map(|lib| check_lib(lib)).collect::<Vec<_>>();
if results.iter().any(|r| r.is_err()) {
std::process::exit(1);
}
}
75 changes: 0 additions & 75 deletions tests/run-make/sysroot-crates-are-unstable/test.py

This file was deleted.

0 comments on commit 591e2e3

Please sign in to comment.