From e31fed054bc19845b04ee0be50c1254174e87ad0 Mon Sep 17 00:00:00 2001 From: binarycat Date: Wed, 6 Aug 2025 17:21:25 -0500 Subject: run spellcheck as a tidy extra check in ci --- library/std/src/sync/nonpoison/mutex.rs | 2 +- library/std/src/sync/poison/mutex.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'library/std/src') diff --git a/library/std/src/sync/nonpoison/mutex.rs b/library/std/src/sync/nonpoison/mutex.rs index b6861c78f00..fd1e671d7a3 100644 --- a/library/std/src/sync/nonpoison/mutex.rs +++ b/library/std/src/sync/nonpoison/mutex.rs @@ -100,7 +100,7 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> { lock: &'a Mutex, } -/// A [`MutexGuard`] is not `Send` to maximize platform portablity. +/// A [`MutexGuard`] is not `Send` to maximize platform portability. /// /// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to /// release mutex locks on the same thread they were acquired. diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs index 6205c4fa4ca..720c212c65c 100644 --- a/library/std/src/sync/poison/mutex.rs +++ b/library/std/src/sync/poison/mutex.rs @@ -279,7 +279,7 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> { poison: poison::Guard, } -/// A [`MutexGuard`] is not `Send` to maximize platform portablity. +/// A [`MutexGuard`] is not `Send` to maximize platform portability. /// /// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to /// release mutex locks on the same thread they were acquired. -- cgit 1.4.1-3-g733a5 From 1cb4fd7dd12be93465a55d56622c52002e3b050b Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 8 Aug 2025 13:18:53 -0500 Subject: tidy now installs typos-cli as-needed via cargo --- compiler/rustc_resolve/src/imports.rs | 6 ++-- library/std/src/sys/mod.rs | 2 +- src/tools/tidy/src/extra_checks/mod.rs | 37 +++++-------------- src/tools/tidy/src/lib.rs | 66 ++++++++++++++++++++++++++++++++++ src/tools/tidy/src/main.rs | 1 + 5 files changed, 80 insertions(+), 32 deletions(-) (limited to 'library/std/src') diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 7c93fdb88ee..2ecabb33763 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -866,7 +866,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } ImportKind::Glob { .. } => { // FIXME: Use mutable resolver directly as a hack, this should be an output of - // specualtive resolution. + // speculative resolution. self.get_mut_unchecked().resolve_glob_import(import); return 0; } @@ -903,7 +903,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // We need the `target`, `source` can be extracted. let imported_binding = this.import(binding, import); // FIXME: Use mutable resolver directly as a hack, this should be an output of - // specualtive resolution. + // speculative resolution. this.get_mut_unchecked().define_binding_local( parent, target, @@ -917,7 +917,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if target.name != kw::Underscore { let key = BindingKey::new(target, ns); // FIXME: Use mutable resolver directly as a hack, this should be an output of - // specualtive resolution. + // speculative resolution. this.get_mut_unchecked().update_local_resolution( parent, key, diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 8ec0a0e3302..6324c1a232a 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -1,7 +1,7 @@ #![allow(unsafe_op_in_unsafe_fn)] /// The configure builtins provides runtime support compiler-builtin features -/// which require dynamic intialization to work as expected, e.g. aarch64 +/// which require dynamic initialization to work as expected, e.g. aarch64 /// outline-atomics. mod configure_builtins; diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index f90f716cd95..604b5d1e37c 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -41,7 +41,6 @@ const RUFF_CONFIG_PATH: &[&str] = &["src", "tools", "tidy", "config", "ruff.toml const RUFF_CACHE_PATH: &[&str] = &["cache", "ruff_cache"]; const PIP_REQ_PATH: &[&str] = &["src", "tools", "tidy", "config", "requirements.txt"]; -// this must be kept in sync with with .github/workflows/spellcheck.yml const SPELLCHECK_DIRS: &[&str] = &["compiler", "library", "src/bootstrap", "src/librustdoc"]; pub fn check( @@ -51,6 +50,7 @@ pub fn check( librustdoc_path: &Path, tools_path: &Path, npm: &Path, + cargo: &Path, bless: bool, extra_checks: Option<&str>, pos_args: &[String], @@ -63,6 +63,7 @@ pub fn check( librustdoc_path, tools_path, npm, + cargo, bless, extra_checks, pos_args, @@ -78,6 +79,7 @@ fn check_impl( librustdoc_path: &Path, tools_path: &Path, npm: &Path, + cargo: &Path, bless: bool, extra_checks: Option<&str>, pos_args: &[String], @@ -293,7 +295,7 @@ fn check_impl( } else { eprintln!("spellcheck files"); } - spellcheck_runner(&args)?; + spellcheck_runner(&outdir, &cargo, &args)?; } if js_lint || js_typecheck { @@ -576,33 +578,12 @@ fn shellcheck_runner(args: &[&OsStr]) -> Result<(), Error> { if status.success() { Ok(()) } else { Err(Error::FailedCheck("shellcheck")) } } -/// Check that spellchecker is installed then run it at the given path -fn spellcheck_runner(args: &[&str]) -> Result<(), Error> { - // sync version with .github/workflows/spellcheck.yml - let expected_version = "typos-cli 1.34.0"; - match Command::new("typos").arg("--version").output() { - Ok(o) => { - let stdout = String::from_utf8_lossy(&o.stdout); - if stdout.trim() != expected_version { - return Err(Error::Version { - program: "typos", - required: expected_version, - installed: stdout.trim().to_string(), - }); - } - } - Err(e) if e.kind() == io::ErrorKind::NotFound => { - return Err(Error::MissingReq( - "typos", - "spellcheck file checks", - // sync version with .github/workflows/spellcheck.yml - Some("install tool via `cargo install typos-cli@1.34.0`".to_owned()), - )); - } - Err(e) => return Err(e.into()), - } +/// Ensure that spellchecker is installed then run it at the given path +fn spellcheck_runner(outdir: &Path, cargo: &Path, args: &[&str]) -> Result<(), Error> { + let bin_path = + crate::ensure_version_or_cargo_install(outdir, cargo, "typos-cli", "typos", "1.34.0")?; - let status = Command::new("typos").args(args).status()?; + let status = Command::new(bin_path).args(args).status()?; if status.success() { Ok(()) } else { Err(Error::FailedCheck("typos")) } } diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 4ea9d051ddb..37713cbf75e 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -4,7 +4,9 @@ //! to be used by tools. use std::ffi::OsStr; +use std::path::{Path, PathBuf}; use std::process::Command; +use std::{env, io}; use build_helper::ci::CiEnv; use build_helper::git::{GitConfig, get_closest_upstream_commit}; @@ -180,6 +182,70 @@ pub fn files_modified(ci_info: &CiInfo, pred: impl Fn(&str) -> bool) -> bool { !v.is_empty() } +/// If the given executable is installed with the given version, use that, +/// otherwise install via cargo. +pub fn ensure_version_or_cargo_install( + build_dir: &Path, + cargo: &Path, + pkg_name: &str, + bin_name: &str, + version: &str, +) -> io::Result { + // ignore the process exit code here and instead just let the version number check fail. + // we also importantly don't return if the program wasn't installed, + // instead we want to continue to the fallback. + 'ck: { + // FIXME: rewrite as if-let chain once this crate is 2024 edition. + let Ok(output) = Command::new(bin_name).arg("--version").output() else { + break 'ck; + }; + let Ok(s) = str::from_utf8(&output.stdout) else { + break 'ck; + }; + let Some(v) = s.trim().split_whitespace().last() else { + break 'ck; + }; + if v == version { + return Ok(PathBuf::from(bin_name)); + } + } + + let tool_root_dir = build_dir.join("misc-tools"); + let tool_bin_dir = tool_root_dir.join("bin"); + eprintln!("building external tool {bin_name} from package {pkg_name}@{version}"); + // use --force to ensure that if the required version is bumped, we update it. + // use --target-dir to ensure we have a build cache so repeated invocations aren't slow. + // modify PATH so that cargo doesn't print a warning telling the user to modify the path. + let cargo_exit_code = Command::new(cargo) + .args(["install", "--locked", "--force", "--quiet"]) + .arg("--root") + .arg(&tool_root_dir) + .arg("--target-dir") + .arg(tool_root_dir.join("target")) + .arg(format!("{pkg_name}@{version}")) + .env( + "PATH", + env::join_paths( + env::split_paths(&env::var("PATH").unwrap()) + .chain(std::iter::once(tool_bin_dir.clone())), + ) + .expect("build dir contains invalid char"), + ) + .env("RUSTFLAGS", "-Copt-level=0") + .spawn()? + .wait()?; + if !cargo_exit_code.success() { + return Err(io::Error::other("cargo install failed")); + } + let bin_path = tool_bin_dir.join(bin_name); + assert!( + matches!(bin_path.try_exists(), Ok(true)), + "cargo install did not produce the expected binary" + ); + eprintln!("finished building tool {bin_name}"); + Ok(bin_path) +} + pub mod alphabetical; pub mod bins; pub mod debug_artifacts; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index cd2567ddb64..bfe30258915 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -184,6 +184,7 @@ fn main() { &librustdoc_path, &tools_path, &npm, + &cargo, bless, extra_checks, pos_args -- cgit 1.4.1-3-g733a5 From 2050a3b297d8878f232d28d48aa1a3a12d1616ee Mon Sep 17 00:00:00 2001 From: binarycat Date: Sat, 16 Aug 2025 10:34:55 -0500 Subject: std: fix more typos --- library/std/src/sys/pal/uefi/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'library/std/src') diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs index df5611b2ddd..74817865941 100644 --- a/library/std/src/sys/pal/uefi/time.rs +++ b/library/std/src/sys/pal/uefi/time.rs @@ -188,7 +188,7 @@ pub(crate) mod system_time_internal { Duration::new(epoch, t.nanosecond) } - /// This algorithm is a modifed version of the one described in the post: + /// This algorithm is a modified version of the one described in the post: /// https://howardhinnant.github.io/date_algorithms.html#clive_from_days /// /// The changes are to use 1900-01-01-00:00:00 with timezone -1440 as anchor instead of UNIX @@ -197,7 +197,7 @@ pub(crate) mod system_time_internal { // Check timzone validity assert!(timezone <= 1440 && timezone >= -1440); - // FIXME(#126043): use checked_sub_signed once stablized + // FIXME(#126043): use checked_sub_signed once stabilized let secs = dur.as_secs().checked_add_signed((-timezone as i64) * SECS_IN_MINUTE as i64).unwrap(); -- cgit 1.4.1-3-g733a5 From aa3008d52e7372af64bf1beda9dc5da5e653bdb6 Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 23 Jun 2025 19:06:36 -0500 Subject: implement std::fs::set_permissions_nofollow on unix --- library/std/src/fs.rs | 19 +++++++++++++++++++ library/std/src/sys/fs/mod.rs | 15 +++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'library/std/src') diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 865ea620a28..3da4b0ff855 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -3128,6 +3128,25 @@ pub fn set_permissions>(path: P, perm: Permissions) -> io::Result fs_imp::set_permissions(path.as_ref(), perm.0) } +/// Set the permissions of a file, unless it is a symlink. +/// +/// Note that the non-final path elements are allowed to be symlinks. +/// +/// # Platform-specific behavior +/// +/// Currently unimplemented on Windows. +/// +/// On Unix platforms, this results in a [`FilesystemLoop`] error if the last element is a symlink. +/// +/// This behavior may change in the future. +/// +/// [`FilesystemLoop`]: crate::io::ErrorKind::FilesystemLoop +#[doc(alias = "chmod", alias = "SetFileAttributes")] +#[unstable(feature = "set_permissions_nofollow", issue = "141607")] +pub fn set_permissions_nofollow>(path: P, perm: Permissions) -> io::Result<()> { + fs_imp::set_permissions_nofollow(path.as_ref(), perm) +} + impl DirBuilder { /// Creates a new set of options with default mode/security settings for all /// platforms and also non-recursive. diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs index d55e28074fe..d7f98c86e6e 100644 --- a/library/std/src/sys/fs/mod.rs +++ b/library/std/src/sys/fs/mod.rs @@ -108,6 +108,21 @@ pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> { with_native_path(path, &|path| imp::set_perm(path, perm.clone())) } +#[cfg(unix)] +pub fn set_permissions_nofollow(path: &Path, perm: crate::fs::Permissions) -> io::Result<()> { + use crate::fs::OpenOptions; + use crate::os::unix::fs::OpenOptionsExt; + + OpenOptions::new().custom_flags(libc::O_NOFOLLOW).open(path)?.set_permissions(perm) +} + +#[cfg(not(unix))] +pub fn set_permissions_nofollow(_path: &Path, _perm: crate::fs::Permissions) -> io::Result<()> { + crate::unimplemented!( + "`set_permissions_nofollow` is currently only implemented on Unix platforms" + ) +} + pub fn canonicalize(path: &Path) -> io::Result { with_native_path(path, &imp::canonicalize) } -- cgit 1.4.1-3-g733a5