summaryrefslogtreecommitdiffstats
path: root/src/tools/tidy
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/tidy')
-rw-r--r--src/tools/tidy/Cargo.toml1
-rw-r--r--src/tools/tidy/src/bins.rs10
-rw-r--r--src/tools/tidy/src/deps.rs16
-rw-r--r--src/tools/tidy/src/error_codes_check.rs2
-rw-r--r--src/tools/tidy/src/features.rs37
-rw-r--r--src/tools/tidy/src/features/version.rs19
-rw-r--r--src/tools/tidy/src/lib.rs74
-rw-r--r--src/tools/tidy/src/main.rs7
-rw-r--r--src/tools/tidy/src/pal.rs2
-rw-r--r--src/tools/tidy/src/style.rs15
-rw-r--r--src/tools/tidy/src/walk.rs66
11 files changed, 156 insertions, 93 deletions
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 96ab42b47..471d78a29 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -9,7 +9,6 @@ cargo_metadata = "0.14"
regex = "1"
lazy_static = "1"
walkdir = "2"
-crossbeam-utils = "0.8.0"
[[bin]]
name = "rust-tidy"
diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs
index 9615c4db6..30903f56d 100644
--- a/src/tools/tidy/src/bins.rs
+++ b/src/tools/tidy/src/bins.rs
@@ -96,7 +96,9 @@ mod os_impl {
#[cfg(unix)]
pub fn check(path: &Path, bad: &mut bool) {
- const ALLOWED: &[&str] = &["configure"];
+ use std::ffi::OsStr;
+
+ const ALLOWED: &[&str] = &["configure", "x"];
crate::walk_no_read(
path,
@@ -117,9 +119,9 @@ mod os_impl {
},
&mut |entry| {
let file = entry.path();
- let filename = file.file_name().unwrap().to_string_lossy();
- let extensions = [".py", ".sh"];
- if extensions.iter().any(|e| filename.ends_with(e)) {
+ let extension = file.extension();
+ let scripts = ["py", "sh", "ps1"];
+ if scripts.into_iter().any(|e| extension == Some(OsStr::new(e))) {
return;
}
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 333f85f6d..cbd8cfa01 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -31,8 +31,7 @@ const EXCEPTIONS: &[(&str, &str)] = &[
("mdbook", "MPL-2.0"), // mdbook
("openssl", "Apache-2.0"), // cargo, mdbook
("colored", "MPL-2.0"), // rustfmt
- ("ordslice", "Apache-2.0"), // rls
- ("ryu", "Apache-2.0 OR BSL-1.0"), // rls/cargo/... (because of serde)
+ ("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde)
("bytesize", "Apache-2.0"), // cargo
("im-rc", "MPL-2.0+"), // cargo
("sized-chunks", "MPL-2.0+"), // cargo via im-rc
@@ -92,9 +91,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"autocfg",
"bitflags",
"block-buffer",
- "block-padding",
- "byte-tools",
- "byteorder",
"cc",
"cfg-if",
"chalk-derive",
@@ -119,7 +115,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"ena",
"env_logger",
"expect-test",
- "fake-simd",
"fallible-iterator", // dependency of `thorin`
"filetime",
"fixedbitset",
@@ -163,7 +158,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"object",
"odht",
"once_cell",
- "opaque-debug",
"parking_lot",
"parking_lot_core",
"pathdiff",
@@ -224,6 +218,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"time",
"tinystr",
"tinyvec",
+ "thin-vec",
"tracing",
"tracing-attributes",
"tracing-core",
@@ -247,6 +242,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
"unicode-width",
"unicode-xid",
"vcpkg",
+ "valuable",
"version_check",
"wasi",
"winapi",
@@ -300,6 +296,12 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
"winapi",
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
+ "windows-sys",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_msvc",
];
const FORBIDDEN_TO_HAVE_DUPLICATES: &[&str] = &[
diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs
index f0054a1c1..0a226443e 100644
--- a/src/tools/tidy/src/error_codes_check.rs
+++ b/src/tools/tidy/src/error_codes_check.rs
@@ -217,7 +217,7 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
println!("Checking which error codes lack tests...");
for path in paths {
- super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| {
+ super::walk(path, &mut super::filter_dirs, &mut |entry, contents| {
let file_name = entry.file_name();
let entry_path = entry.path();
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 2f22c081a..b306a527a 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -175,6 +175,35 @@ pub fn check(
tidy_error!(bad, "Found {} features without a gate test.", gate_untested.len());
}
+ let (version, channel) = get_version_and_channel(src_path);
+
+ let all_features_iter = features
+ .iter()
+ .map(|feat| (feat, "lang"))
+ .chain(lib_features.iter().map(|feat| (feat, "lib")));
+ for ((feature_name, feature), kind) in all_features_iter {
+ let since = if let Some(since) = feature.since { since } else { continue };
+ if since > version && since != Version::CurrentPlaceholder {
+ tidy_error!(
+ bad,
+ "The stabilization version {since} of {kind} feature `{feature_name}` is newer than the current {version}"
+ );
+ }
+ if channel == "nightly" && since == version {
+ tidy_error!(
+ bad,
+ "The stabilization version {since} of {kind} feature `{feature_name}` is written out but should be {}",
+ version::VERSION_PLACEHOLDER
+ );
+ }
+ if channel != "nightly" && since == Version::CurrentPlaceholder {
+ tidy_error!(
+ bad,
+ "The placeholder use of {kind} feature `{feature_name}` is not allowed on the {channel} channel",
+ );
+ }
+ }
+
if *bad {
return CollectedFeatures { lib: lib_features, lang: features };
}
@@ -195,6 +224,14 @@ pub fn check(
CollectedFeatures { lib: lib_features, lang: features }
}
+fn get_version_and_channel(src_path: &Path) -> (Version, String) {
+ let version_str = t!(std::fs::read_to_string(src_path.join("version")));
+ let version_str = version_str.trim();
+ let version = t!(std::str::FromStr::from_str(&version_str).map_err(|e| format!("{e:?}")));
+ let channel_str = t!(std::fs::read_to_string(src_path.join("ci").join("channel")));
+ (version, channel_str.trim().to_owned())
+}
+
fn format_features<'a>(
features: &'a Features,
family: &'a str,
diff --git a/src/tools/tidy/src/features/version.rs b/src/tools/tidy/src/features/version.rs
index 620be2f98..0830c226c 100644
--- a/src/tools/tidy/src/features/version.rs
+++ b/src/tools/tidy/src/features/version.rs
@@ -5,14 +5,22 @@ use std::str::FromStr;
#[cfg(test)]
mod tests;
+pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Version {
- parts: [u32; 3],
+pub enum Version {
+ Explicit { parts: [u32; 3] },
+ CurrentPlaceholder,
}
impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.pad(&format!("{}.{}.{}", self.parts[0], self.parts[1], self.parts[2]))
+ match self {
+ Version::Explicit { parts } => {
+ f.pad(&format!("{}.{}.{}", parts[0], parts[1], parts[2]))
+ }
+ Version::CurrentPlaceholder => f.pad(&format!("CURRENT")),
+ }
}
}
@@ -32,6 +40,9 @@ impl FromStr for Version {
type Err = ParseVersionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
+ if s == VERSION_PLACEHOLDER {
+ return Ok(Version::CurrentPlaceholder);
+ }
let mut iter = s.split('.').map(|part| Ok(part.parse()?));
let mut part = || iter.next().unwrap_or(Err(ParseVersionError::WrongNumberOfParts));
@@ -43,6 +54,6 @@ impl FromStr for Version {
return Err(ParseVersionError::WrongNumberOfParts);
}
- Ok(Self { parts })
+ Ok(Version::Explicit { parts })
}
}
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 09848462a..12d3bdcd7 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -3,12 +3,14 @@
//! This library contains the tidy lints and exposes it
//! to be used by tools.
-use std::fs::File;
-use std::io::Read;
-use walkdir::{DirEntry, WalkDir};
-
-use std::path::Path;
-
+use walk::{filter_dirs, walk, walk_many, walk_no_read};
+
+/// A helper macro to `unwrap` a result except also print out details like:
+///
+/// * The expression that failed
+/// * The error itself
+/// * (optionally) a path connected to the error (e.g. failure to open a file)
+#[macro_export]
macro_rules! t {
($e:expr, $p:expr) => {
match $e {
@@ -28,7 +30,8 @@ macro_rules! t {
macro_rules! tidy_error {
($bad:expr, $fmt:expr) => ({
*$bad = true;
- eprintln!("tidy error: {}", $fmt);
+ eprint!("tidy error: ");
+ eprintln!($fmt);
});
($bad:expr, $fmt:expr, $($arg:tt)*) => ({
*$bad = true;
@@ -52,59 +55,4 @@ pub mod target_specific_tests;
pub mod ui_tests;
pub mod unit_tests;
pub mod unstable_book;
-
-fn filter_dirs(path: &Path) -> bool {
- let skip = [
- "tidy-test-file",
- "compiler/rustc_codegen_cranelift",
- "compiler/rustc_codegen_gcc",
- "src/llvm-project",
- "library/backtrace",
- "library/portable-simd",
- "library/stdarch",
- "src/tools/cargo",
- "src/tools/clippy",
- "src/tools/miri",
- "src/tools/rls",
- "src/tools/rust-analyzer",
- "src/tools/rust-installer",
- "src/tools/rustfmt",
- "src/doc/book",
- // Filter RLS output directories
- "target/rls",
- ];
- skip.iter().any(|p| path.ends_with(p))
-}
-
-fn walk_many(
- paths: &[&Path],
- skip: &mut dyn FnMut(&Path) -> bool,
- f: &mut dyn FnMut(&DirEntry, &str),
-) {
- for path in paths {
- walk(path, skip, f);
- }
-}
-
-fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry, &str)) {
- let mut contents = String::new();
- walk_no_read(path, skip, &mut |entry| {
- contents.clear();
- if t!(File::open(entry.path()), entry.path()).read_to_string(&mut contents).is_err() {
- contents.clear();
- }
- f(&entry, &contents);
- });
-}
-
-fn walk_no_read(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry)) {
- let walker = WalkDir::new(path).into_iter().filter_entry(|e| !skip(e.path()));
- for entry in walker {
- if let Ok(entry) = entry {
- if entry.file_type().is_dir() {
- continue;
- }
- f(&entry);
- }
- }
-}
+pub mod walk;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index aa8d8b4f6..c1ce94f47 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -6,7 +6,6 @@
use tidy::*;
-use crossbeam_utils::thread::{scope, ScopedJoinHandle};
use std::collections::VecDeque;
use std::env;
use std::num::NonZeroUsize;
@@ -14,6 +13,7 @@ use std::path::PathBuf;
use std::process;
use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering};
+use std::thread::{scope, ScopedJoinHandle};
fn main() {
let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into();
@@ -44,7 +44,7 @@ fn main() {
handles.pop_front().unwrap().join().unwrap();
}
- let handle = s.spawn(|_| {
+ let handle = s.spawn(|| {
let mut flag = false;
$p::check($($args),* , &mut flag);
if (flag) {
@@ -102,8 +102,7 @@ fn main() {
r
};
check!(unstable_book, &src_path, collected);
- })
- .unwrap();
+ });
if bad.load(Ordering::Relaxed) {
eprintln!("some tidy checks failed");
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index c5414233f..4d86fe8be 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -59,6 +59,8 @@ const EXCEPTION_PATHS: &[&str] = &[
"library/std/src/sys_common", // Should only contain abstractions over platforms
"library/std/src/net/test.rs", // Utility helpers for tests
"library/std/src/panic.rs", // fuchsia-specific panic backtrace handling
+ "library/std/src/personality.rs",
+ "library/std/src/personality/",
];
pub fn check(path: &Path, bad: &mut bool) {
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 3cf44a2d7..dee58ff2f 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -125,16 +125,13 @@ fn should_ignore(line: &str) -> bool {
/// Returns `true` if `line` is allowed to be longer than the normal limit.
fn long_line_is_ok(extension: &str, is_error_code: bool, max_columns: usize, line: &str) -> bool {
- if extension != "md" || is_error_code {
- if line_is_url(is_error_code, max_columns, line) || should_ignore(line) {
- return true;
- }
- } else if extension == "md" {
+ match extension {
+ // fluent files are allowed to be any length
+ "ftl" => true,
// non-error code markdown is allowed to be any length
- return true;
+ "md" if !is_error_code => true,
+ _ => line_is_url(is_error_code, max_columns, line) || should_ignore(line),
}
-
- false
}
enum Directive {
@@ -230,7 +227,7 @@ pub fn check(path: &Path, bad: &mut bool) {
super::walk(path, &mut skip, &mut |entry, contents| {
let file = entry.path();
let filename = file.file_name().unwrap().to_string_lossy();
- let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css"];
+ let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css", ".ftl"];
if extensions.iter().all(|e| !filename.ends_with(e)) || filename.starts_with(".#") {
return;
}
diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs
new file mode 100644
index 000000000..b07e80767
--- /dev/null
+++ b/src/tools/tidy/src/walk.rs
@@ -0,0 +1,66 @@
+use std::fs::File;
+use std::io::Read;
+use walkdir::{DirEntry, WalkDir};
+
+use std::path::Path;
+
+pub fn filter_dirs(path: &Path) -> bool {
+ let skip = [
+ "tidy-test-file",
+ "compiler/rustc_codegen_cranelift",
+ "compiler/rustc_codegen_gcc",
+ "src/llvm-project",
+ "library/backtrace",
+ "library/portable-simd",
+ "library/stdarch",
+ "src/tools/cargo",
+ "src/tools/clippy",
+ "src/tools/miri",
+ "src/tools/rls",
+ "src/tools/rust-analyzer",
+ "src/tools/rust-installer",
+ "src/tools/rustfmt",
+ "src/doc/book",
+ // Filter RLS output directories
+ "target/rls",
+ "src/bootstrap/target",
+ ];
+ skip.iter().any(|p| path.ends_with(p))
+}
+
+pub fn walk_many(
+ paths: &[&Path],
+ skip: &mut dyn FnMut(&Path) -> bool,
+ f: &mut dyn FnMut(&DirEntry, &str),
+) {
+ for path in paths {
+ walk(path, skip, f);
+ }
+}
+
+pub fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry, &str)) {
+ let mut contents = String::new();
+ walk_no_read(path, skip, &mut |entry| {
+ contents.clear();
+ if t!(File::open(entry.path()), entry.path()).read_to_string(&mut contents).is_err() {
+ contents.clear();
+ }
+ f(&entry, &contents);
+ });
+}
+
+pub(crate) fn walk_no_read(
+ path: &Path,
+ skip: &mut dyn FnMut(&Path) -> bool,
+ f: &mut dyn FnMut(&DirEntry),
+) {
+ let walker = WalkDir::new(path).into_iter().filter_entry(|e| !skip(e.path()));
+ for entry in walker {
+ if let Ok(entry) = entry {
+ if entry.file_type().is_dir() {
+ continue;
+ }
+ f(&entry);
+ }
+ }
+}