From 64f472c5ed65b2a5e4e82cda55ded04d665c7a46 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 18 Apr 2026 09:42:30 -0400 Subject: [PATCH 1/5] fix: use `portable-atomic` for 64-bit atomics `std::sync::atomic::{AtomicU64, AtomicI64}` are not available on some tier 2 32-bit platforms. Replace them with `portable_atomic`, which is already a transitive dependency via `gix` and `jiff` See * https://triage.rust-lang.org/gha-logs/rust-lang/rust/71938527712 * https://github.com/rust-lang/rust/pull/155470#issuecomment-4273312423 --- Cargo.lock | 1 + Cargo.toml | 2 ++ src/cargo/util/network/http_async.rs | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a89e826a378..5dad5918567 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -419,6 +419,7 @@ dependencies = [ "os_info", "pasetors", "pathdiff", + "portable-atomic", "rand 0.10.1", "regex", "rusqlite", diff --git a/Cargo.toml b/Cargo.toml index c0e6faa2d3b..ae93bd02d94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,6 +84,7 @@ openssl-src = "=300.5.4" os_info = { version = "3.14.0", default-features = false } pasetors = { version = "0.7.8", features = ["v3", "paserk", "std", "serde"] } pathdiff = "0.2.3" +portable-atomic = "1.13.1" percent-encoding = "2.3.2" proptest = "1.11.0" pulldown-cmark = { version = "0.13.3", default-features = false, features = ["html"] } @@ -204,6 +205,7 @@ opener.workspace = true os_info.workspace = true pasetors.workspace = true pathdiff.workspace = true +portable-atomic.workspace = true rand.workspace = true regex.workspace = true rusqlite = { workspace = true, features = ["fallible_uint"] } diff --git a/src/cargo/util/network/http_async.rs b/src/cargo/util/network/http_async.rs index 970d36b2d88..63163e32948 100644 --- a/src/cargo/util/network/http_async.rs +++ b/src/cargo/util/network/http_async.rs @@ -8,8 +8,6 @@ use std::io::Cursor; use std::io::Read; use std::str::FromStr; use std::sync::Arc; -use std::sync::atomic::AtomicI64; -use std::sync::atomic::AtomicU64; use std::sync::atomic::Ordering; use std::sync::mpsc; use std::sync::mpsc::Receiver; @@ -25,6 +23,8 @@ use curl::easy::WriteError; use curl::multi::Easy2Handle; use curl::multi::Multi; use futures::channel::oneshot; +use portable_atomic::AtomicI64; +use portable_atomic::AtomicU64; use tracing::{debug, error, trace, warn}; use crate::util::network::http::HandleConfiguration; From a31bfbffac8afd1d8169196ffc916c97dde4bcdb Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 18 Apr 2026 08:35:53 -0400 Subject: [PATCH 2/5] chore: enable `disallowed_types` lint We added this configuration but forgot to enabled it in lints See https://github.com/rust-lang/cargo/pull/12988 --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index ae93bd02d94..eb8112f99d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -139,6 +139,7 @@ all = { level = "allow", priority = -2 } correctness = { level = "warn", priority = -1 } dbg_macro = "warn" disallowed_methods = "warn" +disallowed_types = "warn" print_stderr = "warn" print_stdout = "warn" self_named_module_files = "warn" From d5c6b62fcbb5d707384e40f27917b1187ed7a0d1 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 18 Apr 2026 08:38:44 -0400 Subject: [PATCH 3/5] chore: disallow `AtomicI64` also --- clippy.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clippy.toml b/clippy.toml index dff120e9511..56c0dda4e01 100644 --- a/clippy.toml +++ b/clippy.toml @@ -7,5 +7,6 @@ disallowed-methods = [ { path = "std::env::vars_os", reason = "not recommended to use in Cargo. See rust-lang/cargo#11588" }, ] disallowed-types = [ - { path = "std::sync::atomic::AtomicU64", reason = "not portable. See rust-lang/cargo#12988" }, + { path = "std::sync::atomic::AtomicU64", reason = "not portable; See rust-lang/cargo#12988", replacement = "portable_atomic::AtomicU64" }, + { path = "std::sync::atomic::AtomicI64", reason = "not portable; See rust-lang/cargo#12988", replacement = "portable_atomic::AtomicI64" }, ] From 08f5545b3b7cde398892b43543d275173773530f Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 18 Apr 2026 10:04:39 -0400 Subject: [PATCH 4/5] refactor(cargo-util): move to portable-atomic This is a partial revert of 1d35833e3b62b17ced3ffcbcb7ceb6483b91b743 We also downgrade to `Ordering::Relaxed` since `ignore::WalkParallel` joins threads (while it is implementation details, it should otherwise a bug to whatever used its result after) --- Cargo.lock | 1 + crates/cargo-util/Cargo.toml | 1 + crates/cargo-util/src/du.rs | 20 ++++++++------------ 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5dad5918567..e36cd7f920f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -563,6 +563,7 @@ dependencies = [ "jobserver", "libc", "miow", + "portable-atomic", "same-file", "sha2 0.11.0", "shell-escape", diff --git a/crates/cargo-util/Cargo.toml b/crates/cargo-util/Cargo.toml index bfd67a54a23..c39c9c91749 100644 --- a/crates/cargo-util/Cargo.toml +++ b/crates/cargo-util/Cargo.toml @@ -12,6 +12,7 @@ anyhow.workspace = true filetime.workspace = true hex.workspace = true ignore.workspace = true +portable-atomic.workspace = true jobserver.workspace = true same-file.workspace = true sha2.workspace = true diff --git a/crates/cargo-util/src/du.rs b/crates/cargo-util/src/du.rs index 251acef0137..1c45b0e28d5 100644 --- a/crates/cargo-util/src/du.rs +++ b/crates/cargo-util/src/du.rs @@ -1,10 +1,13 @@ //! A simple disk usage estimator. +use std::path::Path; +use std::sync::atomic::Ordering; +use std::sync::{Arc, Mutex}; + use anyhow::{Context, Result}; use ignore::overrides::OverrideBuilder; use ignore::{WalkBuilder, WalkState}; -use std::path::Path; -use std::sync::{Arc, Mutex}; +use portable_atomic::AtomicU64; /// Determines the disk usage of all files in the given directory. /// @@ -40,12 +43,7 @@ fn du_inner(path: &Path, patterns: &[&str]) -> Result { .git_exclude(false); let walker = builder.build_parallel(); - // Platforms like PowerPC don't support AtomicU64, so we use a Mutex instead. - // - // See: - // - https://github.com/rust-lang/cargo/pull/12981 - // - https://github.com/rust-lang/rust/pull/117916#issuecomment-1812635848 - let total = Arc::new(Mutex::new(0u64)); + let total = Arc::new(AtomicU64::new(0)); // A slot used to indicate there was an error while walking. // @@ -58,8 +56,7 @@ fn du_inner(path: &Path, patterns: &[&str]) -> Result { Ok(entry) => match entry.metadata() { Ok(meta) => { if meta.is_file() { - let mut lock = total.lock().unwrap(); - *lock += meta.len(); + total.fetch_add(meta.len(), Ordering::Relaxed); } } Err(e) => { @@ -80,6 +77,5 @@ fn du_inner(path: &Path, patterns: &[&str]) -> Result { return Err(e); } - let total = *total.lock().unwrap(); - Ok(total) + Ok(total.load(Ordering::Relaxed)) } From 21bcb1d4a139236f0b0909f9c096ae0d0740afb3 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 18 Apr 2026 10:13:09 -0400 Subject: [PATCH 5/5] chore: remove `target_has_atomic` gate from `tracing-chrome` `tracing-chrome@0.7.2` switched to `AtomicUsize` so the cfg gate was unnecessary. hence enabling our internal profiling support on all platforms. See --- Cargo.toml | 4 +--- src/bin/cargo/main.rs | 19 ++----------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eb8112f99d4..257feade6a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -228,6 +228,7 @@ time.workspace = true toml = { workspace = true, features = ["std", "serde", "parse", "display", "preserve_order"] } toml_edit.workspace = true tracing = { workspace = true, features = ["attributes"] } +tracing-chrome.workspace = true tracing-subscriber.workspace = true unicase.workspace = true unicode-width.workspace = true @@ -236,9 +237,6 @@ url.workspace = true walkdir.workspace = true winnow.workspace = true -[target.'cfg(target_has_atomic = "64")'.dependencies] -tracing-chrome.workspace = true - [target.'cfg(unix)'.dependencies] libc.workspace = true diff --git a/src/bin/cargo/main.rs b/src/bin/cargo/main.rs index fb3b3ab4e80..76833ecaa8c 100644 --- a/src/bin/cargo/main.rs +++ b/src/bin/cargo/main.rs @@ -61,7 +61,7 @@ fn main() { } } -fn setup_logger() -> Option { +fn setup_logger() -> Option { use tracing_subscriber::prelude::*; let env = tracing_subscriber::EnvFilter::from_env("CARGO_LOG"); @@ -81,12 +81,9 @@ fn setup_logger() -> Option { profile_guard } -#[cfg(target_has_atomic = "64")] -type ChromeFlushGuard = tracing_chrome::FlushGuard; -#[cfg(target_has_atomic = "64")] fn chrome_layer() -> ( Option>, - Option, + Option, ) where S: tracing::Subscriber @@ -95,7 +92,6 @@ where + Sync, { #![expect(clippy::disallowed_methods, reason = "runs before config is loaded")] - if env_to_bool(std::env::var_os("CARGO_LOG_PROFILE").as_deref()) { let capture_args = env_to_bool(std::env::var_os("CARGO_LOG_PROFILE_CAPTURE_ARGS").as_deref()); @@ -108,17 +104,6 @@ where } } -#[cfg(not(target_has_atomic = "64"))] -type ChromeFlushGuard = (); -#[cfg(not(target_has_atomic = "64"))] -fn chrome_layer() -> ( - Option, - Option, -) { - (None, None) -} - -#[cfg(target_has_atomic = "64")] fn env_to_bool(os: Option<&OsStr>) -> bool { match os.and_then(|os| os.to_str()) { Some("1") | Some("true") => true,