diff options
Diffstat (limited to 'src/tools/tidy')
-rw-r--r-- | src/tools/tidy/Cargo.toml | 1 | ||||
-rw-r--r-- | src/tools/tidy/src/bins.rs | 10 | ||||
-rw-r--r-- | src/tools/tidy/src/deps.rs | 16 | ||||
-rw-r--r-- | src/tools/tidy/src/error_codes_check.rs | 2 | ||||
-rw-r--r-- | src/tools/tidy/src/features.rs | 37 | ||||
-rw-r--r-- | src/tools/tidy/src/features/version.rs | 19 | ||||
-rw-r--r-- | src/tools/tidy/src/lib.rs | 74 | ||||
-rw-r--r-- | src/tools/tidy/src/main.rs | 7 | ||||
-rw-r--r-- | src/tools/tidy/src/pal.rs | 2 | ||||
-rw-r--r-- | src/tools/tidy/src/style.rs | 15 | ||||
-rw-r--r-- | src/tools/tidy/src/walk.rs | 66 |
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); + } + } +} |