Merge from rustc

This commit is contained in:
Ralf Jung 2025-05-17 09:53:02 +02:00
commit 8f2da9b487
610 changed files with 8883 additions and 6671 deletions

View file

@ -579,9 +579,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustix"
version = "1.0.2"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825"
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
dependencies = [
"bitflags",
"errno",

View file

@ -30,8 +30,6 @@ download-rustc = false
# Having this set to true disrupts compiler development workflows for people who use `llvm.download-ci-llvm = true`
# because we don't provide ci-llvm on the `rustc-alt-builds` server. Therefore, it is kept off by default.
assertions = false
# Enable warnings during the LLVM compilation (when LLVM is changed, causing a compilation)
enable-warnings = true
# Will download LLVM from CI if available on your platform.
# If you intend to modify `src/llvm-project`, use `"if-unchanged"` or `false` instead.
download-ci-llvm = true

View file

@ -58,8 +58,8 @@ fn main() {
let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
let on_fail = env::var_os("RUSTC_ON_FAIL").map(Command::new);
let rustc_real = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc));
let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir));
let rustc_real = env::var_os(rustc).unwrap_or_else(|| panic!("{rustc:?} was not set"));
let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{libdir:?} was not set"));
let mut dylib_path = dylib_path();
dylib_path.insert(0, PathBuf::from(&libdir));

View file

@ -129,7 +129,7 @@ fn clean_specific_stage(build: &Build, stage: u32) {
for entry in entries {
let entry = t!(entry);
let stage_prefix = format!("stage{}", stage);
let stage_prefix = format!("stage{stage}");
// if current entry is not related with the target stage, continue
if !entry.file_name().to_str().unwrap_or("").contains(&stage_prefix) {

View file

@ -59,7 +59,7 @@ fn lint_args(builder: &Builder<'_>, config: &LintConfig, ignored_rules: &[&str])
let all_args = std::env::args().collect::<Vec<_>>();
args.extend(get_clippy_rules_in_order(&all_args, config));
args.extend(ignored_rules.iter().map(|lint| format!("-Aclippy::{}", lint)));
args.extend(ignored_rules.iter().map(|lint| format!("-Aclippy::{lint}")));
args.extend(builder.config.free_args.clone());
args
}

View file

@ -1771,7 +1771,7 @@ impl Step for Sysroot {
} else if builder.download_rustc() && compiler.stage != builder.top_stage {
host_dir.join("ci-rustc-sysroot")
} else {
host_dir.join(format!("stage{}", stage))
host_dir.join(format!("stage{stage}"))
}
};
let sysroot = sysroot_dir(compiler.stage);

View file

@ -1403,14 +1403,14 @@ impl Step for CodegenBackend {
let backend = self.backend;
let mut tarball =
Tarball::new(builder, &format!("rustc-codegen-{}", backend), &compiler.host.triple);
Tarball::new(builder, &format!("rustc-codegen-{backend}"), &compiler.host.triple);
if backend == "cranelift" {
tarball.set_overlay(OverlayKind::RustcCodegenCranelift);
} else {
panic!("Unknown backend rustc_codegen_{}", backend);
panic!("Unknown backend rustc_codegen_{backend}");
}
tarball.is_preview(true);
tarball.add_legal_and_readme_to(format!("share/doc/rustc_codegen_{}", backend));
tarball.add_legal_and_readme_to(format!("share/doc/rustc_codegen_{backend}"));
let src = builder.sysroot(compiler);
let backends_src = builder.sysroot_codegen_backends(compiler);
@ -1422,7 +1422,7 @@ impl Step for CodegenBackend {
// Don't use custom libdir here because ^lib/ will be resolved again with installer
let backends_dst = PathBuf::from("lib").join(backends_rel);
let backend_name = format!("rustc_codegen_{}", backend);
let backend_name = format!("rustc_codegen_{backend}");
let mut found_backend = false;
for backend in fs::read_dir(&backends_src).unwrap() {
let file_name = backend.unwrap().file_name();
@ -1623,7 +1623,7 @@ impl Step for Extended {
let pkgbuild = |component: &str| {
let mut cmd = command("pkgbuild");
cmd.arg("--identifier")
.arg(format!("org.rust-lang.{}", component))
.arg(format!("org.rust-lang.{component}"))
.arg("--scripts")
.arg(pkg.join(component))
.arg("--nopayload")

View file

@ -58,7 +58,7 @@ fn rustfmt(
fn get_rustfmt_version(build: &Builder<'_>) -> Option<(String, BuildStamp)> {
let stamp_file = BuildStamp::new(&build.out).with_prefix("rustfmt");
let mut cmd = command(build.initial_rustfmt()?);
let mut cmd = command(build.config.initial_rustfmt.as_ref()?);
cmd.arg("--version");
let output = cmd.allow_failure().run_capture(build);
@ -243,7 +243,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
let override_ = override_builder.build().unwrap(); // `override` is a reserved keyword
let rustfmt_path = build.initial_rustfmt().unwrap_or_else(|| {
let rustfmt_path = build.config.initial_rustfmt.clone().unwrap_or_else(|| {
eprintln!("fmt error: `x fmt` is not supported on this channel");
crate::exit!(1);
});

View file

@ -53,7 +53,7 @@ fn is_dir_writable_for_user(dir: &Path) -> bool {
if e.kind() == std::io::ErrorKind::PermissionDenied {
false
} else {
panic!("Failed the write access check for the current user. {}", e);
panic!("Failed the write access check for the current user. {e}");
}
}
}

View file

@ -870,8 +870,8 @@ fn get_var(var_base: &str, host: &str, target: &str) -> Option<OsString> {
let kind = if host == target { "HOST" } else { "TARGET" };
let target_u = target.replace('-', "_");
env::var_os(format!("{var_base}_{target}"))
.or_else(|| env::var_os(format!("{}_{}", var_base, target_u)))
.or_else(|| env::var_os(format!("{}_{}", kind, var_base)))
.or_else(|| env::var_os(format!("{var_base}_{target_u}")))
.or_else(|| env::var_os(format!("{kind}_{var_base}")))
.or_else(|| env::var_os(var_base))
}
@ -944,7 +944,7 @@ impl Step for Enzyme {
}
trace!(?target, "(re)building enzyme artifacts");
builder.info(&format!("Building Enzyme for {}", target));
builder.info(&format!("Building Enzyme for {target}"));
t!(stamp.remove());
let _time = helpers::timeit(builder);
t!(fs::create_dir_all(&out_dir));
@ -1229,10 +1229,9 @@ fn supported_sanitizers(
components
.iter()
.map(move |c| SanitizerRuntime {
cmake_target: format!("clang_rt.{}_{}_dynamic", c, os),
path: out_dir
.join(format!("build/lib/darwin/libclang_rt.{}_{}_dynamic.dylib", c, os)),
name: format!("librustc-{}_rt.{}.dylib", channel, c),
cmake_target: format!("clang_rt.{c}_{os}_dynamic"),
path: out_dir.join(format!("build/lib/darwin/libclang_rt.{c}_{os}_dynamic.dylib")),
name: format!("librustc-{channel}_rt.{c}.dylib"),
})
.collect()
};
@ -1241,9 +1240,9 @@ fn supported_sanitizers(
components
.iter()
.map(move |c| SanitizerRuntime {
cmake_target: format!("clang_rt.{}-{}", c, arch),
path: out_dir.join(format!("build/lib/{}/libclang_rt.{}-{}.a", os, c, arch)),
name: format!("librustc-{}_rt.{}.a", channel, c),
cmake_target: format!("clang_rt.{c}-{arch}"),
path: out_dir.join(format!("build/lib/{os}/libclang_rt.{c}-{arch}.a")),
name: format!("librustc-{channel}_rt.{c}.a"),
})
.collect()
};
@ -1362,8 +1361,8 @@ impl Step for CrtBeginEnd {
for obj in objs {
let base_name = unhashed_basename(&obj);
assert!(base_name == "crtbegin" || base_name == "crtend");
t!(fs::copy(&obj, out_dir.join(format!("{}S.o", base_name))));
t!(fs::rename(&obj, out_dir.join(format!("{}.o", base_name))));
t!(fs::copy(&obj, out_dir.join(format!("{base_name}S.o"))));
t!(fs::rename(&obj, out_dir.join(format!("{base_name}.o"))));
}
out_dir

View file

@ -552,7 +552,7 @@ Select which editor you would like to set up [default: None]: ";
let mut input = String::new();
loop {
print!("{}", prompt_str);
print!("{prompt_str}");
io::stdout().flush()?;
io::stdin().read_line(&mut input)?;
@ -764,7 +764,7 @@ fn create_editor_settings_maybe(config: &Config, editor: &EditorKind) -> io::Res
_ => "Created",
};
fs::write(&settings_path, editor.settings_template())?;
println!("{verb} `{}`", settings_filename);
println!("{verb} `{settings_filename}`");
} else {
println!("\n{}", editor.settings_template());
}

View file

@ -1102,7 +1102,7 @@ impl Step for Tidy {
if builder.config.channel == "dev" || builder.config.channel == "nightly" {
if !builder.config.json_output {
builder.info("fmt check");
if builder.initial_rustfmt().is_none() {
if builder.config.initial_rustfmt.is_none() {
let inferred_rustfmt_dir = builder.initial_sysroot.join("bin");
eprintln!(
"\
@ -1593,10 +1593,10 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
let build = builder.build.build;
compiler = builder.compiler(compiler.stage - 1, build);
let test_stage = compiler.stage + 1;
(test_stage, format!("stage{}-{}", test_stage, build))
(test_stage, format!("stage{test_stage}-{build}"))
} else {
let stage = compiler.stage;
(stage, format!("stage{}-{}", stage, target))
(stage, format!("stage{stage}-{target}"))
};
if suite.ends_with("fulldeps") {

View file

@ -1278,5 +1278,5 @@ impl Builder<'_> {
pub fn cargo_profile_var(name: &str, config: &Config) -> String {
let profile = if config.rust_optimize.is_release() { "RELEASE" } else { "DEV" };
format!("CARGO_PROFILE_{}_{}", profile, name)
format!("CARGO_PROFILE_{profile}_{name}")
}

View file

@ -504,8 +504,8 @@ impl StepDescription {
match std::path::absolute(p) {
Ok(p) => p.strip_prefix(&builder.src).unwrap_or(&p).to_path_buf(),
Err(e) => {
eprintln!("ERROR: {:?}", e);
panic!("Due to the above error, failed to resolve path: {:?}", p);
eprintln!("ERROR: {e:?}");
panic!("Due to the above error, failed to resolve path: {p:?}");
}
}
})
@ -694,8 +694,7 @@ impl<'a> ShouldRun<'a> {
if !submodules_paths.iter().any(|sm_p| p.contains(sm_p)) {
assert!(
self.builder.src.join(p).exists(),
"`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {}",
p
"`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {p}"
);
}

View file

@ -3,7 +3,7 @@
//! This module implements parsing `bootstrap.toml` configuration files to tweak
//! how the build runs.
use std::cell::{Cell, RefCell};
use std::cell::Cell;
use std::collections::{BTreeSet, HashMap, HashSet};
use std::fmt::{self, Display};
use std::hash::Hash;
@ -406,11 +406,7 @@ pub struct Config {
pub initial_rustc: PathBuf,
pub initial_cargo_clippy: Option<PathBuf>,
pub initial_sysroot: PathBuf,
#[cfg(not(test))]
initial_rustfmt: RefCell<RustfmtState>,
#[cfg(test)]
pub initial_rustfmt: RefCell<RustfmtState>,
pub initial_rustfmt: Option<PathBuf>,
/// The paths to work with. For example: with `./x check foo bar` we get
/// `paths=["foo", "bar"]`.
@ -428,15 +424,6 @@ pub struct Config {
pub path_modification_cache: Arc<Mutex<HashMap<Vec<&'static str>, PathFreshness>>>,
}
#[derive(Clone, Debug, Default)]
pub enum RustfmtState {
SystemToolchain(PathBuf),
Downloaded(PathBuf),
Unavailable,
#[default]
LazyEvaluated,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum LlvmLibunwind {
#[default]
@ -2448,13 +2435,8 @@ impl Config {
});
}
if let Some(r) = rustfmt {
*config.initial_rustfmt.borrow_mut() = if r.exists() {
RustfmtState::SystemToolchain(r)
} else {
RustfmtState::Unavailable
};
}
config.initial_rustfmt =
if let Some(r) = rustfmt { Some(r) } else { config.maybe_download_rustfmt() };
// Now that we've reached the end of our configuration, infer the
// default values for all options that we haven't otherwise stored yet.
@ -2851,25 +2833,6 @@ impl Config {
.as_deref()
}
pub(crate) fn initial_rustfmt(&self) -> Option<PathBuf> {
match &mut *self.initial_rustfmt.borrow_mut() {
RustfmtState::SystemToolchain(p) | RustfmtState::Downloaded(p) => Some(p.clone()),
RustfmtState::Unavailable => None,
r @ RustfmtState::LazyEvaluated => {
if self.dry_run() {
return Some(PathBuf::new());
}
let path = self.maybe_download_rustfmt();
*r = if let Some(p) = &path {
RustfmtState::Downloaded(p.clone())
} else {
RustfmtState::Unavailable
};
path
}
}
}
/// Runs a function if verbosity is greater than 0
pub fn verbose(&self, f: impl Fn()) {
if self.is_verbose() {
@ -3042,7 +3005,7 @@ impl Config {
let actual_hash = recorded
.split_whitespace()
.nth(2)
.unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
.unwrap_or_else(|| panic!("unexpected output `{recorded}`"));
if actual_hash == checked_out_hash {
// already checked out
@ -3297,7 +3260,7 @@ impl Config {
}
StringOrBool::String(s) if s == "if-unchanged" => if_unchanged(),
StringOrBool::String(other) => {
panic!("unrecognized option for download-ci-llvm: {:?}", other)
panic!("unrecognized option for download-ci-llvm: {other:?}")
}
}
}

View file

@ -57,7 +57,7 @@ impl Config {
if self.dry_run() {
return;
}
fs::remove_file(f).unwrap_or_else(|_| panic!("failed to remove {:?}", f));
fs::remove_file(f).unwrap_or_else(|_| panic!("failed to remove {f:?}"));
}
/// Create a temporary directory in `out` and return its path.
@ -112,7 +112,7 @@ impl Config {
// The latter one does not exist on NixOS when using tmpfs as root.
let is_nixos = match File::open("/etc/os-release") {
Err(e) if e.kind() == ErrorKind::NotFound => false,
Err(e) => panic!("failed to access /etc/os-release: {}", e),
Err(e) => panic!("failed to access /etc/os-release: {e}"),
Ok(os_release) => BufReader::new(os_release).lines().any(|l| {
let l = l.expect("reading /etc/os-release");
matches!(l.trim(), "ID=nixos" | "ID='nixos'" | "ID=\"nixos\"")
@ -446,7 +446,7 @@ impl Config {
#[cfg(test)]
pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
None
Some(PathBuf::new())
}
/// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't
@ -455,6 +455,10 @@ impl Config {
pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
use build_helper::stage0_parser::VersionMetadata;
if self.dry_run() {
return Some(PathBuf::new());
}
let VersionMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?;
let channel = format!("{version}-{date}");

View file

@ -34,7 +34,6 @@ pub struct Finder {
// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
const STAGE0_MISSING_TARGETS: &[&str] = &[
// just a dummy comment so the list doesn't get onelined
"x86_64-lynx-lynxos178",
];
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
@ -118,8 +117,8 @@ pub fn check(build: &mut Build) {
eprintln!(
"\nYour system's libstdc++ version is too old for the `llvm.download-ci-llvm` option."
);
eprintln!("Current version detected: '{}'", version);
eprintln!("Minimum required version: '{}'", LIBSTDCXX_MIN_VERSION_THRESHOLD);
eprintln!("Current version detected: '{version}'");
eprintln!("Minimum required version: '{LIBSTDCXX_MIN_VERSION_THRESHOLD}'");
eprintln!(
"Consider upgrading libstdc++ or disabling the `llvm.download-ci-llvm` option."
);

View file

@ -325,7 +325,6 @@ forward! {
tempdir() -> PathBuf,
llvm_link_shared() -> bool,
download_rustc() -> bool,
initial_rustfmt() -> Option<PathBuf>,
}
impl Build {
@ -614,10 +613,6 @@ impl Build {
crate::utils::job::setup(self);
}
// Download rustfmt early so that it can be used in rust-analyzer configs.
trace!("downloading rustfmt early");
let _ = &builder::Builder::new(self).initial_rustfmt();
// Handle hard-coded subcommands.
{
#[cfg(feature = "tracing")]

View file

@ -329,7 +329,7 @@ pub fn start_process(cmd: &mut Command) -> impl FnOnce() -> String + use<> {
Err(e) => fail(&format!("failed to execute command: {cmd:?}\nERROR: {e}")),
};
let command = format!("{:?}", cmd);
let command = format!("{cmd:?}");
move || {
let output = child.wait_with_output().unwrap();
@ -540,7 +540,7 @@ where
use std::fmt::Write;
input.as_ref().iter().fold(String::with_capacity(input.as_ref().len() * 2), |mut acc, &byte| {
write!(&mut acc, "{:02x}", byte).expect("Failed to write byte to the hex String.");
write!(&mut acc, "{byte:02x}").expect("Failed to write byte to the hex String.");
acc
})
}

View file

@ -90,7 +90,7 @@ pub fn maybe_dump(dump_name: String, cmd: &Command) {
let mut file = OpenOptions::new().create(true).append(true).open(dump_file).unwrap();
let cmd_dump = format!("{:?}\n", cmd);
let cmd_dump = format!("{cmd:?}\n");
let cmd_dump = cmd_dump.replace(&env::var("BUILD_OUT").unwrap(), "${BUILD_OUT}");
let cmd_dump = cmd_dump.replace(&env::var("CARGO_HOME").unwrap(), "${CARGO_HOME}");

View file

@ -170,7 +170,7 @@ print("Time,Idle")
while True:
time.sleep(1)
next_state = State()
now = datetime.datetime.utcnow().isoformat()
now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None).isoformat()
idle = next_state.idle_since(cur_state)
print("%s,%s" % (now, idle))
sys.stdout.flush()

View file

@ -35,6 +35,8 @@ runners:
os: windows-2022
<<: *base-job
# FIXME(#141022): Windows Server 2025 20250504.1.0 currently experiences
# insufficient disk space.
- &job-windows-25
os: windows-2025
<<: *base-job
@ -476,13 +478,17 @@ auto:
env:
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-sanitizers --enable-profiler
SCRIPT: make ci-msvc-py
<<: *job-windows-25
# FIXME(#141022): Windows Server 2025 20250504.1.0 currently experiences
# insufficient disk space.
<<: *job-windows
- name: x86_64-msvc-2
env:
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-sanitizers --enable-profiler
SCRIPT: make ci-msvc-ps1
<<: *job-windows-25
# FIXME(#141022): Windows Server 2025 20250504.1.0 currently experiences
# insufficient disk space.
<<: *job-windows
# i686-msvc is split into two jobs to run tests in parallel.
- name: i686-msvc-1

View file

@ -91,6 +91,16 @@ Older versions of `josh-proxy` may not round trip commits losslessly so it is im
3) Push the branch to your fork and create a PR into `rustc-dev-guide`
### Push changes from this repository into `rust-lang/rust`
NOTE: If you use Git protocol to push to your fork of `rust-lang/rust`,
ensure that you have this entry in your Git config,
else the 2 steps that follow would prompt for a username and password:
```
[url "git@github.com:"]
insteadOf = "https://github.com/"
```
1) Run the push command to create a branch named `<branch-name>` in a `rustc` fork under the `<gh-username>` account
```
cargo run --manifest-path josh-sync/Cargo.toml rustc-push <branch-name> <gh-username>

View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "aho-corasick"
@ -28,21 +28,24 @@ dependencies = [
[[package]]
name = "autocfg"
version = "1.3.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bumpalo"
version = "3.16.0"
version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "cc"
version = "1.0.106"
version = "1.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "066fce287b1d4eafef758e89e09d724a24808a9196fe9756b8ca90e86d0719a2"
checksum = "32db95edf998450acc7881c932f94cd9b05c87b4b2599e8bab064753da4acfd1"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
@ -52,27 +55,27 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.38"
version = "0.4.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets",
"windows-link",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "date-check"
version = "0.1.0"
version = "0.0.0"
dependencies = [
"chrono",
"glob",
@ -81,20 +84,21 @@ dependencies = [
[[package]]
name = "glob"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "iana-time-zone"
version = "0.1.60"
version = "0.1.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
@ -110,24 +114,25 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.69"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.155"
version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "log"
version = "0.4.22"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
@ -146,33 +151,33 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.19.0"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "proc-macro2"
version = "1.0.86"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.36"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.10.5"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
@ -182,9 +187,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.7"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
@ -193,15 +198,27 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.8.4"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustversion"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.70"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
@ -210,29 +227,30 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.12"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "wasm-bindgen"
version = "0.2.92"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.92"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
@ -241,9 +259,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.92"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -251,9 +269,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.92"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
@ -264,79 +282,68 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.92"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
"unicode-ident",
]
[[package]]
name = "windows-core"
version = "0.52.0"
version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
dependencies = [
"windows-targets",
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
name = "windows-implement"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
name = "windows-interface"
version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
name = "windows-link"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
name = "windows-result"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
dependencies = [
"windows-link",
]
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
name = "windows-strings"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
dependencies = [
"windows-link",
]

View file

@ -1,10 +1,6 @@
[package]
name = "date-check"
version = "0.1.0"
authors = ["Noah Lev <camelidcamel@gmail.com>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
edition = "2024"
[dependencies]
glob = "0.3"

View file

@ -114,7 +114,7 @@ fn filter_dates(
fn main() {
let mut args = env::args();
if args.len() == 1 {
eprintln!("error: expected root Markdown directory as CLI argument");
eprintln!("error: expected root of Markdown directory as CLI argument");
process::exit(1);
}
let root_dir = args.nth(1).unwrap();

View file

@ -161,7 +161,7 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "josh-sync"
version = "0.1.0"
version = "0.0.0"
dependencies = [
"anyhow",
"clap",

View file

@ -1,7 +1,6 @@
[package]
name = "josh-sync"
version = "0.1.0"
edition = "2021"
edition = "2024"
[dependencies]
anyhow = "1.0.95"

View file

@ -1,4 +1,5 @@
use clap::Parser;
use crate::sync::{GitSync, RustcPullError};
mod sync;
@ -11,10 +12,7 @@ enum Args {
/// Push changes from `rustc-dev-guide` to the given `branch` of a `rustc` fork under the given
/// GitHub `username`.
/// The pushed branch should then be merged into the `rustc` repository.
RustcPush {
branch: String,
github_username: String
}
RustcPush { branch: String, github_username: String },
}
fn main() -> anyhow::Result<()> {

View file

@ -1,10 +1,11 @@
use std::io::Write;
use std::ops::Not;
use std::path::PathBuf;
use std::{env, net, process};
use std::io::Write;
use std::time::Duration;
use anyhow::{anyhow, bail, Context};
use xshell::{cmd, Shell};
use std::{env, net, process};
use anyhow::{Context, anyhow, bail};
use xshell::{Shell, cmd};
/// Used for rustc syncs.
const JOSH_FILTER: &str = ":/src/doc/rustc-dev-guide";
@ -15,10 +16,13 @@ pub enum RustcPullError {
/// No changes are available to be pulled.
NothingToPull,
/// A rustc-pull has failed, probably a git operation error has occurred.
PullFailed(anyhow::Error)
PullFailed(anyhow::Error),
}
impl<E> From<E> for RustcPullError where E: Into<anyhow::Error> {
impl<E> From<E> for RustcPullError
where
E: Into<anyhow::Error>,
{
fn from(error: E) -> Self {
Self::PullFailed(error.into())
}
@ -32,9 +36,7 @@ pub struct GitSync {
/// (https://github.com/rust-lang/miri/blob/6a68a79f38064c3bc30617cca4bdbfb2c336b140/miri-script/src/commands.rs#L236).
impl GitSync {
pub fn from_current_dir() -> anyhow::Result<Self> {
Ok(Self {
dir: std::env::current_dir()?
})
Ok(Self { dir: std::env::current_dir()? })
}
pub fn rustc_pull(&self, commit: Option<String>) -> Result<(), RustcPullError> {
@ -51,7 +53,10 @@ impl GitSync {
})?;
// Make sure the repo is clean.
if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() {
return Err(anyhow::anyhow!("working directory must be clean before performing rustc pull").into());
return Err(anyhow::anyhow!(
"working directory must be clean before performing rustc pull"
)
.into());
}
// Make sure josh is running.
let josh = Self::start_josh()?;
@ -94,7 +99,8 @@ impl GitSync {
};
let num_roots_before = num_roots()?;
let sha = cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout;
let sha =
cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout;
// Merge the fetched commit.
const MERGE_COMMIT_MESSAGE: &str = "Merge from rustc";
@ -102,18 +108,24 @@ impl GitSync {
.run()
.context("FAILED to merge new commits, something went wrong")?;
let current_sha = cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout;
let current_sha =
cmd!(sh, "git rev-parse HEAD").output().context("FAILED to get current commit")?.stdout;
if current_sha == sha {
cmd!(sh, "git reset --hard HEAD^")
.run()
.expect("FAILED to clean up after creating the preparation commit");
eprintln!("No merge was performed, no changes to pull were found. Rolled back the preparation commit.");
eprintln!(
"No merge was performed, no changes to pull were found. Rolled back the preparation commit."
);
return Err(RustcPullError::NothingToPull);
}
// Check that the number of roots did not increase.
if num_roots()? != num_roots_before {
return Err(anyhow::anyhow!("Josh created a new root commit. This is probably not the history you want.").into());
return Err(anyhow::anyhow!(
"Josh created a new root commit. This is probably not the history you want."
)
.into());
}
drop(josh);

View file

@ -1 +1 @@
0c33fe2c3d3eecadd17a84b110bb067288a64f1c
414482f6a0d4e7290f614300581a0b55442552a3

View file

@ -1,6 +1,6 @@
# Installation
In the near future, `std::autodiff` should become available in nightly builds for users. As a contribute however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you succesfully build this project on a tier2/tier3 target.
In the near future, `std::autodiff` should become available in nightly builds for users. As a contributor however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you successfully build this project on a tier2/tier3 target.
## Build instructions

View file

@ -80,41 +80,11 @@ approachable and practical; it may make sense to direct users to an RFC or some
other issue for the full details. The issue also serves as a place where users
can comment with questions or other concerns.
A template for these breaking-change tracking issues can be found below. An
example of how such an issue should look can be [found
A template for these breaking-change tracking issues can be found
[here][template]. An example of how such an issue should look can be [found
here][breaking-change-issue].
The issue should be tagged with (at least) `B-unstable` and `T-compiler`.
### Tracking issue template
This is a template to use for tracking issues:
```
This is the **summary issue** for the `YOUR_LINT_NAME_HERE`
future-compatibility warning and other related errors. The goal of
this page is describe why this change was made and how you can fix
code that is affected by it. It also provides a place to ask questions
or register a complaint if you feel the change should not be made. For
more information on the policy around future-compatibility warnings,
see our [breaking change policy guidelines][guidelines].
[guidelines]: LINK_TO_THIS_RFC
#### What is the warning for?
*Describe the conditions that trigger the warning and how they can be
fixed. Also explain why the change was made.**
#### When will this warning become a hard error?
At the beginning of each 6-week release cycle, the Rust compiler team
will review the set of outstanding future compatibility warnings and
nominate some of them for **Final Comment Period**. Toward the end of
the cycle, we will review any comments and make a final determination
whether to convert the warning into a hard error or remove it
entirely.
```
[template]: https://github.com/rust-lang/rust/issues/new?template=tracking_issue_future.md
### Issuing future compatibility warnings

View file

@ -2,9 +2,6 @@
<!-- toc -->
> N.B. [`rustc_ast`], [`rustc_expand`], and [`rustc_builtin_macros`] are all
> undergoing refactoring, so some of the links in this chapter may be broken.
Rust has a very powerful macro system. In the previous chapter, we saw how
the parser sets aside macros to be expanded (using temporary [placeholders]).
This chapter is about the process of expanding those macros iteratively until
@ -12,9 +9,6 @@ we have a complete [*Abstract Syntax Tree* (AST)][ast] for our crate with no
unexpanded macros (or a compile error).
[ast]: ./ast-validation.md
[`rustc_ast`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/index.html
[`rustc_expand`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/index.html
[`rustc_builtin_macros`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_builtin_macros/index.html
[placeholders]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/placeholders/index.html
First, we discuss the algorithm that expands and integrates macro output into

View file

@ -55,8 +55,8 @@ The first step in [`clean::utils::krate`][ck1] is to invoke
* inlining public `use` exports of private items, or showing a "Reexport"
line in the module page
* inlining items with `#[doc(hidden)]` if the base item is hidden but the
* showing `#[macro_export]`-ed macros at the crate root, regardless of where
they're defined reexport is not
* showing `#[macro_export]`-ed macros at the crate root, regardless of whether
they're defined as a reexport or not
After this step, `clean::krate` invokes [`clean_doc_module`], which actually
converts the `HIR` items to the cleaned [`AST`][ast]. This is also the step where cross-

View file

@ -16,10 +16,10 @@ In addition to the directives listed here,
`rustdoc` tests also support most
[compiletest directives](../tests/directives.html).
All `PATH`s in directives are relative to the the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`),
All `PATH`s in directives are relative to the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`),
so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid
having to write a long crate name multiple times.
To avoid repetion, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument.
To avoid repetition, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument.
All arguments take the form of quoted strings
(both single and double quotes are supported),
@ -87,7 +87,7 @@ compiletest's `--bless` flag is forwarded to htmldocck.
Usage: `//@ has-dir PATH`
Checks for the existance of directory `PATH`.
Checks for the existence of directory `PATH`.
### `files`
@ -106,7 +106,7 @@ Example: `//@ files "foo/bar" '["index.html", "sidebar-items.js"]'`
## Limitations
`htmldocck.py` uses the xpath implementation from the standard library.
This leads to several limitations:
* All `XPATH` arguments must start with `//` due to a flaw in the implemention.
* All `XPATH` arguments must start with `//` due to a flaw in the implementation.
* Many XPath features (functions, axies, etc.) are not supported.
* Only well-formed HTML can be parsed (hopefully rustdoc doesn't output mismatched tags).

View file

@ -169,7 +169,7 @@ The `LazyArray<[T]>` and `LazyTable<I, T>` types provide some functionality over
than the one being read.
**note**: `LazyValue<T>` does not cache its value after being deserialized the
first time. Instead the query system its self is the main way of caching these
first time. Instead the query system itself is the main way of caching these
results.
[`LazyArray<T>`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/struct.LazyValue.html

View file

@ -70,6 +70,11 @@ related tests.
> //!
> //! Regression test for <https://github.com/rust-lang/rust/issues/123456>.
> ```
>
> One exception to this rule is [crashes tests]: there it is canonical that
> tests are named only after issue numbers because its purpose is to track
> snippets from which issues no longer ICE/crash, and they would either be
> removed or converted into proper ui/other tests in the fix PRs.
## Test organization
@ -194,3 +199,4 @@ See [LLVM FileCheck guide][FileCheck] for details.
[compiletest directives]: ./directives.md
[`run-make`]: ./compiletest.md#run-make-tests
[FileCheck]: https://llvm.org/docs/CommandGuide/FileCheck.html
[crashes tests]: ./compiletest.md#crashes-tests

View file

@ -102,11 +102,12 @@ by passing a path to a book to `./x test`.
### Documentation link checker
Links across all documentation is validated with a link checker tool.
Links across all documentation is validated with a link checker tool,
and it can be invoked so:
> Example: `./x test src/tools/linkchecker`
> Example: `./x test linkchecker`
```console
./x test linkchecker
```
This requires building all of the documentation, which might take a while.

View file

@ -32,21 +32,21 @@ Built-in implementations are provided for:
## Structural implementations
There are two implementations of `Unsize` which can be thought of as
There is one implementation of `Unsize` which can be thought of as
structural:
* `(A1, A2, .., An): Unsize<(A1, A2, .., U)>` given `An: Unsize<U>`, which
allows the tail field of a tuple to be unsized. This is gated behind the
[`unsized_tuple_coercion`] feature.
* `Struct<.., Pi, .., Pj, ..>: Unsize<Struct<.., Ui, .., Uj, ..>>` given
`TailField<Pi, .., Pj>: Unsize<Ui, .. Uj>`, which allows the tail field of a
struct to be unsized if it is the only field that mentions generic parameters
`Pi`, .., `Pj` (which don't need to be contiguous).
The rules for the latter implementation are slightly complicated, since they
The rules for struct unsizing are slightly complicated, since they
may allow more than one parameter to be changed (not necessarily unsized) and
are best stated in terms of the tail field of the struct.
[`unsized_tuple_coercion`]: https://doc.rust-lang.org/beta/unstable-book/language-features/unsized-tuple-coercion.html
(Tuple unsizing was previously implemented behind the feature gate
`unsized_tuple_coercion`, but the implementation was removed by [#137728].)
[#137728]: https://github.com/rust-lang/rust/pull/137728
## Upcasting implementations

View file

@ -1,26 +1,28 @@
<!-- date-check: may 2024 -->
# `TypeFoldable` and `TypeFolder`
In the previous chapter we discussed instantiating binders. This must involves looking at everything inside of a `Early/Binder`
to find any usages of the bound vars in order to replace them. Binders can wrap an arbitrary rust type `T` not just a `Ty` so
how do we implement the `instantiate` methods on the `Early/Binder` types.
In [a previous chapter], we discussed instantiating binders.
This involves looking at everything inside of a `Early(Binder)`
to find any usages of the bound vars in order to replace them.
Binders can wrap an arbitrary Rust type `T`, not just a `Ty`.
So, how do we implement the `instantiate` methods on the `Early/Binder` types?
The answer is a couple of traits:
[`TypeFoldable`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFoldable.html)
[`TypeFoldable`]
and
[`TypeFolder`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFolder.html).
[`TypeFolder`].
- `TypeFoldable` is implemented by types that embed type information. It allows you to recursively
process the contents of the `TypeFoldable` and do stuff to them.
- `TypeFolder` defines what you want to do with the types you encounter while processing the
`TypeFoldable`.
For example, the `TypeFolder` trait has a method
[`fold_ty`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFolder.html#method.fold_ty)
that takes a type as input and returns a new type as a result. `TypeFoldable` invokes the
`TypeFolder` `fold_foo` methods on itself, giving the `TypeFolder` access to its contents (the
types, regions, etc that are contained within).
For example, the `TypeFolder` trait has a method [`fold_ty`]
that takes a type as input and returns a new type as a result.
`TypeFoldable` invokes the `TypeFolder` `fold_foo` methods on itself,
giving the `TypeFolder` access to its contents (the types, regions, etc that are contained within).
You can think of it with this analogy to the iterator combinators we have come to love in rust:
You can think of it with this analogy to the iterator combinators we have come to love in Rust:
```rust,ignore
vec.iter().map(|e1| foo(e2)).collect()
@ -33,8 +35,7 @@ So to reiterate:
- `TypeFolder` is a trait that defines a “map” operation.
- `TypeFoldable` is a trait that is implemented by things that embed types.
In the case of `subst`, we can see that it is implemented as a `TypeFolder`:
[`ArgFolder`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/binder/struct.ArgFolder.html).
In the case of `subst`, we can see that it is implemented as a `TypeFolder`: [`ArgFolder`].
Looking at its implementation, we see where the actual substitutions are happening.
However, you might also notice that the implementation calls this `super_fold_with` method. What is
@ -88,17 +89,22 @@ things. We only want to do something when we reach a type. That means there may
`TypeFoldable` types whose implementations basically just forward to their fields `TypeFoldable`
implementations. Such implementations of `TypeFoldable` tend to be pretty tedious to write by hand.
For this reason, there is a `derive` macro that allows you to `#![derive(TypeFoldable)]`. It is
defined
[here](https://github.com/rust-lang/rust/blob/master/compiler/rustc_macros/src/type_foldable.rs).
defined [here].
**`subst`** In the case of substitutions the [actual
folder](https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L440-L451)
is going to be doing the indexing weve already mentioned. There we define a `Folder` and call
`fold_with` on the `TypeFoldable` to process yourself. Then
[fold_ty](https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L512-L536)
the method that process each type it looks for a `ty::Param` and for those it replaces it for
something from the list of substitutions, otherwise recursively process the type. To replace it,
calls
[ty_for_param](https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L552-L587)
**`subst`** In the case of substitutions the [actual folder]
is going to be doing the indexing weve already mentioned.
There we define a `Folder` and call `fold_with` on the `TypeFoldable` to process yourself.
Then [fold_ty] the method that process each type it looks for a `ty::Param` and for those
it replaces it for something from the list of substitutions, otherwise recursively process the type.
To replace it, calls [ty_for_param]
and all that does is index into the list of substitutions with the index of the `Param`.
[a previous chapter]: ty_module/instantiating_binders.md
[`TypeFoldable`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFoldable.html
[`TypeFolder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFolder.html
[`fold_ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFolder.html#method.fold_ty
[`ArgFolder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/binder/struct.ArgFolder.html
[here]: https://github.com/rust-lang/rust/blob/master/compiler/rustc_macros/src/type_foldable.rs
[actual folder]: https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L440-L451
[fold_ty]: https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L512-L536
[ty_for_param]: https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L552-L587

View file

@ -17,7 +17,7 @@ Type "collection" is the process of converting the types found in the HIR
**internal representation** used by the compiler (`Ty<'tcx>`) we also do
similar conversions for where-clauses and other bits of the function signature.
To try and get a sense for the difference, consider this function:
To try and get a sense of the difference, consider this function:
```rust,ignore
struct Foo { }

View file

@ -19,7 +19,7 @@ Here, the type of `things` is *inferred* to be `Vec<&str>` because of the value
we push into `things`.
The type inference is based on the standard Hindley-Milner (HM) type inference
algorithm, but extended in various way to accommodate subtyping, region
algorithm, but extended in various ways to accommodate subtyping, region
inference, and higher-ranked types.
## A note on terminology

View file

@ -4,7 +4,7 @@
## Typing Environments
When interacting with the type system there are a few variables to consider that can affect the results of trait solving. The the set of in-scope where clauses, and what phase of the compiler type system operations are being performed in (the [`ParamEnv`][penv] and [`TypingMode`][tmode] structs respectively).
When interacting with the type system there are a few variables to consider that can affect the results of trait solving. The set of in-scope where clauses, and what phase of the compiler type system operations are being performed in (the [`ParamEnv`][penv] and [`TypingMode`][tmode] structs respectively).
When an environment to perform type system operations in has not yet been created, the [`TypingEnv`][tenv] can be used to bundle all of the external context required into a single type.
@ -13,11 +13,11 @@ Once a context to perform type system operations in has been created (e.g. an [`
[ocx]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/struct.ObligationCtxt.html
[fnctxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html
## Parameter Environemnts
## Parameter Environments
### What is a `ParamEnv`
The [`ParamEnv`][penv] is a list of in-scope where-clauses, it typically corresponds to a specific item's where clauses. Some clauses are not explicitly written but are instead are implicitly added in the [`predicates_of`][predicates_of] query, such as `ConstArgHasType` or (some) implied bounds.
The [`ParamEnv`][penv] is a list of in-scope where-clauses, it typically corresponds to a specific item's where clauses. Some clauses are not explicitly written but are instead implicitly added in the [`predicates_of`][predicates_of] query, such as `ConstArgHasType` or (some) implied bounds.
In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. A `ParamEnv` can also be created with arbitrary sets of clauses that are not derived from a specific item, such as in [`compare_method_predicate_entailment`][method_pred_entailment] where we create a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses.
@ -73,7 +73,7 @@ fn foo2<T>(a: T) {
### Acquiring a `ParamEnv`
Using the wrong [`ParamEnv`][penv] when interacting with the type system can lead to ICEs, illformed programs compiling, or erroing when we shouldn't. See [#82159](https://github.com/rust-lang/rust/pull/82159) and [#82067](https://github.com/rust-lang/rust/pull/82067) as examples of PRs that modified the compiler to use the correct param env and in the process fixed ICEs.
Using the wrong [`ParamEnv`][penv] when interacting with the type system can lead to ICEs, illformed programs compiling, or erroring when we shouldn't. See [#82159](https://github.com/rust-lang/rust/pull/82159) and [#82067](https://github.com/rust-lang/rust/pull/82067) as examples of PRs that modified the compiler to use the correct param env and in the process fixed ICEs.
In the large majority of cases, when a `ParamEnv` is required it either already exists somewhere in scope, or above in the call stack and should be passed down. A non exhaustive list of places where you might find an existing `ParamEnv`:
- During typeck `FnCtxt` has a [`param_env` field][fnctxt_param_env]

View file

@ -24,4 +24,4 @@ Xtensa targets that support `std` are documented in the [ESP-IDF platform suppor
## Building the targets
The targets can be built by installing the [Xtensa enabled Rust channel](https://github.com/esp-rs/rust/). See instructions in the [RISC-V and Xtensa Targets section of the The Rust on ESP Book](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html).
The targets can be built by installing the [Xtensa enabled Rust channel](https://github.com/esp-rs/rust/). See instructions in the [RISC-V and Xtensa Targets section of The Rust on ESP Book](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html).

View file

@ -462,7 +462,7 @@ struct Foo;
```
In older versions, this will be ignored on all targets, but starting with
version CURRENT_RUSTC_VERSION, `ignore-x86_64` will override `ignore`.
version 1.88.0, `ignore-x86_64` will override `ignore`.
### Custom CSS classes for code blocks

@ -1 +1 @@
Subproject commit 0ea98a1365b81f7488073512c850e8ee951a4afd
Subproject commit 04ce66d8c918de9273bd7101638ad8724edf5e21

View file

@ -13,466 +13,466 @@ nightly_branch=master
# All changes below this comment will be overridden the next time the
# tool is executed.
compiler_date=2025-04-02
compiler_date=2025-05-12
compiler_version=beta
rustfmt_date=2025-04-02
rustfmt_date=2025-05-12
rustfmt_version=nightly
dist/2025-04-02/rustc-beta-aarch64-apple-darwin.tar.gz=42fbc48c6f9034c1d47029491e0adc7aaa1adecf429e22ea9eb6d36225ed13e7
dist/2025-04-02/rustc-beta-aarch64-apple-darwin.tar.xz=08f88363fd42d66d537c0a296502f94c3a3fecf59a004613c9acff33eb0b0207
dist/2025-04-02/rustc-beta-aarch64-pc-windows-msvc.tar.gz=ea47adaa63abd18bf0c11cdb381eefb2874994527005cbccc0dcace33191f9c6
dist/2025-04-02/rustc-beta-aarch64-pc-windows-msvc.tar.xz=cefea68c789907a45f0bd4233da2e3406287ac55d1c33f8612ec1aa006b853f0
dist/2025-04-02/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=38fa4ce395641a988247ee58c334389eda62fc1d3c0fb45157f24578319925d8
dist/2025-04-02/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=d8d0b459acdff2a32f8c40707bf5a17b71ce86fb5ee9ad61690cba8f8227bbfc
dist/2025-04-02/rustc-beta-aarch64-unknown-linux-musl.tar.gz=41f01647a80a7f21b85fe660af9e7964ad34f0e909d1e58c9e28e102a796791f
dist/2025-04-02/rustc-beta-aarch64-unknown-linux-musl.tar.xz=8436eddf40ad5bf61153f24c887fb0f0e878bcc403095719b35f3147328d6406
dist/2025-04-02/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=07ee5588005a18477a7de89321e6527ee5f10af00e9c4eeb2a8c666f79d3d606
dist/2025-04-02/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=8a95664cef49c1e45b2ae61ec464a5be976e4cecd2b502a050f95b9eb25dd4c7
dist/2025-04-02/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=b9b186ea9bee58a646ce8c4c384fc4cb528c73c1fee3ea3f5028fd4b3fddab3a
dist/2025-04-02/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=9f62c2ea5b67c14ab804267d449ded07c8b551536886099b02b942ce2d641790
dist/2025-04-02/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=f07363ad0dff8b965dc10543f27cfd923266dea6284ebbb1d1b59b77f5ae2b61
dist/2025-04-02/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=a31afc234645a7dc5dc47f05bb5321fea12931278433df834def303cdea9f52d
dist/2025-04-02/rustc-beta-i686-pc-windows-gnu.tar.gz=f396061e8faaf66edea34b0855e2d3760fc0fd5c75e99696b50b2d4f310e11e0
dist/2025-04-02/rustc-beta-i686-pc-windows-gnu.tar.xz=0f95f9170c5b211db29c3baac9341ef61de83511fe0000b8aae65aaf90041ae6
dist/2025-04-02/rustc-beta-i686-pc-windows-msvc.tar.gz=82b7d1136d1b6f3d229fc77eac19d2cbfb3a46de472345b0ec3ebc152872164f
dist/2025-04-02/rustc-beta-i686-pc-windows-msvc.tar.xz=565bde72132e77617059da66edf9262f728336a2cc2c3c7cf4d61e0a4b5e681a
dist/2025-04-02/rustc-beta-i686-unknown-linux-gnu.tar.gz=8a3abc2a8aee8fa30699f51a216b29b41b2242143646d0f560f89bf72a0e285c
dist/2025-04-02/rustc-beta-i686-unknown-linux-gnu.tar.xz=7d47cf99aa5fd3b5bc2caa918b4eaba793b6d38252a72fa7be631c8db27c8525
dist/2025-04-02/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=0654cf14bd3302d001fa00fe73cb7c597206c6897978b3aeefd00e9325a8bdad
dist/2025-04-02/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=6cd5c3ccb643a912d738239c0ad7464ee755cd81f45a26a9d3aa5ceeff569ba3
dist/2025-04-02/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=e3c0c5c52b04dd060f3a70b0c936dfb5c70ac29256361a491df9c898259dd551
dist/2025-04-02/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=83a9bc8f9a61b2a7fedddbdfb253aa078bc9896f179ec9b1d1bd918e7de34663
dist/2025-04-02/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=21efa7a67647df8aa99e40317c798895321d09c48b8453e51eef1635c20e9c47
dist/2025-04-02/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=56203ed9d3bbbab33e2825db7c72cfbe4f857f68dc98072cc98280cc4f1110d6
dist/2025-04-02/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=76c343aa3f5c74e1419e3f2f79dd3a2091fad8f6db644cf14f7aef036c8369d0
dist/2025-04-02/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=e9c7b97a407127e51fa49ca94c5f22c59f2f325848d55e6160d6dcf7ff690f91
dist/2025-04-02/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=27935ff4136141519b4e7b37b55253960b7fa16f5cd751d731ed85019432247b
dist/2025-04-02/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=fd37c12a55055bc4a2f0e002b3126e6396df8d49254b2a8a7a45354aac46bb2c
dist/2025-04-02/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=cbeba9993d03c6c0c2c508414bee04665abb9c084c736b39c5b8d38c8f63402d
dist/2025-04-02/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=e92f69d85929c81e3c91b2ab45eec418afc65edf6f8bf9383148a98b052353df
dist/2025-04-02/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=31a8ae1e64fb86a499518d7711595d653db56527aaedea06bc2bbcb912568844
dist/2025-04-02/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=7d001ad6c4825d5323813ed19747cc3e3d2dcbbe76317329a52127b3de37ee88
dist/2025-04-02/rustc-beta-s390x-unknown-linux-gnu.tar.gz=c69d15e75d51caa0cf77fbe149d43b62c327896bdeb0c6c73fa7240404289862
dist/2025-04-02/rustc-beta-s390x-unknown-linux-gnu.tar.xz=cf80772ba9eed4885a28aab38323f0ed24ab220339a3b8a148b7c27860c48c19
dist/2025-04-02/rustc-beta-x86_64-apple-darwin.tar.gz=be22d207f8fd4722d69f6fdc56c57618ec01c54c5b6f3a8506c62583259d433a
dist/2025-04-02/rustc-beta-x86_64-apple-darwin.tar.xz=04feea9824748ae01b4f4f85d15adc5baee23c996c22de86041888466ae69512
dist/2025-04-02/rustc-beta-x86_64-pc-windows-gnu.tar.gz=8c75005f0309d30e7c272adce173adb253874ce881b347946b6ffe5a07067439
dist/2025-04-02/rustc-beta-x86_64-pc-windows-gnu.tar.xz=7b87c4ab5291d9ad3670f4e9ee98fe9f6f877ab8d4952109d7e5e9d20181a700
dist/2025-04-02/rustc-beta-x86_64-pc-windows-msvc.tar.gz=a96d89ba655db5317dd51ffa2ebb81b7bdb76b19cf12de36e9d0aba2c5877ae2
dist/2025-04-02/rustc-beta-x86_64-pc-windows-msvc.tar.xz=84bcfd763eba610c78223697393ea97f1f70e567a44b8cfe22db79f1cade4201
dist/2025-04-02/rustc-beta-x86_64-unknown-freebsd.tar.gz=95ff7349cf12e49028256c06c8517719cada2720d4db80bfe7531289bbcdbde9
dist/2025-04-02/rustc-beta-x86_64-unknown-freebsd.tar.xz=c8d0147c625faa5ce0e75c2509827bc4b190ad286e41411bce92023e00eb7a1d
dist/2025-04-02/rustc-beta-x86_64-unknown-illumos.tar.gz=4be80235a110028d64404e532eb20af37e46db72a7ac3a0cf7c94ddf463c461f
dist/2025-04-02/rustc-beta-x86_64-unknown-illumos.tar.xz=b18ea9a5c262c2f7505305110473cc15bd2c4ed9d583f07c15635406c050be08
dist/2025-04-02/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=234027a0075224ea157efaf39173ece43f9ca7d69d86e4790a2a038f7e6d98a6
dist/2025-04-02/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=308a8ee2855a6471db3b3b64cb06e355e31d0d617ebc9f30757bb7db5f6fc7c0
dist/2025-04-02/rustc-beta-x86_64-unknown-linux-musl.tar.gz=10f39cc94f39bcf17d0fa3b8efeb4db72408fba694e5eb0f175e7465f6d2de49
dist/2025-04-02/rustc-beta-x86_64-unknown-linux-musl.tar.xz=6b0d16b46347fdbcddfafad8209df19515059eddce1e048ecf1585341fa1e586
dist/2025-04-02/rustc-beta-x86_64-unknown-netbsd.tar.gz=09f482425c92396f7e4ae3baf625dbcad1d886d82ecfb605b50393abdc23ce15
dist/2025-04-02/rustc-beta-x86_64-unknown-netbsd.tar.xz=bac2f1a493bc2c5fa6cab1f58ff536cbeba55f77141b34636bfded9e3ff167b5
dist/2025-04-02/rust-std-beta-aarch64-apple-darwin.tar.gz=8875ade1dd8ba0bca0c12860a076df1f089195a52adc546679025c405bef4dd1
dist/2025-04-02/rust-std-beta-aarch64-apple-darwin.tar.xz=0a0593ab4c95802b0ed810c0442e13ad9304712c2f7c30a30c734523a7448d8a
dist/2025-04-02/rust-std-beta-aarch64-apple-ios.tar.gz=839086e20098c305adcdf9103cdf3f29a14c4140b4c1b728723e7aedad966883
dist/2025-04-02/rust-std-beta-aarch64-apple-ios.tar.xz=70f1832193e77a2018088943b531bdbacbe5404d5d7a34393e03f40329e742ce
dist/2025-04-02/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=94adeb2e63a91c09001facbc554678227a3717748104424e4fea71db3d5a16be
dist/2025-04-02/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=73c9bb75eb6fa4cf613c7a2b0e237472e144a1469cb043194ad7802052149fee
dist/2025-04-02/rust-std-beta-aarch64-apple-ios-sim.tar.gz=0e01ed2620887b893687758d62422f661429e3c4566ff52d967463eca89f54c5
dist/2025-04-02/rust-std-beta-aarch64-apple-ios-sim.tar.xz=c26beb8ea9f11845ce79d4f0ec2616ce82dfbc4fefadfc7f94a1df17f4d5bec2
dist/2025-04-02/rust-std-beta-aarch64-linux-android.tar.gz=64047673efa9d9bad660e2a44f82e6f929c881fe205523bff10a549505d12b72
dist/2025-04-02/rust-std-beta-aarch64-linux-android.tar.xz=0e4c6b76e8d92023533aef6fe377c9bd45ef9c1da517eda7bfefec85b966780b
dist/2025-04-02/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=a25c50a86e5d674600cec5bd9e7939bf36b0afa766445b0d71673431388d285c
dist/2025-04-02/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=8060a4c5337fa6c34b3f08ddb8886beeb5bafd2b02544b08a7cfcb466a27a972
dist/2025-04-02/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=efd76703934ae0187308eec9b3439abea0dd4437ac353d5dc07d92f9440ab9ee
dist/2025-04-02/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=007462f554b0c6d2b165d727bf72b1ad4347a53869d672fcbf48db2c1dcf128d
dist/2025-04-02/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=e0dc54be7890edef123d2dc31f0dcddd1c807cc060a34f475093cab79100d9fd
dist/2025-04-02/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=01c06c1d61c512a034a109f50f957e4496639549837b63464acb4fb24ff65e09
dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=2042d37b09618379dd91125d20803e2d97d5f3f3794e01ed27597a0f3b27c102
dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=568f0b8da190daf78cd8573b0408db2ecc2c07b1cb1fa463239581963738e9de
dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=386b1e4786dbfe342626cde4c3708abd04d9862d69717c7acd5dfe82427e38f9
dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=781d0f9417e1b3d33d95e3c5b82ba7e481a610dc468345119e09a52b1d170045
dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=8673d059524ac141a8907decfda36c8afac81fd36dd75f78df750a6d52ada221
dist/2025-04-02/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=8e8afe45e9bb84ebc3e02f0b4b71dbcec7c844128329d31067303b86113c3439
dist/2025-04-02/rust-std-beta-aarch64-unknown-none.tar.gz=72e1dce3c1f821b6018ec155bff250b941afcfcf1697b440a69822b10e929b94
dist/2025-04-02/rust-std-beta-aarch64-unknown-none.tar.xz=7030883ad3ca170a061972707c488fc25d4dc8ab0f60a1b9b54240e42ca713ba
dist/2025-04-02/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=28f87a505ca4e2c33015338d73cfdf5c2fdb1f5775f82ec432d033a36880351d
dist/2025-04-02/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=45669a09671c183d702a31b6ecf095e8f422797c4e242063c7864180c6f657a4
dist/2025-04-02/rust-std-beta-aarch64-unknown-uefi.tar.gz=1ad54cabda8bfabfd93e16c564c0950c26e1502662d5f4ce3b33b4ee265b9a2d
dist/2025-04-02/rust-std-beta-aarch64-unknown-uefi.tar.xz=a79f9d7eb4297994b2e87d48106a959c82bc4387433e5e86dc8caddde29a8a4e
dist/2025-04-02/rust-std-beta-arm-linux-androideabi.tar.gz=75192092fa7a40051a70a843cf75513de2c50d66927f16b122f7417c1d4f25e7
dist/2025-04-02/rust-std-beta-arm-linux-androideabi.tar.xz=843dde45dfa49b5cc97266c61d8e58dfb22dbf2288e6e8baaef769eaf59675cc
dist/2025-04-02/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=03ccaa5e246502fc61fea1e0b33f5c60b5895cd0b5b932bf640d62e97164b457
dist/2025-04-02/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=a73525dcab3a0f3bc7064c8a6cdeb9b0e5b359501cb7e8fe20075a0e97b2a5ba
dist/2025-04-02/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=8c851fc122d14beee962e15fdb95c2873769805180be30723f418d84cbc0a8b8
dist/2025-04-02/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=8524ad1b7723a4a5898837d5b526fb11ffcd039b2c4835a2e139071f6cfd4e9f
dist/2025-04-02/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=b108ec4460d4f6ca79813e6d2d4cb7061fa522a990333fb9f4f927b0fc659624
dist/2025-04-02/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=0bdb617dfa833c62c03f5bfd2f06ed3ca1479908d860f888d661794188bd57d6
dist/2025-04-02/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=19f9fff71344f7a42f958c3efec720e4b2e0d67ba36a5fd66946e74811259f2b
dist/2025-04-02/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=0cdfe9b4a8bc4b63637cfd9766c3e0e1d3dcd6d2e82fe35f57973a0081e630ec
dist/2025-04-02/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=a8490374598bbfa42931bbfba51ecc0186c476217eb79408ae6b80a4ba6de9f2
dist/2025-04-02/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=2bc2838320667f060c140345d1c26aedf90bf5efb1f72e6722b74d32f876901c
dist/2025-04-02/rust-std-beta-armebv7r-none-eabi.tar.gz=9a237e1dbd2e3b555aa3932351d1c20a0f9f2f06e810abd254b5ca152aace687
dist/2025-04-02/rust-std-beta-armebv7r-none-eabi.tar.xz=f4978bf9af719f0b6e8300ea862fe617e983e5443a46c769d60d5e8c4d556ba8
dist/2025-04-02/rust-std-beta-armebv7r-none-eabihf.tar.gz=c1476718625d5d5d42b60faa9ade845272b0b71e91d77a9cdd271c4682c900d2
dist/2025-04-02/rust-std-beta-armebv7r-none-eabihf.tar.xz=f8ab07e99983fc7395841cc9ed7ce7cfaedd87bfb91214bd83508ad96aef0c0b
dist/2025-04-02/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=649071a7de4792ff75da59ca421ea1cb364c011db97e73c480982a5f9f06b8aa
dist/2025-04-02/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=529aac0b0a385fa5ddb76a88eb6923bcc981679caab2d1c374d443383c99f52a
dist/2025-04-02/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=8bdf3412b0b557485099db86afcdf58293bfd4c09c4b360c2d9733788b612122
dist/2025-04-02/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=5d5a4ebed984a0930b214ec0b11e20fd9a7b8d5dc2d00985b75a77c8febcf441
dist/2025-04-02/rust-std-beta-armv7-linux-androideabi.tar.gz=2c03cbb393641876bebad9b76465ac7f96adb82c14dcc9b5bc01a82e5110b892
dist/2025-04-02/rust-std-beta-armv7-linux-androideabi.tar.xz=67d86fa728178c30cd7a33e0c488c32f58ae0caeb9a982370e080ea38853830b
dist/2025-04-02/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=3737dd5f80f35f3fecf5cd8324c9226f45bb0bfd040998d91509a2c6fd8967f1
dist/2025-04-02/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=8f9f710c92af058d5a07c93b4cfd45b7d30e63ab79bea7f79530537aae2dd836
dist/2025-04-02/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=6ecb3e238e125e88851dba9711b2b32f4de1da55de36a62373bfcc42d001fa0b
dist/2025-04-02/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=7d6807d24afe4825b77c1cb74c1412b814cf2508f5b40debb55b3f264e02eb6a
dist/2025-04-02/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=a15fccced78065f748a5c4f66763b8940ae3e52b5048b5ee1fab6b0b7b40c701
dist/2025-04-02/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=20bc43c1b5742a9c7a97ade055441ca1ca153dab9602db3ffaf1ac518713568e
dist/2025-04-02/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=b01929a0f18b1a41b65307a04d1273d2197df83b3c124f80659ef8fa4f8c4577
dist/2025-04-02/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=2a13350da7c632d3878ca8da8a7d0bda60c850df8e5d824956082b524eb136fe
dist/2025-04-02/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=11bc9fd437be07cb454182b0d7b287ec030f7d8904f096b73beda6480ba33285
dist/2025-04-02/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=31e06feb45173fec8e58cf92216e44d556587fe2ed866102206e23514c73d3f0
dist/2025-04-02/rust-std-beta-armv7a-none-eabi.tar.gz=aebbae792c070adea3f10135c02b2cf5d623b84e765ec3a72c89275f53a85384
dist/2025-04-02/rust-std-beta-armv7a-none-eabi.tar.xz=e80dcb152e7a8337fbbff6a5c8dfcd9c6da4b753da6b14e63fe7c15cc0836359
dist/2025-04-02/rust-std-beta-armv7r-none-eabi.tar.gz=e79846c1203d5d375c7c1cff1c843cb6fcd4e33bbc71b2363e12fc900bbd72bd
dist/2025-04-02/rust-std-beta-armv7r-none-eabi.tar.xz=0e24e48461cc46edef0237e38480ac806d0521c73ea366668e731f29b638d7c9
dist/2025-04-02/rust-std-beta-armv7r-none-eabihf.tar.gz=fd2a9b48ea203b44567cfdcfcfb21d5d803896fdfdc5f3aa191e3fa7472b98db
dist/2025-04-02/rust-std-beta-armv7r-none-eabihf.tar.xz=2b85d461bed34a97cf832a7c0e1d4179d7800ef47523a8e31d635b8de5dd44a7
dist/2025-04-02/rust-std-beta-i586-unknown-linux-gnu.tar.gz=cab412c30b27060cdcb29adb947dc070875813726707dff121c4a1aa8615646d
dist/2025-04-02/rust-std-beta-i586-unknown-linux-gnu.tar.xz=1b8d469fbb8903a5f4f5eb6ccee7bdf28cc56137b6b212fdfa1aed647f4c347b
dist/2025-04-02/rust-std-beta-i586-unknown-linux-musl.tar.gz=93fa0383e32f18567c3c156f3cddde1fa4296003f98cdd22b0b5628d69d5208a
dist/2025-04-02/rust-std-beta-i586-unknown-linux-musl.tar.xz=71ae00b01ffbfdc6654d0fd14df204adb7d499ac71e59c93affff91d58833d88
dist/2025-04-02/rust-std-beta-i686-linux-android.tar.gz=4c6f4764e284ff29958417295ddc5d3316072fc9eac87dfed8b694c237aa4f88
dist/2025-04-02/rust-std-beta-i686-linux-android.tar.xz=f471a7abb2d447f668f01973be4712e20c6dd29b210a96517b277e62c6d7de07
dist/2025-04-02/rust-std-beta-i686-pc-windows-gnu.tar.gz=0c5efb9792502fc08174b2556f5c91f3edbad6e02de5e230f39c5fa011fc935c
dist/2025-04-02/rust-std-beta-i686-pc-windows-gnu.tar.xz=b6a87360e7be832288e59239d41e809db01710ccae5ef37bcbe7b0eb1d311e66
dist/2025-04-02/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=0429745cd95a198a7a42a1ce0c7ab2d502f3ff3eee81104fe6d5d4d5dab9447e
dist/2025-04-02/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=bcb43c9e2d4a49c18d39e041d28021f2302707ae9ac20ef37f4d467fd2cd3975
dist/2025-04-02/rust-std-beta-i686-pc-windows-msvc.tar.gz=e1d8c40e61701c6bfd519125169cc1ab1d60e9a58238351bbeda0ccc5522cc49
dist/2025-04-02/rust-std-beta-i686-pc-windows-msvc.tar.xz=1f87f343a90f6e88cb3173d52f4f88d8abdb0c1a613681c92675c1acc340aa54
dist/2025-04-02/rust-std-beta-i686-unknown-freebsd.tar.gz=5862f33548bef1aa21b3d63caefa12ee34775cb378f89c4dc161e081a773d11e
dist/2025-04-02/rust-std-beta-i686-unknown-freebsd.tar.xz=ed3460948031d0c4e97f7b1b77062f388d133db2b2212518eabd3198e72c031c
dist/2025-04-02/rust-std-beta-i686-unknown-linux-gnu.tar.gz=3a6edd9f412a274e372c9555b6758d540d06ac08efd21ce95df1ed4d30418afd
dist/2025-04-02/rust-std-beta-i686-unknown-linux-gnu.tar.xz=8338baaa50b9cb08a28f7bb21a22deef849f8809282c661e48c486a168b6249e
dist/2025-04-02/rust-std-beta-i686-unknown-linux-musl.tar.gz=56ab80fc6cb75a0d66c477e76f87918645bc3b616cf704306820832681022768
dist/2025-04-02/rust-std-beta-i686-unknown-linux-musl.tar.xz=94efb810dbee977ecb3ff5a42a5a620d720c237da58d974ba1f376c99947baf5
dist/2025-04-02/rust-std-beta-i686-unknown-uefi.tar.gz=64cb107065bde9b30c78b9b342211c4e6cd2c3ed726155dacfcf5958ba869a82
dist/2025-04-02/rust-std-beta-i686-unknown-uefi.tar.xz=ff1bc215b4aba25f59eeee8285967e24b78f6965473ea8bb30186ab55804f88a
dist/2025-04-02/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=da1d33b266e1dd277f97f63228843765706f26c9f75c4b5171f49c2762fed870
dist/2025-04-02/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=8309c9c4a03df90eb53116b5c5c4870d103911227848919580a48e5e85954709
dist/2025-04-02/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=26a3115d5354f878f80bef1c83a44af185e2780882e17143ca57aff078d123a0
dist/2025-04-02/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=12431c3b50276f352a3ea71c74db279cd03c2edfb3edf743f81774d4274f7ef9
dist/2025-04-02/rust-std-beta-loongarch64-unknown-none.tar.gz=ac67b23f84d09ab17d26f30deb38a128ccf812a561738327effe48ecd0caa319
dist/2025-04-02/rust-std-beta-loongarch64-unknown-none.tar.xz=5508b02465d3dbb40512a142eabb27817807d2af153089f7d05a0af355fdb245
dist/2025-04-02/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=a79a59139e13166cb1121d703cee113bf92821f937d433cb9a2c00567280a4e2
dist/2025-04-02/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=8c3b5501050f57125cc89e6525b780ca0e18d2d5318f779894ab97efef761fb3
dist/2025-04-02/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=84a48148eb313f236f85a4907af615b7af4c3ce3d9065ffe0db54458852690ab
dist/2025-04-02/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=26281622332b438bc43b8f46921153a45c6236a4c0939c76fdb4d9fb3d29cbbb
dist/2025-04-02/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=0eef233c871404b913c6458d8005d362e3c24fcb0670ac49a7e67b1a503b4b29
dist/2025-04-02/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=b96422b0f33446abee203160a22e9bac8861e1c7988b2cef463276743001fc7c
dist/2025-04-02/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=18db97406a6e644734c7890991cb3006fabe1e1a185f89d108d28a992ed7c17c
dist/2025-04-02/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=eea42655b5335643905acaa3d8ff1774e2c1a39ffde363c2073a8636c153087a
dist/2025-04-02/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=5feaf6f3859204979fb4dab03fc93428abd103d61822d6e4e9a2f5d6d155213a
dist/2025-04-02/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=98f8e695253c9dad3d82638bd69c084a3e7a96d17eb1dba0f90a42df993de864
dist/2025-04-02/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=e028f2ec967ecee5d9e7b48058209428ed220c5da2c00f2753f8d4e98951e168
dist/2025-04-02/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=69f508ffcb55347dbb773cfa22a1f7a6362f3aff6a48296b50945422ea82c7b5
dist/2025-04-02/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=ea30bf48fcb3873db4019ae3d248e1db868e1f7fc49e4549737aae58b3b49b22
dist/2025-04-02/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=c3724aaa58f812dc8283622f27e215546d8522b6ecdf1d191010dde3a1ba3344
dist/2025-04-02/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=9d24eb785b66796309c2f03944719fb6b6980ae8fb7ca97084fcfdea0094bcce
dist/2025-04-02/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=f6b2233474eb64d041e6bd8f1b6dee3eaf775b6b5a7ddec703689352cf88f6a2
dist/2025-04-02/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=8a5c94055180b9a1226a23c5992a622062ac52cddf91651a91a5d236be46d0c8
dist/2025-04-02/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=7ea826d6c58fe1ef1c9374aef0cbfec5495daddcda581b231d18397330d9e248
dist/2025-04-02/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=811881bd5b514c89c316453ea1214fbeccf5388f18468cc83676a879d58f53ab
dist/2025-04-02/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=9448b7bad586237faa4f090ce8c3de83b62d19fbe37104ae32032d9df709d2e6
dist/2025-04-02/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=dd9252a03b0a888ee7598a84c20aac721739c2caf9c5b585274d2a30d7fcbcb6
dist/2025-04-02/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=d1f134647fe0c3efcce80351cf9e4786ca8e3e336c0316b7c28ff07b78907c73
dist/2025-04-02/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=4f688c40457ba71542438fbc100b62b5f081435567f965512481ccf3d002826d
dist/2025-04-02/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=a474fddf29c6979e0870c397c19f64de00650893a781eb51d9e136802bfabbfd
dist/2025-04-02/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=7071209fdf0d2605b623ef96c934ed039d1dd95a68c438a8c563530ed48fb4e2
dist/2025-04-02/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=1328504e895dc9bbc36ac697bd5031e0034b2468fc66a91e42b39a4d35d4ea8b
dist/2025-04-02/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=e7878c1137279790205e62f9c363a6f45e2a8cd9c30702a53478a8104dc87a6b
dist/2025-04-02/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=f373b1d79547c385a01c2b36951eb3750a4cf3bcaaa213587af9a6b4274dc924
dist/2025-04-02/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=4832338ebc25d088e30952605b3f6491d96003790df5b10c5c56e29ec69ac646
dist/2025-04-02/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=d782dac690b3da2b96206809512f1ae82fb4a73ee387d91128ae0d98bf51ef3a
dist/2025-04-02/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=faccf22845e31101a420796d9065b350092cbee29d755c2369ee36cc7172866f
dist/2025-04-02/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=f296c5726380b1f2b8603a079e8dfdfa7e4a97a499b1e86874753c312768ab15
dist/2025-04-02/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=b8a8fd8fda8b99d96d6f890bcd0c9073393441e85a4cda169b6fc7dbb7296984
dist/2025-04-02/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=923a0530224f0631162f7b86bef79be85f45071f62ca4f5de0588fb5ca6affa8
dist/2025-04-02/rust-std-beta-sparcv9-sun-solaris.tar.gz=944a83365d3c46313e28b1d3a5b0e52e57ce88b3eaaf0f7f53234d4423ce9ca7
dist/2025-04-02/rust-std-beta-sparcv9-sun-solaris.tar.xz=be0c983c443f05feb4614d97336755894b3ffc5083d852bd84ee7cd9e5edfa03
dist/2025-04-02/rust-std-beta-thumbv6m-none-eabi.tar.gz=08905a766352dd259be919aeb366e965dbbd4066c398dc4d26efa333b0ac46b8
dist/2025-04-02/rust-std-beta-thumbv6m-none-eabi.tar.xz=4fa005107c3d1addb242179c03a804a27d34ca68bd76c092a41a197da56abce1
dist/2025-04-02/rust-std-beta-thumbv7em-none-eabi.tar.gz=e6ccc1004004ed759b1814daae0b50a3a0adca9786688ef9cc601a0a19edc72a
dist/2025-04-02/rust-std-beta-thumbv7em-none-eabi.tar.xz=fc23abf9c086a34264bfcfe7c4876ec65ce54f8ca73a98020bb8eab6d2c51d57
dist/2025-04-02/rust-std-beta-thumbv7em-none-eabihf.tar.gz=e8121551c0529f73796bc157bf916e3608685454a02a81d170a258a7465b5b7c
dist/2025-04-02/rust-std-beta-thumbv7em-none-eabihf.tar.xz=2695f76447ff5d70aa3cc6b6690267b31b9aa4ddc7c45205e529f92d234483a0
dist/2025-04-02/rust-std-beta-thumbv7m-none-eabi.tar.gz=36d7fb4edd572c7d73501aab7c89737ee0036d606700c728f430142e91649eb0
dist/2025-04-02/rust-std-beta-thumbv7m-none-eabi.tar.xz=a6e59eaed0ab3e310852d9a75fc43600c7c2eee0c808224b87bcb8c18df4ada6
dist/2025-04-02/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=6bc70be43929b77f3508b1872e5b09227aebce1c7c9c943995b5df92cf6d9181
dist/2025-04-02/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=37b956924534aed1ae7ef9908d38bf724c6903591269136d23e293e17a0d333f
dist/2025-04-02/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=041562edada0caeea67fe7f3ffb5b9f8c1b506c0d5ee7b657c5ee2afbefba7fa
dist/2025-04-02/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=8980372a7e9a072b1e0b954569e59df260583a3371daf005c5a83576688562d1
dist/2025-04-02/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=83f461ac0ebcc05d5cbf67a6585b49dc7b245c8788dc3a75e08a93be41e2615f
dist/2025-04-02/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=6ac8847ce601c8dfeffff07915de06a605b3c685f81b90f87b092897c2afb973
dist/2025-04-02/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=bfcd9ff7dc9bb5e95bd563d750240efcbc3bfa1a21a9f9a2786ef37f665b7e43
dist/2025-04-02/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=4507383395a26d41abd71041b162dfc5e9471a4c624d9fd6ad310e184ef15d01
dist/2025-04-02/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=b4d1940ea5e24cd6a0ba3906c98d2b03e4a18927619152b43e91832733316258
dist/2025-04-02/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=45eec7770344beb84cf418cf7818216d123136465785f4742127f6f5a8c5ce27
dist/2025-04-02/rust-std-beta-wasm32-unknown-emscripten.tar.gz=19bf2f4bf64f874ccfd84b820b7200e83e896c96a396edd7bd10301d2bc89d98
dist/2025-04-02/rust-std-beta-wasm32-unknown-emscripten.tar.xz=4c616b7bd972c09461f0bccf5009bc574dcfa8bdce2dd97d17fcffd64542e496
dist/2025-04-02/rust-std-beta-wasm32-unknown-unknown.tar.gz=69bcb61fd0f8bd7d2da225a4525a877cce003afd7fc3d789c385f164959cd41a
dist/2025-04-02/rust-std-beta-wasm32-unknown-unknown.tar.xz=0372a64eda0c7249ce5fbcbbbf29e145e969b383a73b7c470f0b583720fcdbe2
dist/2025-04-02/rust-std-beta-wasm32-wasip1.tar.gz=f76a2a3f4702eb781a680ebd4346afb4c26ca2235e62bad144b057860c09b8a8
dist/2025-04-02/rust-std-beta-wasm32-wasip1.tar.xz=173bc3317b59a01036a9c8e0bccc570fd6f5174d15f94634f53d81dec3d2cd68
dist/2025-04-02/rust-std-beta-wasm32-wasip1-threads.tar.gz=18e05380478ed0b3f76d9062fade2be2e66c039dcc470ffb01be3c8dffc79995
dist/2025-04-02/rust-std-beta-wasm32-wasip1-threads.tar.xz=3d477eb85308f73d1081d6dd3e54577be4bd84f291a50af0e3be15fa8aa36db6
dist/2025-04-02/rust-std-beta-wasm32-wasip2.tar.gz=3444883960a9f8b831d1f26ee17ef082a2029cdc2e9b45ce5af4d6565d3a526e
dist/2025-04-02/rust-std-beta-wasm32-wasip2.tar.xz=867361c7ba912b404c426807a60625a1f830707a172f7da139c1a892aa85bf35
dist/2025-04-02/rust-std-beta-wasm32v1-none.tar.gz=d15017a323c662a1e8c65f51e66151138c2255cd8842a67e990000606dac839f
dist/2025-04-02/rust-std-beta-wasm32v1-none.tar.xz=f3b32484ef287317187ca0bd5245b1793ae40d50290a2882419da8503b8243f3
dist/2025-04-02/rust-std-beta-x86_64-apple-darwin.tar.gz=179be6a29fcf16b4c18775208569a051f2f5a38558e751d2dda0a42027868843
dist/2025-04-02/rust-std-beta-x86_64-apple-darwin.tar.xz=912f7f8d7117a5cac85dffee5ffd9f2c1cf237477bb0f9e1127afff1f0cd4757
dist/2025-04-02/rust-std-beta-x86_64-apple-ios.tar.gz=9d2f3230bd82ba9d45e572b45ec63c63cfb592dba6311b6a16de075f18c86999
dist/2025-04-02/rust-std-beta-x86_64-apple-ios.tar.xz=c8ff77db2d081444ab5167764465beb33046cc81cf2e8dbbd8e9a7328306762c
dist/2025-04-02/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=76c9b2ae710fed611a2294a5e4bb6597b07d78f0bbd3a5a0d15c3320f38a0017
dist/2025-04-02/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=b9c485a3824c971a42c10af26cf06c539c34fa429e92601a1978280867029e62
dist/2025-04-02/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=a223c08b88c768d97bf9f071c74d9548acf00bbb097b8c8427c2ec87ca205597
dist/2025-04-02/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=34ddb3db8a71edabb4d0fd8d52a164dbca5a5cd96d6ba131e7d439c333726f78
dist/2025-04-02/rust-std-beta-x86_64-linux-android.tar.gz=9ba28bf95c75ca0d69461d1c044902443053b64678b540967a97c7cd2eb7cc4c
dist/2025-04-02/rust-std-beta-x86_64-linux-android.tar.xz=09e35188a801371a55abeb9e2ee455ebd26d41b8eb561b8016ecacfc7ba20c90
dist/2025-04-02/rust-std-beta-x86_64-pc-solaris.tar.gz=c1f2fb4b90cf258dfa1a52167ba925b583dc889ec1c3c48958560ff3b7b79b13
dist/2025-04-02/rust-std-beta-x86_64-pc-solaris.tar.xz=d71f2bade21f751d9592e865ce3722b5d3b9abc49e55ca9d04c02d658360b6ad
dist/2025-04-02/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=691c23504582e6db1cf883f52b5378aad3c42da7e2d2237e54601be9c8d16cac
dist/2025-04-02/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=22e7327c5ba22863cb62cc5331862b8c2b4b10a732637729b5e1504034aa2cf1
dist/2025-04-02/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=81b7dda817a7dbc8b33542c356e0c5e5605b7c60a2fee13f4a266c8d970a3f54
dist/2025-04-02/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=09e4c9804f7489b337ccf66426e18e7522dcba24234b289a39eb63c8242353d0
dist/2025-04-02/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=a8188567321462309fb63af38f652c6a7448ebaae1425b9ec20d2fe2a12e8896
dist/2025-04-02/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=5284f85dce61b2b021888b6b82995aa7b4a14a979b42b83499a810c261fc183e
dist/2025-04-02/rust-std-beta-x86_64-unknown-freebsd.tar.gz=eb57c8ca7f515386d60a88e56443e377aae70e185ac52a62869e115c636a2bcc
dist/2025-04-02/rust-std-beta-x86_64-unknown-freebsd.tar.xz=8bef59b74196fa9f7839bb491f6b32d0761a45c8d7178980ee3afd80231b836e
dist/2025-04-02/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=f43f402881f4558e3df4a7ace68ba80caa9354cfa5a8b1efac89f95e38386253
dist/2025-04-02/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=ea7d09c015c057591ff51b808cca9c8c1d973de3a9033fe42c1bf34d748d03a6
dist/2025-04-02/rust-std-beta-x86_64-unknown-illumos.tar.gz=a4835455348bc5b154b1bba63aa03d2294713589214b50d3babae3e0f9918a3c
dist/2025-04-02/rust-std-beta-x86_64-unknown-illumos.tar.xz=711920e7491332251fb672abdc7685fa940f863d8e182e2ae9d9347d7fa6a725
dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=1b8324839c0e10e410f29bd471f6c49eb4710adbe172d6bef3e619ae95d47d02
dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=223b41f16a80b9c404f5af9a194b7414ef354681f911839353f24b44eed91494
dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=6d8d8d9fd6336de0ebcb58fa85aa0d11e62a60d6c6ca01d71da0bdf668d216c1
dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=033df93011b4461cde64c4230c495bad1523b9b38f5b0de56dd928c1da85b577
dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=70a441c0cf8ca25abc1f722c1db5dde8b5fd3b90c767895b7518fc58c2678390
dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=b5584d6d0031f8230a40f5ed76570ab1396c8997c3e957ca159d72a5dc201a2d
dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=2596cdc3708d82aa93a8a1f595238fe9fd7b5b05a4886e7e390ca3b86d352e7e
dist/2025-04-02/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=c03901c0c8434b5db244c22145870e7d933b9060af3b23f24a765c755098a3a1
dist/2025-04-02/rust-std-beta-x86_64-unknown-netbsd.tar.gz=82bc22594dc602b27edf8233bd9c4fbf0323999ce99ff2a7ddd0ce9268647eb1
dist/2025-04-02/rust-std-beta-x86_64-unknown-netbsd.tar.xz=86f674f5e19a1b1780f06a6d5add06fd4240430233b7c3f5203a4daa5f444673
dist/2025-04-02/rust-std-beta-x86_64-unknown-none.tar.gz=ca7882354f4274dc405034aa6edbda685b9d76bc6e5905074d2aaf8c35b35a95
dist/2025-04-02/rust-std-beta-x86_64-unknown-none.tar.xz=ed6c828fdafcf87a68f522379f11c44eff1a4be1bf027d9888d1f17f22e9ca61
dist/2025-04-02/rust-std-beta-x86_64-unknown-redox.tar.gz=6f8ab182274e2f5b0fa82fdc5c6e3776ba969e6ee6f6098ce6d170f6685f55c2
dist/2025-04-02/rust-std-beta-x86_64-unknown-redox.tar.xz=ee061d725f657a2e52114f282be0cab1a6e542a0270b11782c36e8737ed84f32
dist/2025-04-02/rust-std-beta-x86_64-unknown-uefi.tar.gz=0324f537f463738bbdbf40b92423df6c6068f76c583872d6070d6a41c5169dac
dist/2025-04-02/rust-std-beta-x86_64-unknown-uefi.tar.xz=2cd2727f71b14c06eb0a14fa532e5b3bc66f8b983c021f3201c327606b04511e
dist/2025-04-02/cargo-beta-aarch64-apple-darwin.tar.gz=76010b5a9f8dff0102a18de75e818c51b915a3bcff428fc48973728577c2ecd3
dist/2025-04-02/cargo-beta-aarch64-apple-darwin.tar.xz=f0f03ece675cfaa9dd0f00204d7ddd4086a45357f09cac9d800d37bef8d0db33
dist/2025-04-02/cargo-beta-aarch64-pc-windows-msvc.tar.gz=bf4ab12afcea7911ab973177de83b7bbdfd0000e3090331f31a595d57819ed6d
dist/2025-04-02/cargo-beta-aarch64-pc-windows-msvc.tar.xz=156fc94166e5f2af91fd9a36c67b545c0eff63dad51fcd81571cce01447c1c1b
dist/2025-04-02/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=c86bbf8091188ab9f7d41e566ef628a657d66683884333c3851e99edaea6e279
dist/2025-04-02/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=610383a4efb93ab53cc747ba038888742346499407c982b7bc8c0c41689cf453
dist/2025-04-02/cargo-beta-aarch64-unknown-linux-musl.tar.gz=7d427779360c9cba5903c2a0183be1c1759cb2c2f2b77bd2f64b409821fabb64
dist/2025-04-02/cargo-beta-aarch64-unknown-linux-musl.tar.xz=29bda8bd7dcee65315b8c14a527f4e4b4dd678b35dd430591f7c71712ecbd2f9
dist/2025-04-02/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=ef6d6a810eecb3a38940634b653257070dcfcff52c2d8321fa3a933d41c7ed73
dist/2025-04-02/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=79796d83949811776aaedc7e6db6d32374c07b8f8d256d9b871de335bf5e7074
dist/2025-04-02/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=fa93a1285a97453e2aaaf9cf392abb4ff9a419451e925959470166522e54b1dc
dist/2025-04-02/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=acb69df00475904faccf18729030a70e8ce21543189d48c7102330a98a12edf1
dist/2025-04-02/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=7141bf32c173d26f34571b2dfb890187d866f113e28b63908841377e48dbc6ab
dist/2025-04-02/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=249f3c535805fb2510d13338401e9ae96f16e6996e58551025b35676a1147ab5
dist/2025-04-02/cargo-beta-i686-pc-windows-gnu.tar.gz=fe4f5f35ecac25bc3726ffecbe3e650d51adb9ea13dc5153a0699ea8d8776d13
dist/2025-04-02/cargo-beta-i686-pc-windows-gnu.tar.xz=b7b8432464eb793e9a651c4c38ee8abe76421a9be7f75e96237a4ef938f927f9
dist/2025-04-02/cargo-beta-i686-pc-windows-msvc.tar.gz=a283da65d3a75435ff3d05441fd0337472fd16325531086e90b01cc5d5bd221a
dist/2025-04-02/cargo-beta-i686-pc-windows-msvc.tar.xz=ae19f98c901228ae5c7573cebde4816517bdb8d03dbdc7b92d95518d27d93531
dist/2025-04-02/cargo-beta-i686-unknown-linux-gnu.tar.gz=e3c5b2560f64c8056ef82ed0cd659d35fda5181f19fa670b962228142398efbc
dist/2025-04-02/cargo-beta-i686-unknown-linux-gnu.tar.xz=3fc435b8a186f6ec1b7ebc38c92c2e23e1bd786415fc33e7743ef95c37c69b45
dist/2025-04-02/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=bcab46663be61e979b7a89792d164e182d5482ad9b444a969dbb304c5dad8c8c
dist/2025-04-02/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=9e2ecb90d85a4aca95211892a6a41fde09ce1e4f44a60caab9aeb61833191d36
dist/2025-04-02/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=3c5c40f61e85663d03fe51f63d505d8dca73f94bfb3eed29f6e1396b31e0a554
dist/2025-04-02/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=775c56ce638e0923758ab5f82a87c15b7a1500d10e0be2433af40364a0455d58
dist/2025-04-02/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=c1a144dc83b673e0375e8f718cde6672ca276dbab9161d7f3e002c6273352c1b
dist/2025-04-02/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=1b41b3396340c97c122661c95fe54265036e721f1750bad3a8fe4920f6f52b34
dist/2025-04-02/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=2a43a7682ea3da8b911b09a7bb4a3a75fc3facb64fc952e51ff35c63e6630b75
dist/2025-04-02/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=73a3383196527e63716de1b1cab233226519873556a755a7e47279f799936116
dist/2025-04-02/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=d5f521839bd4b258454097cf97b056508e6f9103f7312c93b632ae44ac9f7dc0
dist/2025-04-02/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=c4fc5ff91bc1054e8497efa53ee6a9a9eb7f06927cd314a681e16b6d46b08440
dist/2025-04-02/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=5b0d569fe4ec84d6e7526af9d9794b440e8f1b5fc1b09e951678b09fd3ff97fb
dist/2025-04-02/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=e9c68eee5763c624cbe312bc1b50b6c3172eb7997e209371692e7f897d13b03b
dist/2025-04-02/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=96962461e7f6744a46f18a557a4701d35d6fa3b6d960d854f4c3effe6f2636f8
dist/2025-04-02/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=4d6029204f930543afeeaf44d9e635692c86c9daaaac6301cccbe076c7facbe5
dist/2025-04-02/cargo-beta-s390x-unknown-linux-gnu.tar.gz=f40421ea02804c3089420e5ca13838f94fb89c114de9a9e596e9a1207d2166d7
dist/2025-04-02/cargo-beta-s390x-unknown-linux-gnu.tar.xz=77521eb215cded6886267644661b3357590f20368383f314da8f310197e9679e
dist/2025-04-02/cargo-beta-x86_64-apple-darwin.tar.gz=0357ed5c9c8ccbe71f89695bffe1604dbd2f451472fc6ea8d8d2dfc93a703b30
dist/2025-04-02/cargo-beta-x86_64-apple-darwin.tar.xz=6ce4f66b60609f58046138831ae3828ad1d58f8d0b2f515f153c96b690a0134f
dist/2025-04-02/cargo-beta-x86_64-pc-windows-gnu.tar.gz=8fbf8506fc0c47bb30043c026107c51d6b548fa91320b5bbd2c608e191bdc007
dist/2025-04-02/cargo-beta-x86_64-pc-windows-gnu.tar.xz=bb57df35e6d73b0b0bba58801d66febfed03f0b3f74085eb50ef8b5ea3fdbb40
dist/2025-04-02/cargo-beta-x86_64-pc-windows-msvc.tar.gz=0bec5e9059c4b3035f636017c1586653d372f03969bcd4d80c0eaee52f01a2ac
dist/2025-04-02/cargo-beta-x86_64-pc-windows-msvc.tar.xz=3f836d3027d7ed25655f43262b126311bf014629dadc4a860f00302bc468e752
dist/2025-04-02/cargo-beta-x86_64-unknown-freebsd.tar.gz=0f60566416471c38350c12f066bb512eca65a66319f5ee7fdbb60464d70661fa
dist/2025-04-02/cargo-beta-x86_64-unknown-freebsd.tar.xz=eae168df54ddfe95db669c205ae97baa902056722856fa174758ebd058168a95
dist/2025-04-02/cargo-beta-x86_64-unknown-illumos.tar.gz=816eb91ac3858043f58075fc48fc2e90d0427c58b6283be589d337a7f0ddc9df
dist/2025-04-02/cargo-beta-x86_64-unknown-illumos.tar.xz=faba548d376309b71bcdae49f7089705be951f72a84ef68362aa6d865d40ebf9
dist/2025-04-02/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=1fe7e9d2c5a733acdaed418011c1fc31c3036e5299e8f9288ddeac43780fa35e
dist/2025-04-02/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=7a39bd08e46d3e19da81c02ea3bb46bd1750a3ac1d1db8fb5db852cde14cdd72
dist/2025-04-02/cargo-beta-x86_64-unknown-linux-musl.tar.gz=00df62b75e1811fd4fcc827b531e7ad94a73fcc37318d0aed28796d902b33568
dist/2025-04-02/cargo-beta-x86_64-unknown-linux-musl.tar.xz=874084ab37814ddf50ef423e22f0721e5c24acd953ed02cf83432d2372606a5f
dist/2025-04-02/cargo-beta-x86_64-unknown-netbsd.tar.gz=7b4467e398bd34f94912c56863ae83b45415bbf612b3be15624a6a410c27ff2a
dist/2025-04-02/cargo-beta-x86_64-unknown-netbsd.tar.xz=75e7ac498a8e617bb907c26f2a3bba9a1e9a22af1c0946f88c7bd53c28790ffb
dist/2025-04-02/clippy-beta-aarch64-apple-darwin.tar.gz=0f5a8a6a96b8785beae1fc9476374d060632dcc4c17a4335031425ee8e2dec48
dist/2025-04-02/clippy-beta-aarch64-apple-darwin.tar.xz=aed266be1799ae3e95099d491c3b20b731b2094bc8388c6ac3e782667b58ca6f
dist/2025-04-02/clippy-beta-aarch64-pc-windows-msvc.tar.gz=0ca97501432918d43aa9bed9b58cd4f1d0d738970e09d6c037ce967519b2b13f
dist/2025-04-02/clippy-beta-aarch64-pc-windows-msvc.tar.xz=c64edd87358c1ecb9e01b204977edaf0307cc939a3dd3ae62f151c153ac2019b
dist/2025-04-02/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=7bfdd371ed44a32e50ecd6baf107796d5a77ca3cce0bd58bc5882afd98ca0edf
dist/2025-04-02/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=cf49acab8153fb65867a9c44eabb7f156f85e9818b6f49453067ce0764036919
dist/2025-04-02/clippy-beta-aarch64-unknown-linux-musl.tar.gz=bfb20f832ba30a4840f0d4898d27cf69b5717a78bd71b20270f8ddd66c48bc69
dist/2025-04-02/clippy-beta-aarch64-unknown-linux-musl.tar.xz=54081690d35c39267a49d991e5e0c16043261b6969c49f23c2be44e46c3bfcdf
dist/2025-04-02/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=3d88b69d6c67c58b09be9d679cfbe8ee449b9de419e950edcffd4637ded46cac
dist/2025-04-02/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=67843ea0aeaab167029818669074e8bdc46a7e1c269a15580cdfe44a7d2ba96b
dist/2025-04-02/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=46e9efe50418a035ddabf9a6467b6b0ef20453816c4b6dfd46fa1342bdc42167
dist/2025-04-02/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=3b27dc434e88280bbc89f5c5ba6eb68ec5332b549b73f7f8d79feda9cbb49628
dist/2025-04-02/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=670a6ce01ee6e5225b152a1357eba9a41cb47f04d08cdc8a0828eded4132aba1
dist/2025-04-02/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=cf92bed8c784e9579c09305fd227df3992950c227bc844a9b09995828d62e2cc
dist/2025-04-02/clippy-beta-i686-pc-windows-gnu.tar.gz=58238b6f4f8ad957a39c0eb63b45007d1c3f8c79e98307c7e5a531b7309a30f4
dist/2025-04-02/clippy-beta-i686-pc-windows-gnu.tar.xz=e77c5215b3e96c59fa150330cb5144db66dac377fdad3be9c28f9fa07d9fb7cc
dist/2025-04-02/clippy-beta-i686-pc-windows-msvc.tar.gz=7c65df8af1f6f4102ffbd7fdaec50c24f89f2631edd06642732f1b5c74558ab4
dist/2025-04-02/clippy-beta-i686-pc-windows-msvc.tar.xz=eeb119d26e1e2ddd3ef72741158d75d0db254f6420fd729d34abe5d172c7d765
dist/2025-04-02/clippy-beta-i686-unknown-linux-gnu.tar.gz=c43518b27adce17f06f89c70ab52ae4c94f1f7129a182c16f9bb28fbc8a5f40b
dist/2025-04-02/clippy-beta-i686-unknown-linux-gnu.tar.xz=1d972c55d89cc01b7e408b4e24e8975bca29ff28578f224024a00f00d17c28b8
dist/2025-04-02/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=0d779bd9fcc5ed8e1db81a3a385bc0158c3903e5b0f0e4c99d172eee106a4f3e
dist/2025-04-02/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=5515e0678c081ddae45f3f0c3c7ae58cc2f7b1141e1557a39826bf1aa58a2480
dist/2025-04-02/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=e99599c1fd0cab2eb0e89dd8e37e90ee2106d602a3edb3473fd65768bb8f7b27
dist/2025-04-02/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=f346a801dee3734461eab4303469d31faaf3e8f0d733b854470722ed48c66276
dist/2025-04-02/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=cd7b58e507d6695ada446ef9fa113a9588501832f4627b3e7cc0000a77c9265f
dist/2025-04-02/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=0a7073874663b4ce8eb47a0257ac0cf8049acb34703241466f1208489c4dbee0
dist/2025-04-02/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=78d0b9581a7d79549bbb6a7e8984bf923a7b80bf6bb3979a90e90ceed8e66d33
dist/2025-04-02/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=79069a26ed617a2a07eef7cf098d028cb0c172fc4a6dc99115a51862b1b8bea8
dist/2025-04-02/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=23c58421839105c88937ad90a92603b7fcd6d9e21f291ab8c419fce1663a20a5
dist/2025-04-02/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=b546706d28c46f5bd3799d6b42201962ec2e9d6baf8df2b66cfcf1bc42789036
dist/2025-04-02/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=31cf0d973eb3f0ca341a8d64c26b8b3b045b44b3c00d2497893dac6e44ebdeb4
dist/2025-04-02/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=8afd89866c41631d4f4ac4d8a06d943473af7a96b043f6112216a04863817820
dist/2025-04-02/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=f08bf4ed1519e7c47f354a0d0b750933342314bacd4be761746666cf455cf74b
dist/2025-04-02/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=e502f83f811c35e43df0a5e158d9eb61f60c9e1aacc75b588b2ba85022ca4b3e
dist/2025-04-02/clippy-beta-s390x-unknown-linux-gnu.tar.gz=21bede57083544028238ef6c9d24cbf9194a35c88500f2d0c5d50e6f0ae79616
dist/2025-04-02/clippy-beta-s390x-unknown-linux-gnu.tar.xz=670c0a293e1b01f331c2645b648c1df087da4c1b5d689f608279b1ba524cbaef
dist/2025-04-02/clippy-beta-x86_64-apple-darwin.tar.gz=a6552e032c047203d5a9f5b767945c7a556be35468c42631c0c84cd049e24a8a
dist/2025-04-02/clippy-beta-x86_64-apple-darwin.tar.xz=17a9e9ea8e0d6140080b7fa4e3c77ad1a7fde3c3179f26b0aabe34c3af73b58a
dist/2025-04-02/clippy-beta-x86_64-pc-windows-gnu.tar.gz=2ffa8663502f4c6bba049318c70e79c174fd717d45ab4427103fc11563be678f
dist/2025-04-02/clippy-beta-x86_64-pc-windows-gnu.tar.xz=8c0a71f226b229f30a9acfbc1ab7c6bbedf692ef7b26737721a0518d3f1972ab
dist/2025-04-02/clippy-beta-x86_64-pc-windows-msvc.tar.gz=463c7a5d2a11beaeb1e63bc769db89fb9996a0558da15b4e091befe982893711
dist/2025-04-02/clippy-beta-x86_64-pc-windows-msvc.tar.xz=40241fa6e463df734096e0e910b414c83d8a4dc8706b7c712cc170844e59e3c6
dist/2025-04-02/clippy-beta-x86_64-unknown-freebsd.tar.gz=6464044b05b326d8ea594a963e38a52a1e27e0f028704427c41ec5e93e3772d9
dist/2025-04-02/clippy-beta-x86_64-unknown-freebsd.tar.xz=77cdeb1e838c3da1d01252481f7c06149b0b8e7df48c2a2ee5961f4550d7b662
dist/2025-04-02/clippy-beta-x86_64-unknown-illumos.tar.gz=d51238e1ad2329b9309e94b40f3374788e2fda9bf47466841a841392835e8a5e
dist/2025-04-02/clippy-beta-x86_64-unknown-illumos.tar.xz=6ad33945045790946fae843f63a805e60c09157e106ff342d3b99a201cd221e1
dist/2025-04-02/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=64b4f85d9eb75172928b46540090128ce9eec00e275d9027f74d0d5d4106bd76
dist/2025-04-02/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=b090383b4ebeae96fb340f0a363ee0276eb1f17a4f2a0f2ed81aff039f21bf78
dist/2025-04-02/clippy-beta-x86_64-unknown-linux-musl.tar.gz=8d8025922c563bb1c872111722a4de298a8f85cd5be3e4cf753d44d6b8304de6
dist/2025-04-02/clippy-beta-x86_64-unknown-linux-musl.tar.xz=ecf15ae9eb7dafe97afd69133f13364dac09d5e6edc35ddab91fb4ac32e17d42
dist/2025-04-02/clippy-beta-x86_64-unknown-netbsd.tar.gz=c802af6a6f454b771046bd4a5207bdbe538cb6827becc9174dc229de5f874426
dist/2025-04-02/clippy-beta-x86_64-unknown-netbsd.tar.xz=03d1e16eaf6f83f80e4cef8c7beebee97498135dd3138b97f97186b545edfb86
dist/2025-04-02/rustfmt-nightly-aarch64-apple-darwin.tar.gz=c02047132bc7b48bbe930dfddb3afd31349eb042cb101a19d6e4360ea6e586ad
dist/2025-04-02/rustfmt-nightly-aarch64-apple-darwin.tar.xz=cf825dfaeb4d97eb2819ff8e46360192f480960f6b516e328ef8a9493d413a9f
dist/2025-04-02/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=588551cbfb62eb4ed4e5755fe6eb3e1499a79e24a8a75f448b10d9a2237c63db
dist/2025-04-02/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=df666f179fcfccb316aeb1a5eb4c17710b23198176edb34ba8b98c88cb369098
dist/2025-04-02/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=b06f4aefa01300ef1827a29c9fcd2e4da0c13f3aad92b4c929f6e8811d53ab71
dist/2025-04-02/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=059a888b8db76f5a3054a9a78a131d79c49060deaf70b2e2f03a4fcab44ab536
dist/2025-04-02/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=f0117a7be9eefe70fbd2f0d3fc05c51f3a97d069dc99500520a5d0973178fc6a
dist/2025-04-02/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=f2fa87f1e814d0fb163146cf6a47d9375fec2c3778f76c33988acaa1665dacf7
dist/2025-04-02/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=fa53d4a6fb2ee3e1607d825afcc05063c0fa0dda1a3ede9a57e1ccc72cece8c4
dist/2025-04-02/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=3d785d982878f9bda4778cca0f9365947665849d5f7d2ee4794d8c28df3ab8c8
dist/2025-04-02/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=affb343357cd4c677cdeaf3b24698f20cfa15062cb63257aaa9bca3bd7baeeae
dist/2025-04-02/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=6eb95c2021571a0c1ad3e3edf58fa4daa7711a9085e2ab61bc75799252183358
dist/2025-04-02/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=1dffc39afb9210c77e6d45b68cb801247f00afdf33107963c82a83bd94d2225e
dist/2025-04-02/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=2da28dd8ec76744a7629619f527196689eb35e9bc60f3a5965ed69486e44235d
dist/2025-04-02/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=5b1b39125106cdcbf12be9d5786900852f54eaa1429cabf28eeb68f96a008f90
dist/2025-04-02/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=3f2ecb3787c82a8dae89929aca4f2f3af790f1ab3c698adf21dde21c919a4052
dist/2025-04-02/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=eeb8b3f10f1cd75fac4e9e13dd1aee5941f38f1ff7fcfcaa69fcc3a42ea7c49a
dist/2025-04-02/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=afd81cfd8d5fb37427c7eb2a1429c3b06d8daa1f42002c7230718fc56e132c47
dist/2025-04-02/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=5eb0f065a5403645ebb6c01d7f27a763f9446b8a48db5b6ff962b6f7c0f3ea3b
dist/2025-04-02/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=3576e2e8ecc563cfbc4b3f464d80f8e27f412b5eb267656dc5f0316a11a2d299
dist/2025-04-02/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=5e69db53a1161ad7616f9e50d1a7fef785840bdf0ba81757d0b6811078692921
dist/2025-04-02/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=ba9d18dd2d63bad1e2863c9e14bbc4bd282d03cb806d03011d2d61ce701d934f
dist/2025-04-02/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=b112f8c2e6ec011382c02a40ca07f30e1885a1396a7f2c30f099e56d756f2f54
dist/2025-04-02/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=42af68aa0b77306187d13ef881ee4327856f505a8a518f46244ffb17037f7e4e
dist/2025-04-02/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=ed4277c9c8a27fdb97911bb9fbb46385b5fd807ac9338d31eecc3240bb0bc5c2
dist/2025-04-02/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=4cf3a7a64edd09b5d8ad72af545c15013842072e70789d1741f845f27c60566d
dist/2025-04-02/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=65d49556ac1abd1da9cb7c41e518f85213ee2b1f05559c917614937d4c0cada9
dist/2025-04-02/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=535ea938d888ea12c139740e5d25ac4b82135b3274b8d86c3c59e36928922ec6
dist/2025-04-02/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=9776e0c641ae8a229453fe1fbdaaae05ea0caf37bb4893a00fe86e5d63d1241a
dist/2025-04-02/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=bf73cfd35802b2706d0db96c854e8a4c45398297a59aef92226ac28d8bb69417
dist/2025-04-02/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=307012d0741898b3a2840ba3535832943ab6127f27323e587e1918b2023b37a2
dist/2025-04-02/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=79912529a393cb77c604f5a16d5b22611e938971656efd57fc5ef1980ffad35a
dist/2025-04-02/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=854280cb3eeac146196ba30c8f3a010d568bf5bf9613d1870bd052a2aa3a03c0
dist/2025-04-02/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=36e6cfc2b333cf077e3e1bf651acab4e6845330fa151848926d7b33fafa016f3
dist/2025-04-02/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=19409bf4daa2e4d76c99659d7348f9a7dd4eb640c8bc81d93dc9170a1e51b7ba
dist/2025-04-02/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=999346ff469e15507ec43c0b265a94b98ee99a0096d68ea0307a2280d138838f
dist/2025-04-02/rustfmt-nightly-x86_64-apple-darwin.tar.gz=6a52a943d59edb9e6ed97643b01a2ca2f51abb6fba1b4c9b73f59646372aac01
dist/2025-04-02/rustfmt-nightly-x86_64-apple-darwin.tar.xz=3701a72b39a31e31c9fe65afa660a507088dfe6039867a2019bfb69970872bad
dist/2025-04-02/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=c0dbe39a6dc72d96446312584055cfd75a4304c4859016ec7590d52813f0736c
dist/2025-04-02/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=f9e8814cf2e0241bbe40bfafc62bb961d87060dd94c84fba8ea00b2992eafe2a
dist/2025-04-02/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=b9a2c923b6794b3462882a9f5b1579e2463024a72ff34cdf4bdfd8b0f51ee528
dist/2025-04-02/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=c5e8272c451a3d685842e07a996e8bdc305ccb02a02d39f7f4cc764be4b2adce
dist/2025-04-02/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=d47cb1e290f09795a04652f33afba39f80f3b6dcc4b570c14c75b1d945c78f0a
dist/2025-04-02/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=389ea9f755623dd3d887bbff71189f86d7397c82e2f8fe660c27784cf7c68a94
dist/2025-04-02/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=b49f6c211c51a50309ddd2bcb4c886ebeef47e5413e6399778157bc90a37ed0e
dist/2025-04-02/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=d53f55b6dba14bb2e2f90510c3e432781a8aad1f871d8f38795edf866ed4a4f3
dist/2025-04-02/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=2b8d77937298b23522ab9bd2f64a829f6faf1dccb87033f6006aa8c324474b47
dist/2025-04-02/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=0579d2a7c17cd585c49a42efe062466db777c1e7890f21b319234ee81c86ea39
dist/2025-04-02/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=65bc50db8fbe283e876b9ae7d6c15ff0461c1db8b3327f2992a99d21bcc3266c
dist/2025-04-02/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=120505da1a8cddfb3f549438a52b2c73c76a9f1c2f25709db13d61efd214d732
dist/2025-04-02/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=d19004b3f6b9fa446e23f540b21a8f314d3bbcca11f753c9a6fdaf4c7ae7a2de
dist/2025-04-02/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=e7facb66daed07789015c2d5b092afde5dbb1349d06cd0f80ae8319437587723
dist/2025-04-02/rustc-nightly-aarch64-apple-darwin.tar.gz=3783e0aa4450a6bb913fc9a9799950892e65c7af9a2c895419090072999a2305
dist/2025-04-02/rustc-nightly-aarch64-apple-darwin.tar.xz=4d3a72db4cfcd7663803f1a0b193326e37c7faecc0c97c3903a17fbc0f7c8848
dist/2025-04-02/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=c253308683fd394b1287a4eb9ca00cb8557bd7f7f91af8b087adccf9153a94eb
dist/2025-04-02/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=63c30a1e523266dd6f8d6bb1525484f51fc6462bd7946900e0590b219f2a8b47
dist/2025-04-02/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=74d2313a732fc8401d62b9a8610bd9a25502f0372921c0e99d9d20f0cf8e3b19
dist/2025-04-02/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=a96db92f8c7cebe6e0d140a1853ecaa038e04975d62f17950e141d8ac2452536
dist/2025-04-02/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=250e2c21af9d4b284c7455668ebcc3d1e408c20cda1abf0ee69acac4c873e5ed
dist/2025-04-02/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=931714cf51d93fee5cc9465e9a0e9d34c771fe2aaae46994f3b00da4c95a8f54
dist/2025-04-02/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=28f993889175ba3feb78b458be5282b2564a7c9b96117fed071835ff7b47f43f
dist/2025-04-02/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=8645d1a7510cc13e2cd9abeffa71cbfb5f3a99990d27da2b05c336801a51c7f0
dist/2025-04-02/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=a86525223d8c5d67b0a92382b6ebce65761cdb83629e11bf29d625d688908d38
dist/2025-04-02/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=06a57a2c6298bb6e477d1e04922c626142bf96b2072684aecbbbf876bb4296f1
dist/2025-04-02/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=a7fb3babdc244ea1f025f3033d13088c50696db8d6db29efcc6a78474a06769e
dist/2025-04-02/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=b130a7efa1c2bdfa5ef51237d5233ab6bd8feade7dc596d120b6501b4766a569
dist/2025-04-02/rustc-nightly-i686-pc-windows-gnu.tar.gz=ebb4dda0d1ced3ec5aa14b1ef38227628db92a87f45b817d4ce41ff026a687ec
dist/2025-04-02/rustc-nightly-i686-pc-windows-gnu.tar.xz=43a69c9382b20249495824c149ffb5b5dae2ff7407c0c431859bc3e1f1ca4a7c
dist/2025-04-02/rustc-nightly-i686-pc-windows-msvc.tar.gz=bf3eb550e148e89e7ff17be5e72ad0462d57f3c452bfdc46b80a1812ec2fe457
dist/2025-04-02/rustc-nightly-i686-pc-windows-msvc.tar.xz=b2dde774c1ef573c6a889c2d78bbb98f535f22be4b20896797be2f10781f0eb4
dist/2025-04-02/rustc-nightly-i686-unknown-linux-gnu.tar.gz=96d130960b0dc1d8fa54f53d22a8fa8cf5aa35d0b213071404122e4e714feab0
dist/2025-04-02/rustc-nightly-i686-unknown-linux-gnu.tar.xz=d743c6126151dd18624382a4228bf90af1239fc7fd97e763009b31666fb860fb
dist/2025-04-02/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=090ec673f24758b8a4d0ce7b8c58fc6015585bd8392e37760283ffbe6045298c
dist/2025-04-02/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=c71ad975a15c440890a7358b5459b7ca6b9d5e1842dd353071467c2a3f841605
dist/2025-04-02/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=8806875cee039409632e8baf5433227af04bd07d015329d9512cc4f4879f687c
dist/2025-04-02/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=cebc3a4f1eb71e86e4e63f78e1c2f86fc98f7d23db1a3cb7e4c4d385e5591d51
dist/2025-04-02/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=643dc0fe347a78a82321b5f47b41b09025856b6383ef67274ba3324879aae75e
dist/2025-04-02/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=955018b90daf3797497dfc423aec731e8d0320b96dcf42db1705b761e1e0dd58
dist/2025-04-02/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=aed278e57ffe0eb54328a9536607bc179806e0c2de9fccb9779a4517752899e5
dist/2025-04-02/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=0b6e0305b13d867c677243b16613f62b07352038f5e7ad7e1865cc2d00168283
dist/2025-04-02/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=e10d8eee30be690aa2e6ff58ca554d47173086d5df8f0ea8581b3fd10d4cee0a
dist/2025-04-02/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=3ca3c258404dd8718321ed8a50aa6512fea9d810120db225a3fcfe56d7b83064
dist/2025-04-02/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=ddfc329b8932ad796c0eb7618632f9ae0c5ffb7a6093ea7d5cc4185fc0537f22
dist/2025-04-02/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=b4e82b64f2e934e17fc9b270295554a8bf0bd3d38ffffc66b367aad5bee3ad6f
dist/2025-04-02/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=116d290065bd9e8ff2ca57440e94f773f68adf79aedba767159dfb92fe1a42b0
dist/2025-04-02/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=6e1deb0c47bba4b56bbf1d04344e45f0490938455aee421629f2fcfd309eff64
dist/2025-04-02/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=445f8a0ca579153b449fa0d36460227af68399c4227be76e4cbb3d65cef9055c
dist/2025-04-02/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=d87bcac173e9800dc1c1b28e668a1b4c3616029d0ca53adfa4ac382733610193
dist/2025-04-02/rustc-nightly-x86_64-apple-darwin.tar.gz=4342b89aed19f409df56bfac3d6ac071a02cb6839a52d19fdff9d10cc1d9f540
dist/2025-04-02/rustc-nightly-x86_64-apple-darwin.tar.xz=cb787327895f275e6f9025bb38c6337492c839310931b8c7ba39743813621701
dist/2025-04-02/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=6cddd0d3cf18780b36776fd0324643a36b3294923531a741cc763516c8238caf
dist/2025-04-02/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=cefc15752bd84b290f50b958b96feb0134d420a10c6f36791424c762cda08abc
dist/2025-04-02/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=731e968787044081453a559a95579435654b47f91a9b7f94579ac007ed3e4cf9
dist/2025-04-02/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=3d9b173043aed73aa3ab1fa0b14d0ce2149a4943f4bb10aa1e31af619afe0eed
dist/2025-04-02/rustc-nightly-x86_64-unknown-freebsd.tar.gz=c0df2f0a354d2d657d8ec8091bc094060321b343c8e7bb8e4315cfe042dacfc3
dist/2025-04-02/rustc-nightly-x86_64-unknown-freebsd.tar.xz=8933bc0361484ac7c6b226defaea73eda5c4e10462e7ea54052c7e1d370e48c0
dist/2025-04-02/rustc-nightly-x86_64-unknown-illumos.tar.gz=5887f913ac80dfe9826619227c66eb234a2b4848e6bc4f41c6fdd8102bf981e9
dist/2025-04-02/rustc-nightly-x86_64-unknown-illumos.tar.xz=4a54b8b09eba43df0d99fb6e03177cf8ba2214a5810be52ac33ee3d9d33e98bc
dist/2025-04-02/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=1c0bb76acd7944804d52c3139f4dcf154d3221cdeb300bb6b9bca726cd6ad30f
dist/2025-04-02/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=e67a33440c3e021ff2dd41add0fb05db6c0e8ae68bd30d33e8b3185b0bb7191b
dist/2025-04-02/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=0ea7e17d7bb67d6a6c4b2f864aaffcd96512f15f17f0acc63751eb1df6c486a7
dist/2025-04-02/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=b73d37b704ab58921172cc561f5598db6a504dcd4d7980966f7c26caaf6d3594
dist/2025-04-02/rustc-nightly-x86_64-unknown-netbsd.tar.gz=986f6c594d37bcbd3833e053640ba8775f68d26a65c5618386654ef55d7b3542
dist/2025-04-02/rustc-nightly-x86_64-unknown-netbsd.tar.xz=c0d9a88c30d2ab38ec3a11fabb5515ed9bc3ac1a8e35a438d68bf7ff82f6b843
dist/2025-05-12/rustc-beta-aarch64-apple-darwin.tar.gz=e5ec8453efc1f51d37d5031d87d45a327647614b00993d1b7f477c7d2e6c7b16
dist/2025-05-12/rustc-beta-aarch64-apple-darwin.tar.xz=6711902d59079cd57d6f93e951d3028acb5cef0f59a2ab87e1688edee96f6471
dist/2025-05-12/rustc-beta-aarch64-pc-windows-msvc.tar.gz=7168682081144b8eacab42efe6c9ddb9ee6964712d271988345e63d2d6faac9c
dist/2025-05-12/rustc-beta-aarch64-pc-windows-msvc.tar.xz=5794e0d6bed097d349e138c7602a083f4025604f711328c0a4548e27f191444b
dist/2025-05-12/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=c4d31776d1b74dcc6184c2ed6064667b1ade59c68fb355bee812a805f61234f9
dist/2025-05-12/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=970b0c910f8ba2b5b470ffa7959466526b0f99211578f7d8ceca8d0aaa23fe1d
dist/2025-05-12/rustc-beta-aarch64-unknown-linux-musl.tar.gz=8e9c80f826b4571136f082d3cadbb4668167f19688a3da91fc732464b5a604b5
dist/2025-05-12/rustc-beta-aarch64-unknown-linux-musl.tar.xz=09731185aeb15263cfed5786ccc78fee0db70f82aeb5409f8bd8b03b0566d491
dist/2025-05-12/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=4ae8dec81d8f2d1aff7710a357e3c56323cae56bacd6b014fdb4058c06bb75f0
dist/2025-05-12/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=4767de7ea81913c6ed33907d93dfb56664d9bce0d095f33f0ca5662b284a94d7
dist/2025-05-12/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=d2233f4e687bb1bd407593f6d7a8c288581b7209d758be49f0681e1f556083e4
dist/2025-05-12/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=a8f9778a765d9fa8a0651b7d6fac8fdebcbaa61e903a32e7cbcd88bcd9418bd3
dist/2025-05-12/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=bd2ee7918df85f24a34911b91a233663b4cf706e7c54784c78fea8e58c12ca91
dist/2025-05-12/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=9b1a1c4eb35d3c1ec97132e33fc6551ffb280d6b2c9d049bf0392441674d338c
dist/2025-05-12/rustc-beta-i686-pc-windows-gnu.tar.gz=729e4d7a116d8ee2a42489484429b138bafc14b43c87adfedaad442515e61c15
dist/2025-05-12/rustc-beta-i686-pc-windows-gnu.tar.xz=8272b95f1d99dff28f22161d0181ac0e64e1909d51448f9ba4bcbe09690e79a9
dist/2025-05-12/rustc-beta-i686-pc-windows-msvc.tar.gz=13a7327d08d26ba1911071c798d520b74422e320f5cc1c41d4e215a5615e692e
dist/2025-05-12/rustc-beta-i686-pc-windows-msvc.tar.xz=0f9ce8fb06bb1ae460ee82601c269b885c109729df342e5b6b05b9dd9b51560a
dist/2025-05-12/rustc-beta-i686-unknown-linux-gnu.tar.gz=82b54be8042baa56e1e6c0346f2044a84c4a50b3df6fe813d45eab21e1fe8935
dist/2025-05-12/rustc-beta-i686-unknown-linux-gnu.tar.xz=48c9a8181b6ac7b7b6fb4535391c0498965127f5b5ac694de7eb1dba7ed8e9d5
dist/2025-05-12/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=768156149054211735ec45d0091a8e7dfac16a39c44e122af5b28b316a45fd00
dist/2025-05-12/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=50a38f72a253bfb8005a9cdd49621289f8b4a2373247957f520f5c5d1f12db29
dist/2025-05-12/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=f79bb58d8e2c80270a4c9d7076ce8645b2ea3f64db5077b085cb4cc6763f5e17
dist/2025-05-12/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=eafeaea2813e34ef0606a9f935fe1a104417604686ef9144b899fe97de53aa67
dist/2025-05-12/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=f557e00500071835712afdc9d91161a95b1cca5cc4e32abebcf5d35a9147eb2b
dist/2025-05-12/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=72fc4d26e06d74349e65415da211429ec92cd479aae78f82e223f3f760b0e63a
dist/2025-05-12/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=a67b7e5e0b30227b07a41829c5e88180d9c404c2ce37fcb10d8df702c2b3c222
dist/2025-05-12/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=0c4cfeb6555283e58b75533930783e7cc3c838f9c8eb34938fa60656b15568a1
dist/2025-05-12/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=7e6f02eede8d87cd5bbcd8dcf8235ebabd1237fb294cf1d0dcfaf961f3628d95
dist/2025-05-12/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=a5e9612d42f999a7b0fe22b2d5d5def21162aeb604c4625fc70259c5ec2b669e
dist/2025-05-12/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=8fc92b9e35110a53458e08b49db1809a23060f8d05e742561cd746fd206085f2
dist/2025-05-12/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=8b3fc4ac4423bc71b7402554436d1e6e62ff06b36c69f7be724e8ec5ebf96352
dist/2025-05-12/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=d0777e5ea794a9d19a2a1744acff649a1bac8fc616f6df41410553ac0b3c275d
dist/2025-05-12/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=849039740272c91141862a028f45889d4874ddc83842a66b906df37b7a30f9de
dist/2025-05-12/rustc-beta-s390x-unknown-linux-gnu.tar.gz=3230ab1516a19cf803952138ef7f815ce321d7123539539249b76f6afadcf9ed
dist/2025-05-12/rustc-beta-s390x-unknown-linux-gnu.tar.xz=12c8e476a73d71d58d5438ce94bb2fa822a8d043015b0961af14096d68c52daf
dist/2025-05-12/rustc-beta-x86_64-apple-darwin.tar.gz=01717cd3b5141d29896caeab17ad61a27b8b7af6460745f245d67dd066a09924
dist/2025-05-12/rustc-beta-x86_64-apple-darwin.tar.xz=fceb7e0f431f84621a22ae50ec9694cd0ecdf90801f953295b1975b0aedb4fff
dist/2025-05-12/rustc-beta-x86_64-pc-windows-gnu.tar.gz=1f7abd7650cab64cd09848ac8de9b7e0047f6c77eb433140fbae8ae8b522c019
dist/2025-05-12/rustc-beta-x86_64-pc-windows-gnu.tar.xz=4e3e07967e44907cb2b2ccb733b969014ee6efedb82412dc81f95533d2d473be
dist/2025-05-12/rustc-beta-x86_64-pc-windows-msvc.tar.gz=3cc10eb4187e09a48efa5351250e09c83edda4296d605dcb886eb81f9d6580af
dist/2025-05-12/rustc-beta-x86_64-pc-windows-msvc.tar.xz=9ce5c89a9b2e7360c7991c3f976bbbe9bf9685854d1019aa6dc1cc5b9d13eb88
dist/2025-05-12/rustc-beta-x86_64-unknown-freebsd.tar.gz=3a9e92319e91c0498a3e54ff5ae00f4e1ecfac9b0d4f291885c9feef89d356df
dist/2025-05-12/rustc-beta-x86_64-unknown-freebsd.tar.xz=6930ccd83b6b63d0a876eb5ac52c32a8449fd4cea8666b919494ce6358c6122c
dist/2025-05-12/rustc-beta-x86_64-unknown-illumos.tar.gz=c1a4ad2cfa4b7c3181ea0facc3b18baea7f4138d089825915eb41630e5bac500
dist/2025-05-12/rustc-beta-x86_64-unknown-illumos.tar.xz=44ae303a09cbc8a198c0cd947f958229b0e605842666a3b0aadb0f1f69f34ffc
dist/2025-05-12/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=fc55fe3f5b2d206417452de880a177f59004762e58fbfa4404f0b59fdd7075dd
dist/2025-05-12/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=a5ce304c4798bbacc998b2350d6ef79e9845a7ffb28bdf0af6066869667a0c86
dist/2025-05-12/rustc-beta-x86_64-unknown-linux-musl.tar.gz=391cb81e61589377ab0a6780289628a805a5b1d842adc29e66ee5731f36372af
dist/2025-05-12/rustc-beta-x86_64-unknown-linux-musl.tar.xz=7c3ac5df14b28b99e3e2d0072b5aacc59acc08621731fdebaa3199059ccbeb76
dist/2025-05-12/rustc-beta-x86_64-unknown-netbsd.tar.gz=670beaf2ec21118fb099a1b034b33665e360b8f1920b9cbd5fb58271a8aab9ca
dist/2025-05-12/rustc-beta-x86_64-unknown-netbsd.tar.xz=e4982c3e4b9f757485ff9aee183d973e31b2c485dbb39387c1afe4bee0fdbc30
dist/2025-05-12/rust-std-beta-aarch64-apple-darwin.tar.gz=c2786d9e874eecea00935c62c58e2e3ddfbe11b4c99f9ce807e2251640c8f7f8
dist/2025-05-12/rust-std-beta-aarch64-apple-darwin.tar.xz=0f2a6b28befa7d44055f32683d7b9c4de19ffd39c02fe6ce44aeffbdd1d13ea8
dist/2025-05-12/rust-std-beta-aarch64-apple-ios.tar.gz=3cccf751678cc229a7ca3b39cbee4467230bec235e16b48acc576c825e0be15c
dist/2025-05-12/rust-std-beta-aarch64-apple-ios.tar.xz=9ed9b7f1672d887fac4a0386027440651ef99c682ff21b1bd9c1ddd850934613
dist/2025-05-12/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=e7e6c0c7d9fa99f268d7601a127c6ce07df620fb27462dbaf933124a5786ef8a
dist/2025-05-12/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=abcecf3ecdb72714f35981847a91190c3f038dd5dce23a68253c7129fa6abf3b
dist/2025-05-12/rust-std-beta-aarch64-apple-ios-sim.tar.gz=c50ac5245e87b5e251fce3ff847ddf7d62df4490843e8a5f592515517b04d406
dist/2025-05-12/rust-std-beta-aarch64-apple-ios-sim.tar.xz=1c913535759d008327eef49e47870d3afcf609c29aab4a188209c3cfea954682
dist/2025-05-12/rust-std-beta-aarch64-linux-android.tar.gz=6120c1b159fa4f0279f8952aebf8cf1513f5b843905d64d1efaccaceac79c1f1
dist/2025-05-12/rust-std-beta-aarch64-linux-android.tar.xz=57ab4652b879df33556cf04596f0f9ad9b0eee832b67e33c8c8cdf812c229a6e
dist/2025-05-12/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=7afcbb49691f8286ac21107598a7a44363a8e385eaa648ab2e7711f87ddedfca
dist/2025-05-12/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=ea8af597e49e924f1e04eb3435afa09720c81f43dc467461de1058265d36dd64
dist/2025-05-12/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=2d8791f8ebff5f5f679c8b1735fdd1f0a4d7968983a5c2ddc5e036ad35b31f1e
dist/2025-05-12/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=a7f7bb3269dd7312edea5c6fef81d373499a670804259cf7853ef346fff42ee0
dist/2025-05-12/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=9469cb7871dc724148489180df240dd51c0388cd9bb478adf272934e38916b73
dist/2025-05-12/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=315f3dea48c50819f925bd32a3a5181591d4370eee4def8e37448828e622ab06
dist/2025-05-12/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=abfaa164202c7d5d3c7e956b10a5ea612b092ee45d6c05d5c19a097617cfd703
dist/2025-05-12/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=71ef1275726f6c61113bf1d23099a7557461205b6be243a952fa806ef15d9413
dist/2025-05-12/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=d651e5e46e1251952e719237dde30ed7ecdb6b95a7cc0398fc635a76b94c552a
dist/2025-05-12/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=0a67ebf159539bc7f5a4e5698a0c74550da3c5e2cb0b5e1dd694ad29e1f35834
dist/2025-05-12/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=c0f1ecbbdd5234230d2439620c0ebe9b1c3d331388cd174cdeaf48d724172aab
dist/2025-05-12/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=e2ba0a2853d685679422c065f266ee57f269bb5a231c5af5a791559a3609fb25
dist/2025-05-12/rust-std-beta-aarch64-unknown-none.tar.gz=04b4eaf5910e662364b5ac3ee08ddffc2eda3957892ba99c8c945f5e1a18747a
dist/2025-05-12/rust-std-beta-aarch64-unknown-none.tar.xz=065751b346f9c3d76e164a9edc123f277492ebfaf1d00db61027e4fb17d50f79
dist/2025-05-12/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=056a135278dfdafb5b22c8f01bfc77b17396511d67b55c1404693d801e584262
dist/2025-05-12/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=fc086ae7ca3a5c05790cb41dfc382fc65f929c669efd540c07131b851b78a743
dist/2025-05-12/rust-std-beta-aarch64-unknown-uefi.tar.gz=97a6301cdd34da68d5c6b243cc125f7e34215853e405d9b34bc715aeda3223ab
dist/2025-05-12/rust-std-beta-aarch64-unknown-uefi.tar.xz=3f2055ce638671316dc074595a35b893eea7be596cff218ec1416f3259ff86cb
dist/2025-05-12/rust-std-beta-arm-linux-androideabi.tar.gz=299158c865df15424564be4d72921b8b25993b0671e4d462ff69f49ea29367db
dist/2025-05-12/rust-std-beta-arm-linux-androideabi.tar.xz=6e71d518bf5f4a29b91938ee28b3c9b22509f3d97d4331ddd8ae0c1069192310
dist/2025-05-12/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=0a00703833d46720e470ed90f81a08d9c20f63932d852e379fe63df955e61c9b
dist/2025-05-12/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=57be85e4c2d4eeb4cbb19f48150693d4e6dd2969d380b1d55feb431c858e4c35
dist/2025-05-12/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=7b96461125b04d98a550bac5a7c3dad9c1df65ce849758d867c72ffc0b475012
dist/2025-05-12/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=a66602af671667fe5686c7a4e395d3dca8374ddae10cc9260e23e20f65022549
dist/2025-05-12/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=deaf5c7ed339c8a7bc2af94888841b647f8118854f698ece4ddbf900df921bd9
dist/2025-05-12/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=eac2d4d330a5300ee297c2eb61914b86efded3d494c5a73e2f91d989cb2896c4
dist/2025-05-12/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=479a5941193d14e2d4d50fcdbecb31103f6a143bcd3afae887d068c2ebe14163
dist/2025-05-12/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=2483258323175c1e338be84ce52d44e15177096643beabba9d806c69cbed23dd
dist/2025-05-12/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=528803fac28b0a0025dc50324a6980a4b561e7e3b99d7428b8ed0a73fd3dd462
dist/2025-05-12/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=6603b9aa82cfd563d7c462ebe50058c36aff403aa9e3a1d6a305780126aee481
dist/2025-05-12/rust-std-beta-armebv7r-none-eabi.tar.gz=6ae7f3e39e974e20e9cbfae276fd4995063c5702c41085c2b764f3c37cbbfdec
dist/2025-05-12/rust-std-beta-armebv7r-none-eabi.tar.xz=404ae1fc0f5a6995ced2f66fa863cfff17c863096e99b5a04c841b97e6f0e28f
dist/2025-05-12/rust-std-beta-armebv7r-none-eabihf.tar.gz=bf6aaeeba558ac148b693c4e4d231415f6e72506b50ee06b0a1f987374a08df7
dist/2025-05-12/rust-std-beta-armebv7r-none-eabihf.tar.xz=ed3f8767f5e824c5b81178e56c6084c45c67653793128d2c08146533333cc0ba
dist/2025-05-12/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=7d2fae89c459d65fe2cd28acaa225f0ccc35b3f49c84ce6aa86e2c40dba38e03
dist/2025-05-12/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=fc05ce5ee26be4a233181b9841975c0975fc45ad5466d1001a24a01e2a31123b
dist/2025-05-12/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=0335813546a1f905e274135b2bd97c3a0c95f2e0d992d7396bc110b800d3ca8c
dist/2025-05-12/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=7031aeca445d4f8fa351c7ad2e0e06df0386ed11f91080ea65968f1716006bd3
dist/2025-05-12/rust-std-beta-armv7-linux-androideabi.tar.gz=9abd7fe0b7163a141d758ccdca422bd32ed4ad3618066ac022671b082f4641f9
dist/2025-05-12/rust-std-beta-armv7-linux-androideabi.tar.xz=2bcdeb652d42755528a17b86a3b64b13b32d1ba9207cd2c9ccb43fa0d7a1c6bc
dist/2025-05-12/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=1bad15b2e9806e7858d5d4d58f6b2864c3f04e65d4ecb1cc448efdbf0e0030b0
dist/2025-05-12/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=f2d9039c903e5c309bbd17c7567462d4663665cbb7e1d98154022d98a9883719
dist/2025-05-12/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=13aa4a3ef68a87de259726c7c2a3906cbf013836f753b707a453bf91879f023b
dist/2025-05-12/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=8c4f8c044aa4ec6813cec1fed11326f67b0f2db3f20e4b441aba5656af7f0ae3
dist/2025-05-12/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=4c2e5ae8c903577e963af32fdbb39de6180db52907c3f508064a87a21feb9390
dist/2025-05-12/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=c1a12c15792f6b0de81a6e24317d7bea9af023a977ae0558ee3b4598539aa7cb
dist/2025-05-12/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=f789db5aebd9395daf198d5248323fee1eec27533f6d95d0f454339cbc997950
dist/2025-05-12/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=0376d2f2ad8f82719eabb378de3404e066da7d603e27ae4e1620509ccd6eb5b6
dist/2025-05-12/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=9312a8d530c6ca1e72ed35ef82700853e1fba8a1f39bcaad61277a86a974ab18
dist/2025-05-12/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=8c7d99202e5468bbd6fcd818cb832376c00a7c4b09973e5d00b84aa4964b7ff6
dist/2025-05-12/rust-std-beta-armv7a-none-eabi.tar.gz=c4fb94b25d21802136bc36289eea9b95e50b101f64de925a1e9d8ad8ee70aef6
dist/2025-05-12/rust-std-beta-armv7a-none-eabi.tar.xz=6ac88ec457fd554268da3307d40664d2926174cf8e89eb173112c7248776e060
dist/2025-05-12/rust-std-beta-armv7r-none-eabi.tar.gz=c436c2c58d224e1f9bea4703f8ab57cd3f427c60432cca50eb294dde65994002
dist/2025-05-12/rust-std-beta-armv7r-none-eabi.tar.xz=220906e1eca686d6e4a76a80417f527d37b0659adbec940566570292496715f8
dist/2025-05-12/rust-std-beta-armv7r-none-eabihf.tar.gz=eee1788aec77c48c76bc5ba807d42d4bbb7c8f3e9220ba1135764061a9ddf3d9
dist/2025-05-12/rust-std-beta-armv7r-none-eabihf.tar.xz=136f3486bdd8a7e91d738a3f8c1c3b96b853aa054a76c4e83e427ea56d3eea0d
dist/2025-05-12/rust-std-beta-i586-unknown-linux-gnu.tar.gz=72e3c031fa55d131a206d5815899a48ff7bcb19c9ac4b3dbaeab38a3cc4a3630
dist/2025-05-12/rust-std-beta-i586-unknown-linux-gnu.tar.xz=91ca56a1e5a07e1c147a8906d366985548bd961af2aa31dfba60938e457ddece
dist/2025-05-12/rust-std-beta-i586-unknown-linux-musl.tar.gz=839ece94670a9295148231c77573f5b2d8ec5fb9727ab6aa45b8f320201f40d5
dist/2025-05-12/rust-std-beta-i586-unknown-linux-musl.tar.xz=27ec97a6e24184edf4a51de5500d5bb4d4833ad2b7bc771a4506589ce2190062
dist/2025-05-12/rust-std-beta-i686-linux-android.tar.gz=d8f529a63a46bba2bd358e491d7fe0be10fee6dabf0075c40177402aeeb49721
dist/2025-05-12/rust-std-beta-i686-linux-android.tar.xz=a061a703858aa0770d51c6c8bcdfca048efe96b561c460464b835b4ccfdca387
dist/2025-05-12/rust-std-beta-i686-pc-windows-gnu.tar.gz=8b7eb90ad7edb050599dd477c520455ad7e02696426692a0a72094381e189285
dist/2025-05-12/rust-std-beta-i686-pc-windows-gnu.tar.xz=f99e1d82a3cfaef05e6f088e766932a3860e7df60e1f392162746bb08eb72ddc
dist/2025-05-12/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=5d57965f2a6ffff01619e84acdc0f7d9b2afe3c361e5094eecccfa9893eaa501
dist/2025-05-12/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=c1b218aac6370cef9564043c98f361a2938c6ebc7784cb49b361aad3a1bfb6f1
dist/2025-05-12/rust-std-beta-i686-pc-windows-msvc.tar.gz=fdcd4b6f391338fc0f7b72d11fc8dad9df903fb4639b893b57e729de387a9cf9
dist/2025-05-12/rust-std-beta-i686-pc-windows-msvc.tar.xz=c8faa9123c9df0d764cac59e10e94f1562ec7bc7a792f5c63f9a9decd48a3280
dist/2025-05-12/rust-std-beta-i686-unknown-freebsd.tar.gz=e8882425b127d01afcf6269e820bb8c4b813619b6d10f0422fea17c87d5921bf
dist/2025-05-12/rust-std-beta-i686-unknown-freebsd.tar.xz=dabd3bb2560a7949f8984e1dcab35aa46f8e46b09e68c7f2ff32894370ed80b7
dist/2025-05-12/rust-std-beta-i686-unknown-linux-gnu.tar.gz=dd296784ed2199b4c2d85053bce686e01cf867851b175b24781e7e8e6f6ef8bb
dist/2025-05-12/rust-std-beta-i686-unknown-linux-gnu.tar.xz=3bb9069b4456de27cc9fba5dd2b350e5e8215f0460ce9ee375f65856958e4a82
dist/2025-05-12/rust-std-beta-i686-unknown-linux-musl.tar.gz=008ea77ae8d982461c65c25bfcc0c41642ca51a33007a4c8d1ede8612df8f20f
dist/2025-05-12/rust-std-beta-i686-unknown-linux-musl.tar.xz=fdfeb6df04afe1f4e414ad8292a7b75191c2507d020e69f402f97ee9ab3ccf90
dist/2025-05-12/rust-std-beta-i686-unknown-uefi.tar.gz=dbca5a983d2eb2bd84aa7779fc54562bccf9043b31a7f52a3043f1e1e59695c8
dist/2025-05-12/rust-std-beta-i686-unknown-uefi.tar.xz=c0d9abf38ba7b1847fc70b9dbe68f4c27d5a1adb9726dbbee77911f1d271b6aa
dist/2025-05-12/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=c923562d0a1d2830d41212ba140225b9c36087087dde6753e7a891383a095a10
dist/2025-05-12/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=5ca633c2e218939983d77cbf5738ab7d5fc4aa89093a0d1fb701ab06ed7ecf51
dist/2025-05-12/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=a38b4748085b3c06f2154376cdda41fcee2154f1fb409ac5137b63034cfe8cab
dist/2025-05-12/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=43601e0aecb02535ee46b0ddd076867248cd8654be302ae6580a81af33660faa
dist/2025-05-12/rust-std-beta-loongarch64-unknown-none.tar.gz=04dc49b516a638589d907f885aeafa19170683b023d0ee1bf5d78f0d91d0b94a
dist/2025-05-12/rust-std-beta-loongarch64-unknown-none.tar.xz=123f388b208842b3ee46a01ae8efab900c0b5b01b97eb896d26b12bb3aecdeaf
dist/2025-05-12/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=a57452e86c5b768f1feb7f903e4ef8e76518e625c09b5f555885e1d9aaf9b76f
dist/2025-05-12/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=e9d8b99bc4686e199f3aeda5cbfd99d49416a7ba104b494c18ae67a8d1133d9d
dist/2025-05-12/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=3a9f4744fc128be61877967586e6c163cd6ef4e017e04578cb9101c8a9a60cdc
dist/2025-05-12/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=0e693f7c27a34876728565152f7b6b407e1773a187742792ea2ac3f53d6c9839
dist/2025-05-12/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=9d0f6d9cc2b7d1ceff5934a00c780337d2fa77cd9a81cbe9e041e5b18adb43ff
dist/2025-05-12/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=afcd5c9d2e67d6c514630443d9e50d37d36722712e9275e3eaf4f460f7eb779f
dist/2025-05-12/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=9c02e0eb75361a024d25863456c3906b845314481cd9173a6708104a21265e88
dist/2025-05-12/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=5b0628ca22f762796c9215606314babc1237baea075c990e146ee9f9ba1ed834
dist/2025-05-12/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=9e12bd3f2b61b8753aca3a1ed117cae0b4bae2267634a6e24afc0c642d998784
dist/2025-05-12/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=70a6cf1d3e6767656657e5f76e8dd35049bd20a30517f85832c35847c9f63bf7
dist/2025-05-12/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=e2feb3c8bf2390281c71f3b76f07a5a9700e454236bdd2c8f75403cb2247b252
dist/2025-05-12/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=0b533328ff7dfffdfb11826811fa9474c36faebe909f176d60898477d5b9d23b
dist/2025-05-12/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=42b46c1d8ebec202131d08aa21fb6ead760a630199822b4fe88c94a5447f0491
dist/2025-05-12/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=24bb2a24d41bfdb76dfb8817e99759dfd314ce52309d51b294db7a558114f936
dist/2025-05-12/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=5d50c5a766344cacc6e7ebdabddfe720199fca74d1d4284a80ff5625150d7bcc
dist/2025-05-12/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=f6f6e68c0d495b2833566deacac8a6154a220fe1f92deacd031e6b649a63a04f
dist/2025-05-12/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=a80d128b4d0b3b5bb9316da1297b0c1cfee026eea3e9e23c546d62dda9cebd3d
dist/2025-05-12/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=03e27d02bf685f6eb1281fc48d417dcf9f934587fbc743d6e7aac6e0c3691d5c
dist/2025-05-12/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=67185b764c3423704af10318f44f0f310349191d62785bd8cb85ca2bac7f935a
dist/2025-05-12/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=8ef88ac6044c84815bbbcd2b5ce4128349633addf40bb8c439b9a0a07fc5e179
dist/2025-05-12/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=2ab3bbb6de6a5281f8aa586e5fc15d575a34b17b4f44908347d7a776c924add2
dist/2025-05-12/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=321b0167c9481ab88ff44bf920fa15bdb4e07c864a90b6777f3c8dfd0e5c5ec6
dist/2025-05-12/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=bede2674247df8ff2153808f499ee1c1a7a909ff87600513ebc2998f43c7c1ea
dist/2025-05-12/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=b903c9ca2344fd1323695052f74b9562f6dd3cdde4872f935bcba6c0fb988dce
dist/2025-05-12/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=ad90fed7ed9137d04aa8c41d1c7e856dd8cc57a0f4b7836b22c9b1932a24a769
dist/2025-05-12/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=78372e3e32174a2cfa12dcd426e36fe29ff76779d8815944e6f6c7be4a3c55fe
dist/2025-05-12/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=a781d0ee95ae3012e3d016ae1b029ca8507ff549a6b1e0a6f052bca6d4afbc7b
dist/2025-05-12/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=23b1cf7192f044a0f46ccedd654aa203dc0e9fad47c5ffc2a1e6717bf6598d69
dist/2025-05-12/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=dfb15324b8047bd26a58a26d373af441182808203c06a3d4e595d79bca21b757
dist/2025-05-12/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=432dfeb9231b67537dc5c77941ee26fd73404ea16dc1be4071b98c13680ddcaf
dist/2025-05-12/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=cff18fbbbe323c67779651dd6e3b94a76a573567720985d59a091c26a3c33110
dist/2025-05-12/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=c5f25038ba5be3ffddb6966e89017de862a0d9f267a57eeaae81b3b2a44d5690
dist/2025-05-12/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=104d762d5a45fea227880d2395068824f9202e5a7fbd30bea478bb1ee6899ee2
dist/2025-05-12/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=de1f15d6cfafc275108c4584a294128962dabe54bf5a1f6e81da3508ea9e8a14
dist/2025-05-12/rust-std-beta-sparcv9-sun-solaris.tar.gz=531562c65d558a993128054fcfb29f0d408a40318ecd5623b5b24636bd7b0a07
dist/2025-05-12/rust-std-beta-sparcv9-sun-solaris.tar.xz=af866deae0c10ce2b11c0ebe37fdafef79285bc694eaba75213316ab125b198d
dist/2025-05-12/rust-std-beta-thumbv6m-none-eabi.tar.gz=ff623d437bda1c0b8cd8affd2a6bc165b8224a5467894aa54dee63b1b6939fc6
dist/2025-05-12/rust-std-beta-thumbv6m-none-eabi.tar.xz=d8743e42057014ef2742cec5b93e34d5cde5a658d3ed9e7e738276387985122e
dist/2025-05-12/rust-std-beta-thumbv7em-none-eabi.tar.gz=0b097cef25dfe72f692cd6d9dd2df85a2fc5ea9db87b8c06b8f310c239c74624
dist/2025-05-12/rust-std-beta-thumbv7em-none-eabi.tar.xz=e7fd61ad7660c7f8c62ae6dbbd238305d997fe7539dfffb8fd0df2205656b5a9
dist/2025-05-12/rust-std-beta-thumbv7em-none-eabihf.tar.gz=d6b3c40bd84fe352c1a88dfbc3c0f9012dcc1d82b860ce68c1d21a8d452fa662
dist/2025-05-12/rust-std-beta-thumbv7em-none-eabihf.tar.xz=b2be1305ae382359f81e0bff16341719b6ea7731ff833205dc3fd99e7e978fb9
dist/2025-05-12/rust-std-beta-thumbv7m-none-eabi.tar.gz=5452dc0f152065e887178423e324bf3082885b922ac57ff22c156cf7c432e184
dist/2025-05-12/rust-std-beta-thumbv7m-none-eabi.tar.xz=5331de420a79f521351a1ea3dd501cb00b21e1979eb23dfc871ce33abca68dd7
dist/2025-05-12/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=0b2ffb463dca747f00cf063d8fb07971df80882d3890c34ba82fbf1b77655dd0
dist/2025-05-12/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=2f7c2bde8ae4b911889dc24a8fbe2d1539685d46c71689e5e8362cf46c391019
dist/2025-05-12/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=1d29e86aa77e277ce1598313d6851f2f077b023217f1712d59eb76305fc773fb
dist/2025-05-12/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=73dc975b217329d6ad44b8e8b3f72a3396597a207df7d7222d983a155ca05758
dist/2025-05-12/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=c34c686a62afb45b9e57b3d487dcc1f66396bd7804a9c0d9696def0936a2ba1f
dist/2025-05-12/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=1527843f87588ee28aaedbb0590bb809c24cbde6a5264151ce5fe01baf70176d
dist/2025-05-12/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=8225d6b35a55d7937bbcb7f2e74ab8ec0f23fcd69a48c59391e9016d9863151f
dist/2025-05-12/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=8c59ed4aa0a62ff8999570b60a6b9c468ea52c45642ecfdc515d6f2722fd821b
dist/2025-05-12/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=6a5804a7dc199f696867e4612d1381910ff9a13b5516b2906e651451d8ec23e8
dist/2025-05-12/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=11205a43892169cd0aad2764f5d7604a52d13292978e7e851cef2d8e65ae6fe5
dist/2025-05-12/rust-std-beta-wasm32-unknown-emscripten.tar.gz=962e092960bd3074dc966c1928a4adfdc16d6d811060e719dc1a84061132566c
dist/2025-05-12/rust-std-beta-wasm32-unknown-emscripten.tar.xz=5d7fe7b3fe3b022c95d96e4027767b44a7e7980ca5c894839868919a0bb4b5bc
dist/2025-05-12/rust-std-beta-wasm32-unknown-unknown.tar.gz=38afbfef695bad377ac9d3a4d7d9037b500795c3a75f907bf60acd4cac2b4cd4
dist/2025-05-12/rust-std-beta-wasm32-unknown-unknown.tar.xz=f5f670d35a843cda6f5213ae02a99c3c6d1e30f3ab651be0087bf8e4de0911f2
dist/2025-05-12/rust-std-beta-wasm32-wasip1.tar.gz=e7faeb24fac65f565e0145166d67a30b02b26f0df20791f3bdc31169846a0e2b
dist/2025-05-12/rust-std-beta-wasm32-wasip1.tar.xz=0136f4434e8a0edbbe050899a17ae2b2825aeb4b98c4fb80f8eb25c9ea6623ab
dist/2025-05-12/rust-std-beta-wasm32-wasip1-threads.tar.gz=2ed823ff5c3704f91048300fa31624cddeea8086cfc654fa2fea4adff58fd901
dist/2025-05-12/rust-std-beta-wasm32-wasip1-threads.tar.xz=6f156a460db83c271b43c37709ce5724fb8059c44b29e08c2b2da27c32c06e5c
dist/2025-05-12/rust-std-beta-wasm32-wasip2.tar.gz=ecd1ba1fec2e1e87b5f30b341e8228ca98545143adb8acd6ba53c7503f581e34
dist/2025-05-12/rust-std-beta-wasm32-wasip2.tar.xz=593976f715c77796cecf6f7f2b79fbd4f49c10ded0349762e8312052497f1e28
dist/2025-05-12/rust-std-beta-wasm32v1-none.tar.gz=396eb4c1e4cd930f045b092bbc8203315f494ea32c836d62e84f63ead124d886
dist/2025-05-12/rust-std-beta-wasm32v1-none.tar.xz=9b827d1941a1d67a32a255342b476a19f57de06e53a9e6798bf00688b86eb2e0
dist/2025-05-12/rust-std-beta-x86_64-apple-darwin.tar.gz=2796de44843d68141c6330f0e09fbabb5c3a8f34470d2948f1ed93b1b9dac088
dist/2025-05-12/rust-std-beta-x86_64-apple-darwin.tar.xz=881e98599e5b2475e8c9f6b81e0ad6a51e8058cb2c7fc893ab57c19cdcc80804
dist/2025-05-12/rust-std-beta-x86_64-apple-ios.tar.gz=8203faeaf21dc2c86b35d4362413c12d01de33da4524008c6261d3c87be9e51d
dist/2025-05-12/rust-std-beta-x86_64-apple-ios.tar.xz=13a59816008d3d4b0fb20680bfe2f1c2ae8ca7eed0bdf717817e03693724eb25
dist/2025-05-12/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=5b906fe2d801c572696cd93564723338385eb574587769f79506cb3e6c87452d
dist/2025-05-12/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=1624a408800a895d8fe71bfc71876e52349c3508e9ddabd46d89d3274ede2dd7
dist/2025-05-12/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=6722e76457289c6551f77fd462058862d7fb8597e1714cf66925b21e5af75c7b
dist/2025-05-12/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=8097f509383cab4e8e444ccbf7f5d91fe35bcd2cd2017ab78bcc692c9fd1ecf4
dist/2025-05-12/rust-std-beta-x86_64-linux-android.tar.gz=eb3124653c908003185b36aa9829ea983f4b44e11a96da69c2585664a67bfeaf
dist/2025-05-12/rust-std-beta-x86_64-linux-android.tar.xz=4f29c6a0458ed5e37ee7a17643ff7854bd6ed029c46cdd0707019d01523a7a62
dist/2025-05-12/rust-std-beta-x86_64-pc-solaris.tar.gz=319663b24b449df3f8063f64bd849969999a441b9376c86e6eea15cf3b872e5b
dist/2025-05-12/rust-std-beta-x86_64-pc-solaris.tar.xz=13280470aa4c84ed6ca200664ebf3a6aa084550a82c06505b3178caefe3072ef
dist/2025-05-12/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=d97cf2b52f013b5cfdd9c5a3885ea70accdf52e2f957e086018d88731c8c1964
dist/2025-05-12/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=a2685ab1c204823b19809e47b00f2c48c5f2cc2faea05ac2df935732a7412441
dist/2025-05-12/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=50c0f770a938123f704837bd3313dcb12842aba75b687282a9aca6c11b11ba8e
dist/2025-05-12/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=8f0d04c8d55f23235f8dec94c5d5035405afd513b082f00b257bbb86cd481240
dist/2025-05-12/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=e633aebc178d4846a3d26f796405dde13115560c23bd2955c82afea8ab7c8d7b
dist/2025-05-12/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=8125d5bb9a9205ffab43d0dcd56402320643101169a49098a98ee6ae785c0ed3
dist/2025-05-12/rust-std-beta-x86_64-unknown-freebsd.tar.gz=c089415c86c9f74a454b82955911e84c9138ad66757e4da689381a1bfbd4cee5
dist/2025-05-12/rust-std-beta-x86_64-unknown-freebsd.tar.xz=a930b94bc005ce2b09b4d67abf47bfeafad8c7ab6ca5c15acc10e023818e7b25
dist/2025-05-12/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=f74e77eb803d1ca244e1e97272578ec008e9c373af92887318d9281204a798fa
dist/2025-05-12/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=2fa583fcde17c1ab2f2d148af9467fa65f6bf6a0a1801e957fa15a79e6de4f78
dist/2025-05-12/rust-std-beta-x86_64-unknown-illumos.tar.gz=20d16ce11adf468da51b30c0b55a46ce3bd030eea9f9fdb3f65f36aa442a3d71
dist/2025-05-12/rust-std-beta-x86_64-unknown-illumos.tar.xz=dc1f2d3c1a0ae59cbfaa09b2d646645cb4fabb151edbf92975e4c8a0bfa54eba
dist/2025-05-12/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=05b2e5ded14501cbdc86c0510faecbf873e30d2d70724013bbb176b6f4039b44
dist/2025-05-12/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=a18281579cb61ea26ae0062428f7a49e51c4a928102a5eba7ff96b0ca38490c0
dist/2025-05-12/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=a5285ae02217d64c7bbddaa3dd1f68c361f2849479a6d75edf1d551751886f7d
dist/2025-05-12/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=4c41edc4f4cd1f24107b1b003a1713af3b456ff3e933781c5d4ef21a490df5e7
dist/2025-05-12/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=2d4c1666d456e810353f8b386d0d331812f84d9a17344953e5f4f4370bdccb0f
dist/2025-05-12/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=287f51dbc6e4273208869140b9c2e0de2896c0cd40f7492396ec0bbb8989a82b
dist/2025-05-12/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=e20af62d1900a5e10cf766ddcda9550176ab5f41111e09d57167e4e23e68d005
dist/2025-05-12/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=7837f4880ce5d5251213d17867a6c61977504840678388fe245e0433086f409e
dist/2025-05-12/rust-std-beta-x86_64-unknown-netbsd.tar.gz=17d2a43bc24e4e49d54315c7eb0e4952c3118b278b0a564fd588ea4ce0e8d90e
dist/2025-05-12/rust-std-beta-x86_64-unknown-netbsd.tar.xz=ab34b5b10273c639805956665cd6543749cff2748c53980f80342facb9171b2d
dist/2025-05-12/rust-std-beta-x86_64-unknown-none.tar.gz=d8387a8478f6a937944d684f852dee18d584344ab84425d228489dee324c318c
dist/2025-05-12/rust-std-beta-x86_64-unknown-none.tar.xz=6ed8c2c72d547c7cc6b32a6080c346915de02a1ac02f032b6320fc7e3d45e330
dist/2025-05-12/rust-std-beta-x86_64-unknown-redox.tar.gz=7f3a62578694121ef90fd08ab7a82a8fb27d86f164d7f73edb56a2e360198f41
dist/2025-05-12/rust-std-beta-x86_64-unknown-redox.tar.xz=44f7ba0ca447050ad3eb7be0a0e41fee304dad2ce359c854848b7430c42b22d8
dist/2025-05-12/rust-std-beta-x86_64-unknown-uefi.tar.gz=f78e6eca6ff517571480a6bbe20099d170f6a6b2ff0e64544c41dc77588ed890
dist/2025-05-12/rust-std-beta-x86_64-unknown-uefi.tar.xz=d2a733aad6929be6135676307bd4576eb168e11192c24051e0be4a713b5733c5
dist/2025-05-12/cargo-beta-aarch64-apple-darwin.tar.gz=43afffa0c5f7287e205a63871b555be144e900f8d8d67e4ed0654b50809b7338
dist/2025-05-12/cargo-beta-aarch64-apple-darwin.tar.xz=705f051543ed8cc7011d7a866f345c3aa22c9d24f5325bffb9d9676e3c26142b
dist/2025-05-12/cargo-beta-aarch64-pc-windows-msvc.tar.gz=c0911e84ca85de5e8c9550e2be08dd85458ba31516e282044c9149bf8bb56fa1
dist/2025-05-12/cargo-beta-aarch64-pc-windows-msvc.tar.xz=7335470fc1338b95edc81777eb0975cd5cf5cdcdcaefc7658f356ef3e0c54fda
dist/2025-05-12/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=99071e036041b47f78b71f1ff2ef5699b96a126ea84010ac031ee8d52d7c5873
dist/2025-05-12/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=a9be2eeeed37905e83beb4265f4f45086675a0f5ff25db0e6bc0c5164257e1e1
dist/2025-05-12/cargo-beta-aarch64-unknown-linux-musl.tar.gz=b38fa8d68c27b4989b1dc94caaf6bec833cc8e6d4464b859451d495b081c5b1b
dist/2025-05-12/cargo-beta-aarch64-unknown-linux-musl.tar.xz=95a839bd2f928afafbe1058cb185b95e0099ae15d5d3030a3493724f40300ae9
dist/2025-05-12/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=34cef4599ece9c218c3841ccff9a627a69909eb733c19441c19de5b68841845b
dist/2025-05-12/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=cedfde42e95a0e86c3be841965c20f1c8bcebd20d88f38b2e694017a8afa745e
dist/2025-05-12/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=b8f1a0fca9b32362da6169b41fd58d53af6b02992ac5666cdeed03aa6150dd0c
dist/2025-05-12/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=8f5b040e4099a03418b72b5975419089e7fa15a947b04ce6dd18f450cc21f2b4
dist/2025-05-12/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=2f526034ad1280d152861e700fad2aef95759eaf17780a3a00d71e8fc6d8520a
dist/2025-05-12/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=b6fdc7a08740d06e29aa678f4f9cb2dfb57fb863605fba1cce67d71ae1c1ace7
dist/2025-05-12/cargo-beta-i686-pc-windows-gnu.tar.gz=f8b1e0227f5c1c2334cbcf53ebe5e94e01215ce21de2c5c9846e0ea7dce8e777
dist/2025-05-12/cargo-beta-i686-pc-windows-gnu.tar.xz=149bc0d8cba9924db3b882795b6dd17f3d0a01bedfa75143dfdb7623cc7c4684
dist/2025-05-12/cargo-beta-i686-pc-windows-msvc.tar.gz=b8462286bb1746bb789f580a14f1c5c37b108037633d9e8fbc5e2e6638e12a5c
dist/2025-05-12/cargo-beta-i686-pc-windows-msvc.tar.xz=f07104b3439e4cfcf5c96dbf6bf4428f677f45449ce2a5595551884ab0a6870a
dist/2025-05-12/cargo-beta-i686-unknown-linux-gnu.tar.gz=f68dece61dc087622d9e622944c4c13cdfb056eecdd93c9527c71637c73a708a
dist/2025-05-12/cargo-beta-i686-unknown-linux-gnu.tar.xz=3272d868a2bc44b80d0ab11d133f66ed7a40b75d00fbb7a341adbee083dfd8c0
dist/2025-05-12/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=2fa7ef9b0f5247a650c1cf649e7f5514989a22b6c7927fa1df809e54466bc18f
dist/2025-05-12/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=3eddae3525cd8b446a4b31ea933cb859d335b0309900379868230d4a63979afe
dist/2025-05-12/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=88d56208387b4aa9707729f0b9337c32a0516dacc4c891b3c80140874dec6043
dist/2025-05-12/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=8e4ceefb3d64560d989bf69f3d58cc07ab2e6a68d1f761ef92cb1826351834bb
dist/2025-05-12/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=ed5705fb6dba34981727e4af215d8875de2c39d41b1c3e8653a93cdc06873975
dist/2025-05-12/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=be618816cd7706709fc13ab268249a74f7b905e7ae6abe6ca1fda336dd38baa2
dist/2025-05-12/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=8b53a21201661914e3291ebc6912083e1cd86ed5d202d6940c2be15724371bc7
dist/2025-05-12/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=546260a68ec029f228f280fc439e93dc1f64b3e597cf615ff3915548ab67b435
dist/2025-05-12/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=343a00f2cc571ac779fd7647560b215650a01e877c9b15f95668cfc33c67ec77
dist/2025-05-12/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=efc6a23ffb467e1459f3fe5932e8303d0ee550853ad13b3ace12c9aa6514f24c
dist/2025-05-12/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=5c4e53aca46fcfb7d669b74872130fa2b8bf05b09d14bdce34f0322030450e47
dist/2025-05-12/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=c2e33c9522924cbfde1109f87d12d27225ceb23c7ad801d3a5559a72715ca402
dist/2025-05-12/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=91d578317c8fa147c22e81728da411fd01c1fcb0bdf2e054948537476b8371e8
dist/2025-05-12/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=83fc425704b7673943583e38c31a944695984ffabcdaa4ab79b43aea03cef48e
dist/2025-05-12/cargo-beta-s390x-unknown-linux-gnu.tar.gz=dac65289a906a32908ff0af9e9b829111295b49099fd5d9f90b2e454b4ecb422
dist/2025-05-12/cargo-beta-s390x-unknown-linux-gnu.tar.xz=02a3972bfd62d4097da252fed278d741193f2c4face2e35ce8e84974e42cb1e1
dist/2025-05-12/cargo-beta-x86_64-apple-darwin.tar.gz=148d0410ec2d3e540cfc27b6756e50d98b7ed214c2e5a702a9f2326e75ec249c
dist/2025-05-12/cargo-beta-x86_64-apple-darwin.tar.xz=65e993adfc14eb7a9c3946a3d1ce35f5aa9767ece65cd759669bb82deda0adc8
dist/2025-05-12/cargo-beta-x86_64-pc-windows-gnu.tar.gz=a69c23bfe9ec73737c22d0b6ce308a4f19625aab2f1846bc223ec6974cdd9163
dist/2025-05-12/cargo-beta-x86_64-pc-windows-gnu.tar.xz=56b33a8c9e0bcbbdb2c6be13d7b84d077a896b21d800a3c6da64aa2ef64ecada
dist/2025-05-12/cargo-beta-x86_64-pc-windows-msvc.tar.gz=cfd22dda3987642606f9e869264fa709d87b8ac5894547f809f60abce268ff76
dist/2025-05-12/cargo-beta-x86_64-pc-windows-msvc.tar.xz=7075d67ef2dbf1e0d3889039d4db66042db538304c53cacd3e983eb9aa9d0275
dist/2025-05-12/cargo-beta-x86_64-unknown-freebsd.tar.gz=419ce0f856113509f58f2fbccf9e5f864aa56c3c1a2c4029ecdb546464393214
dist/2025-05-12/cargo-beta-x86_64-unknown-freebsd.tar.xz=d8f73cb808471883a5f6ee8db3dd5165fff5084ae744f4ffdca89fb545faaba8
dist/2025-05-12/cargo-beta-x86_64-unknown-illumos.tar.gz=69e63b33c7f8d469232504c373a4e35df97016735be633a818023ea21de8f0be
dist/2025-05-12/cargo-beta-x86_64-unknown-illumos.tar.xz=aa86cbf46dd2e35c10bb5725c627dc40ecb33329a866c2b0c5c274728f384ed3
dist/2025-05-12/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=f77e6d762e13eb95d6369a26971e4108de448eb23690554914f650fadd2898de
dist/2025-05-12/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=8e4b379bd88e8f18e5b6efe6058bad4ee60fb6c2e734ec165fee188f893f948d
dist/2025-05-12/cargo-beta-x86_64-unknown-linux-musl.tar.gz=a04b711f9a07eee991b1ab13ab56e0f9e2c2ba2a16186be6c0d04529ca68af59
dist/2025-05-12/cargo-beta-x86_64-unknown-linux-musl.tar.xz=587b214ddf5b85697b78d8baa9164a4b81604b8dccc969a03b1bf06ae7c11240
dist/2025-05-12/cargo-beta-x86_64-unknown-netbsd.tar.gz=81a468f1db3cbdaddf6a1785297457d4780fbec472d0bdfda64fb7a398782a78
dist/2025-05-12/cargo-beta-x86_64-unknown-netbsd.tar.xz=32212f4273171d78e10170c4a863d6f9990e29e26fdf6857dd3d134eb803161d
dist/2025-05-12/clippy-beta-aarch64-apple-darwin.tar.gz=e5de69a84edb22eeaaeea2d94aafb07ed408508f68fc0989268e6dec8bae6a8e
dist/2025-05-12/clippy-beta-aarch64-apple-darwin.tar.xz=03a9ebedbf11cf151d19f46b9eeb3f8ea765ac779b55356b51db21e83195c610
dist/2025-05-12/clippy-beta-aarch64-pc-windows-msvc.tar.gz=5a9e27ab31a382ba91f9621508cf28fb4f5d0f2521452369ea2441598d34b2bf
dist/2025-05-12/clippy-beta-aarch64-pc-windows-msvc.tar.xz=951c9f03a6fe0de1e94ab8f064cfc1b29b06606c38e891c2f9f1c550e9d94678
dist/2025-05-12/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=1a241694ef544259a3c87bf271b1248ebb6fd32ac35b3ac16154e509b80c6e47
dist/2025-05-12/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=679c8ed606c22490fb0a5a8503d898e61199e3cd17d9dd7a34c121781ca7306a
dist/2025-05-12/clippy-beta-aarch64-unknown-linux-musl.tar.gz=26ba8ec943e4f8cfa27afcde06fd34dcf546c3a5c7668acf703a9b962a1977c8
dist/2025-05-12/clippy-beta-aarch64-unknown-linux-musl.tar.xz=051112fc6bd906c62cf14d2fa9c7f1505540a6aa86ee0b1889e11b1925274c23
dist/2025-05-12/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=a44d29c794e49742417de03a955922ff3634ad45a5e6b5799c767f3feb2ae7ea
dist/2025-05-12/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=1650c464df6d87fcf3cea65722a515a1f1625d9e1ad6d27359455ecab849a592
dist/2025-05-12/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=1c4f6c22361665705334faf35a0a7c17d55fb3fbd2622721e8cd7c76418cfc41
dist/2025-05-12/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=f75400fc72fd358be80cbedefc53a9002fe6cc22637687e941835acb8c5eced0
dist/2025-05-12/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=f1a2db6029e9d881dbfe7c6589873b323358d8317865824705c0cd358fa3ef49
dist/2025-05-12/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=9cc0a2212a36bfb39379008b781304da67c74ab4ce0909da18f8cad50fcbbfd0
dist/2025-05-12/clippy-beta-i686-pc-windows-gnu.tar.gz=06051eca41cbd1b570725847b4d8b79f29bd20ac06878ef5689167626fd4b137
dist/2025-05-12/clippy-beta-i686-pc-windows-gnu.tar.xz=857d43d424e718e04714562132802aa5fc9028945a3c40c34508abd165a909c1
dist/2025-05-12/clippy-beta-i686-pc-windows-msvc.tar.gz=58bf660a2f3ecf4671de4624b12b5a35f1e530d3c16f47eb7e114d1deb1891ad
dist/2025-05-12/clippy-beta-i686-pc-windows-msvc.tar.xz=5a36ec9ff4e35f1a49775e6657ea4f65543b47ebbb776fa1c60fa7898666de62
dist/2025-05-12/clippy-beta-i686-unknown-linux-gnu.tar.gz=30df536f3cf6fbea2cf745ca8177f88831ed5b5e25d8fbdeee5f300fb35b97fe
dist/2025-05-12/clippy-beta-i686-unknown-linux-gnu.tar.xz=a491efcade35834adcbcfa8f08004b6a181a8d8fbe36f6a1bfd8e092443a82ad
dist/2025-05-12/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=a16579fb92973f609f0eb215d81e1125ad9dfa9e22d5d869236bbe0a7bf8050c
dist/2025-05-12/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=45ff10aa52e6162b015b1a927dd23ef7404fbbec554e5a1b655c085d59a378e7
dist/2025-05-12/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=37e4ca4776fb278cac2ac05ece43ae569780503d0b122545eebc7a746dca69f3
dist/2025-05-12/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=9c33b12b9c0a6d94b16a52066e3a1a8a2581db1c7549de002f0d6f4670021f0f
dist/2025-05-12/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=a7939ed010f6cef23e23e17c7ad905c6c0f4e549c85a8ae38d743232fe8de321
dist/2025-05-12/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=21046d6fe31c0930e4611a18dcd48f5cacdcf3b64b5d035b4449b8b5af417254
dist/2025-05-12/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=a03df872f97472d9a4310c8097042ef80ca859485fdb95ed9bcd853de3cbe9ec
dist/2025-05-12/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=925ff3b371f6c4ec871920c5e9fa5ab046f203c0af95f10f0996a750bd125582
dist/2025-05-12/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=5f159a1913f6a5d10b5d5140093c9af4277d8a632db5cc116065a08fc0ff8bb6
dist/2025-05-12/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=a2385ac96c42af4d77eb84ca70931e005aff1dc0e1ba272483ee82a837d96709
dist/2025-05-12/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=9c289ed719cd18c8e5b883aeecc03e46f35b6b90d191b4fb0d0b4b6c7fc5073c
dist/2025-05-12/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=1a62cf477d5ad2ce4904a4438ab5756f75b894288a7449ae70c9f63d3b7badda
dist/2025-05-12/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=c1abab08e81632db27613f3ac7036d8ffdeaf92e345b345bf2c3535f4d9c16f0
dist/2025-05-12/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=611252f8b142af9a86e511ae783f41cc97104d2e5ec5835c7d5006421ff6207c
dist/2025-05-12/clippy-beta-s390x-unknown-linux-gnu.tar.gz=d436be0f0f72db3c4933e8e34fcbb71e33b90ddcca58bc4b4360fe22e7a89404
dist/2025-05-12/clippy-beta-s390x-unknown-linux-gnu.tar.xz=9f8086f13b6f53d44f03bc53fa3d750a9f4dc13b3612b10dba48958f4b61706d
dist/2025-05-12/clippy-beta-x86_64-apple-darwin.tar.gz=1b4a51c42bcc9e3241ceaceab3fb22bbf8060e9f4c2c55357603c1bf2fbf75f2
dist/2025-05-12/clippy-beta-x86_64-apple-darwin.tar.xz=42556126bad0e0554dc5464396383c75a1fcb76257249c62ca4e40971129c458
dist/2025-05-12/clippy-beta-x86_64-pc-windows-gnu.tar.gz=59a2a00a0c4e05cd0900fd119f43d4354b9f6b9df9dd9a9b44a1cfee9c674eb3
dist/2025-05-12/clippy-beta-x86_64-pc-windows-gnu.tar.xz=35290a11740a2fc0c02d534375ca4ac0392de41f281383d7396179f670ddf309
dist/2025-05-12/clippy-beta-x86_64-pc-windows-msvc.tar.gz=db01970a436b89d5fe3cb5eb65ea075f7dfd15b649958b35ea8d88835d8fe1c3
dist/2025-05-12/clippy-beta-x86_64-pc-windows-msvc.tar.xz=9df8c8ed117b2e975bcb0520601c9b4e19e0440b14d9e510d09c9b54b872379f
dist/2025-05-12/clippy-beta-x86_64-unknown-freebsd.tar.gz=736361d62d33e969bda4cb98ea592ee7128e88c047f05b77cc025c982c27acb6
dist/2025-05-12/clippy-beta-x86_64-unknown-freebsd.tar.xz=72f50e46dd2697c32b20ac2d0ae9ae2ea10485225dfd41dc9fa4e24d3b61a26e
dist/2025-05-12/clippy-beta-x86_64-unknown-illumos.tar.gz=4c856630844d01f655dc9855efb3685c2c30fcf199edfe665d9cf4230774ae0d
dist/2025-05-12/clippy-beta-x86_64-unknown-illumos.tar.xz=70bad50bffa518c4658e44dda7b6723558d68a545511228b97e18efc37a3ad0b
dist/2025-05-12/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=4c1e0fc35732f19effc50e67f637c57699ed7e846e4201db3897740c1e34a43a
dist/2025-05-12/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=fe53a5340c93485ac496453752a15222d323755cb20427b29b952b49f317a4bc
dist/2025-05-12/clippy-beta-x86_64-unknown-linux-musl.tar.gz=c56f80644373fbe9bb87310d26876a86325fccb1756716db30a5bf70293d328c
dist/2025-05-12/clippy-beta-x86_64-unknown-linux-musl.tar.xz=f4597f7ed6d0def07a32e952330cc964e49d42f84d65eead84192a29978c1a41
dist/2025-05-12/clippy-beta-x86_64-unknown-netbsd.tar.gz=ecbc80189d470c1cc221360b94964fbd26d52b7583ea065cdd52795a48bf6271
dist/2025-05-12/clippy-beta-x86_64-unknown-netbsd.tar.xz=f08204b9216fcb127934f2ceefeb7abe4338bb2ab79576a3a2e2077201f521e6
dist/2025-05-12/rustfmt-nightly-aarch64-apple-darwin.tar.gz=269b22b568f60889c4841feff1c11d9c151d2655d134e966f7344f7affc6db57
dist/2025-05-12/rustfmt-nightly-aarch64-apple-darwin.tar.xz=474f13aa57c73f4f9e3c63edb9a126ca845e63a376b7b8e35b5c6aa8fb0d9573
dist/2025-05-12/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=9f24753d7abc9aa196a72ac54bb574f5eb375ecd5b2da42d0ed34bf0fb8eb947
dist/2025-05-12/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=daae34864734810ff8ea563db7bf691f6c0fa56b9087fe285f7a3060247ef6e3
dist/2025-05-12/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=c21f59bc03b8097f066be7bd3a7d0febe873f321583a4c7a9a0cdf5448d92ced
dist/2025-05-12/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=574fce0d0ff06850db47da008fdc6c6551f2cc459f63f69dcf8edae5e5ff51eb
dist/2025-05-12/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=6379365fb729e0f5d57873ad028f0c2641d60bc19ac5c905a2d1772b6730cb93
dist/2025-05-12/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=a274c20436d31f74b4144f165a2b383297316f1f96b0d89b2b86bbf38e57be98
dist/2025-05-12/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=03c3270a78c5d62517ec1b5c61414634ad58e5d4afb914f31bdc12ee0893ff2b
dist/2025-05-12/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=b309c052cdae48b23c2e89dcd7362af97f50181745191dee596ac176c2ade8a0
dist/2025-05-12/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=300baf318827928f0c824e20ccc8966d3fe9e5b5f62a0d1aeba5feae1d183a11
dist/2025-05-12/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=09b764e2038499d23b28b8cbdb01c9480f2100a01d864b7f03905bc78412fa00
dist/2025-05-12/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=47c087899d4155750e71a261a0c93c9f736530d991dfa7e34c1a7bb7f2aedd8b
dist/2025-05-12/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=7e589aaaac2ab2c1211e5f5e1090b2ce1633f8b8682425aff01afd4dbd25e088
dist/2025-05-12/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=0169fb75018dd644d7ed842472c04a5c82d46f3bfebe6d49931839809d1824b7
dist/2025-05-12/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=96f3e288c8ccf073b1ea983ba382e341c8f6664135ad9aed7168bc05cf06ac4e
dist/2025-05-12/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=29b1f7a4b1454bb1c6af1e720e05bda846725a8e866266a147335920e99e66a9
dist/2025-05-12/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=71a2f81ff29fd7e4c8dbdb2ce85bebf5e8ea5889cbb41f98fd3c3816918a6a3d
dist/2025-05-12/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=ae5458b4c0d58bc3e307c289aa44daf82218aaafc7911dadd4a09f4ca7cf6e12
dist/2025-05-12/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=cf19b582a8336aa3f3959803cb24ad4499bc529bd58cd0766e668af5083de93b
dist/2025-05-12/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=474a34a9566402e313f5fcfaefe29188a6db1c0bd17caa20f186787267ac8e5d
dist/2025-05-12/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=c02f75eaa71f6c4d613a80dc7092d57cd4f6ef8a7de7511711fa818c0612da24
dist/2025-05-12/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=95b47139ab6e9c16acee5ac78744c3e9ac917a5e811f45adfec4fddd45e98cf3
dist/2025-05-12/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=fe13340e51d7d81629e03019d375a72874b80f19420c77ea083292a22a9be589
dist/2025-05-12/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=a95ed14a5bc2f926c2ffb5dfe49813817638154edef7f29522661c57ec2dec09
dist/2025-05-12/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=d9060c0aa08e0ade2fb54fb5381f0f69dc94166741200b2ed35a46b5d9885036
dist/2025-05-12/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=060213e707c6b8911517e786b21515e169e062bbbf96302e012a442d260789e1
dist/2025-05-12/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=f1d4dd54017937490f559a472893fb8a00236b46bf0f57ef9222ec3bbd191004
dist/2025-05-12/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=38a57b7fac63608992995b3b983643ae213f6fa3d6a1021691334d84a5491542
dist/2025-05-12/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=f26658ea60a6424707a027b1e36488f99490bce045978c3919c7320638f60d68
dist/2025-05-12/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=07fbca58abf5fc57560e20fe7aede77137dd3f2f4cf2a6da11a80eaf6672bed3
dist/2025-05-12/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=f56f7bb1091fbb1a8d1583beb586194e5dd526f7a0268b4ebe997e0ce7c9d9cb
dist/2025-05-12/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=3ec40438a95a086a1c4c522c6ae018393469f605b03d392562fca4926bdf0631
dist/2025-05-12/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=d7c342edbefe3fc22631961c2aca53cb808bc8f1df17673ec5cafcc56eaf0475
dist/2025-05-12/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=4c1a2aa84e8e1c67a111b9a622b2c6ed96eebcec9752ccc5e940460ce048f22e
dist/2025-05-12/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=e26a0359223ca793d34ac9e4e5731923c4531dcdbf32aa8789bc9d1bda17013f
dist/2025-05-12/rustfmt-nightly-x86_64-apple-darwin.tar.gz=dbf20af35cbe11baab7ead72ec254717642b01fdf30140589510413058af3e49
dist/2025-05-12/rustfmt-nightly-x86_64-apple-darwin.tar.xz=7beb25f2df0877ee74231abe03e74a09c6e41a356d0cea27956b2091382dbf47
dist/2025-05-12/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=527d2d68bfd519d49936fd8941a04d787df1edf8c2c3ecc39103d55d1683a970
dist/2025-05-12/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=8744bef9d00d6f7397ef2b1b36971ad7af6389e93b5286ca60feb6137c4f6b10
dist/2025-05-12/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=50f8f2db4f410e60a6cd4ad03a762ea636076d85af05d511f40d2d2ea98bc833
dist/2025-05-12/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=183f8742c505ab1d0488ca915509c1b0558166c6d19d8dc864d0a1686d66a791
dist/2025-05-12/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=f042a8c4ef96911b2cc6cc2228ff832229196b4ab5b1b04b05b22b5b9a90649d
dist/2025-05-12/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=9b93acd9cb8c8e062f3e47f5415adb8eae67479318b6201bf66119d467b81e11
dist/2025-05-12/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=fe9073a3bbd3b6513ba0fc38005b8ab1d44052e1bb10c1976bc98a62f8df5934
dist/2025-05-12/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=4c99f67e351758fe0db0bc7cdfe177018083b9ada2feeee952180b420e2c6ac9
dist/2025-05-12/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=c5a5702c66ae7de6b7a10d1c8c39af6c973c6eeebbc1fdba3b427c1ec9588756
dist/2025-05-12/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=8da51f6150fa5c53dead4c3db2c2d7493cc46b36d64b978e605a9d5755dfd779
dist/2025-05-12/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=3d77d2579fcb53a9bb6d942d44353f7b818b10504b64b790ecc3630d8b17a565
dist/2025-05-12/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=7e75748bcb8b25bebeb1b5aeb2afc2fc1c48f38ccff9c624cd002a8e051424b7
dist/2025-05-12/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=9c05c902b0db8fd8f8b44d83a95bc8722bb714d333d2a61a2e1ef140092b6d83
dist/2025-05-12/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=d614cb69e1484f3653bc148280e7518640ec830ab8f02ddf512206ac265d6746
dist/2025-05-12/rustc-nightly-aarch64-apple-darwin.tar.gz=ac2c35cd19b85e6356bcdb987031314afbb7e41f26418ddb0d943fc3482245c6
dist/2025-05-12/rustc-nightly-aarch64-apple-darwin.tar.xz=a3c53f15d7b6f7c7e5f1e55c107663ef102cdb123394bcbe8a8c9c32a7e715f5
dist/2025-05-12/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=29e3bae16967111ce72d00b931d32410ab526617bf1c88bbf90e4d32825ea7dd
dist/2025-05-12/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=116103ab4251b366644239f8ef8d7129ae3d9588d768b8e66671497b1fa36c95
dist/2025-05-12/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=911acda80c362dd7690e5a4596e166b8ea49425f6dbbfd78ef697e69dc826c85
dist/2025-05-12/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=9cabea351ef05117d8cdfae0df334c98b12a99c4191d3e4f382c336c326520dc
dist/2025-05-12/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=81c9ed04939e8d363e060ef2808bee8dbd63435b111f37325bc8fd2891726560
dist/2025-05-12/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=a44b2f887aeafd5ff57ff67d8c4eeaa94cb4edd2f7d5912618ee186a4d609c73
dist/2025-05-12/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=7a4047a85297d3012c00377241f3daa50b34ddc54d68d67787d76eb45f5db616
dist/2025-05-12/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=09acd09fbfa3c43738c43c8c423d3fce6dc4451ca4ee8650ab3392279cfc288a
dist/2025-05-12/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=88ffa28a612cfb661a731dd4feeb6d6fae88d7236469ded88ee74a06a1576a8f
dist/2025-05-12/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=7c5747fb16062a786ffba5d00e1bc0e3c81ccf6154f09e21a6aa5b87c2fc9594
dist/2025-05-12/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=c1bd5074d4664f0ac8019151aea13e051cf2d89b8bd8fa77b9ed3831a1b7c217
dist/2025-05-12/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=20fa9e5531e4be0e54af97c8d033722c68d54ef984be3619ad84be6b579d0c73
dist/2025-05-12/rustc-nightly-i686-pc-windows-gnu.tar.gz=fe7511b5bf7830efeec083d3414e389286ec117b53db0501d5c314eba24e3bdd
dist/2025-05-12/rustc-nightly-i686-pc-windows-gnu.tar.xz=95677d845a5c7677b951300f17d810301397df022145f16674a58ebb1cd52a56
dist/2025-05-12/rustc-nightly-i686-pc-windows-msvc.tar.gz=a8f1e4852ffab09aeab1ccc09fff930444871fd3b490e68a1f9ae504c0dce6ed
dist/2025-05-12/rustc-nightly-i686-pc-windows-msvc.tar.xz=11fd3093a95e379d6472f063bfdccf6f3cf6c44956d68d121adcd1c927812eba
dist/2025-05-12/rustc-nightly-i686-unknown-linux-gnu.tar.gz=d95876f9a84ebcc97033c81dd07fe8852f0f472db94c074f5029458fec512d2e
dist/2025-05-12/rustc-nightly-i686-unknown-linux-gnu.tar.xz=766182f4d375138f4871abba6a8b50c3ca342edb7842b6d4bf7162e466cb32fe
dist/2025-05-12/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=58e41cb37fb5b974a78e7891c7aca2786bdf8153ac9cd134b713fc73771017b3
dist/2025-05-12/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=ec6990871579f86c0587a6f7262bb53dd7de3a79a39ca55b994475ad96f20f4f
dist/2025-05-12/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=39b7b026e95bdee7eba78804d2f8f3703a141ff37c24ac636deb755fc669f081
dist/2025-05-12/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=0b066061a1a55836b3b81667c0c35d864055578370f00365db7226fc41f0f11c
dist/2025-05-12/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=040b0718e4f460bb6136628ce24dca390608671b609d8e222e4ccbfedff43d6e
dist/2025-05-12/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=f9206ff2fad2acaab1b3a30e1d7a634384533329f71ceed5ef2fce0bd288bd43
dist/2025-05-12/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=9c6c12d9d5486c4d26d1f7d9a61625a20e3e7703af79195ec4cb7e7e22358f4e
dist/2025-05-12/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=2cace3cec2973aa8f93f1d5bbe8cdcb36134fc2313b0131c51d2d4885bb18492
dist/2025-05-12/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=60adf24efc4a8207709ccb39bf45ff5fb08c4a853de816c239a2aec795c22e46
dist/2025-05-12/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=038e9220451a497885e7886a293986b37b83979a4a6f70b112d42245f9e4a924
dist/2025-05-12/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=66d700e4a734f1a1a4f2c5d9125fee2c20e400b85a4a72ec4d6963f7d438a591
dist/2025-05-12/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=1198a73d12b6f556a5016a2181e1c95adf929f24df1be5a17b1ff8cf6635656f
dist/2025-05-12/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=e1b12d459eeed0496a93db5ca6962bd15bd307a400e8bb870623d20479d75aa0
dist/2025-05-12/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=2339af50b563056c4ad58cff24b1d59198e71e06c85f1860461e9384a0aeac0a
dist/2025-05-12/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=4977999e15a893215a7f86ad55e195249f63c416b7a0bee3423950575a952d1e
dist/2025-05-12/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=5745e2dd22c39abd35b19117b5514ba383058c057265b3003cda3da4aadfa18b
dist/2025-05-12/rustc-nightly-x86_64-apple-darwin.tar.gz=008b5b604e3fb66026eca67f29ed65262f85a2e305286a5ad11642edc8eaee2a
dist/2025-05-12/rustc-nightly-x86_64-apple-darwin.tar.xz=b2c071998e209e6b4989eae799938268dee9d8ada531956d41147e747128f328
dist/2025-05-12/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=8791712c5513a077d2936dd26c7157b12fd8b4bfc93180f97273eb534461837f
dist/2025-05-12/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=02fd232fa95660aa19665089a191fe350d0dfc44fcee4436be28fad82324fd00
dist/2025-05-12/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=9f7d67cadca7abf25c5445a9f7c911a3e0a2db2e52c088cc6833e40b52bef0de
dist/2025-05-12/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=ef2853ac4f2a5c6932f16768fb1df277b9edb8d91615869b8cfa574d6bda026a
dist/2025-05-12/rustc-nightly-x86_64-unknown-freebsd.tar.gz=117efae53fc69e481498c1f268bbb12e382f479dc6859ad04fdfc4a84659d677
dist/2025-05-12/rustc-nightly-x86_64-unknown-freebsd.tar.xz=14b67230c06ed6ec7597e31c6b7385782ab6a1f6bc723c5d2f171defa02c669d
dist/2025-05-12/rustc-nightly-x86_64-unknown-illumos.tar.gz=881a6c5ff0222eaca1fa278fb517963b30f51714c3724956bb2d29c142af0add
dist/2025-05-12/rustc-nightly-x86_64-unknown-illumos.tar.xz=3e708bcafdf8da1ceb92ad0e27407ea210144d91e30ba2486bd6758085153caf
dist/2025-05-12/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=b264a719d90f6842e3cbc8dc7d74ec356328f0a94cca279795ada5f4b22c54ed
dist/2025-05-12/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=fbe22ac8c9995feac7b13f92b8d4c16fc1cdfb4a15c06e127420762db0198443
dist/2025-05-12/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=48cf6d33fdba4e38dcc19710efd24eb863fe13bbca634e0ca02fc1647255bd6a
dist/2025-05-12/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=7767dd1b6baf7065dfc74b4e9ce4c200616294ecd664243c6fe756522fb4a328
dist/2025-05-12/rustc-nightly-x86_64-unknown-netbsd.tar.gz=bde7b39870fbce418257278ae56159af3f80f1688efd01d6d52b16127fd0b64a
dist/2025-05-12/rustc-nightly-x86_64-unknown-netbsd.tar.xz=6018c06dda8f5a0ff5ef7754bf2e8692b2dfd48be525d896261aea27d682f4e5

@ -1 +1 @@
Subproject commit 056f5f4f3c100cb36b5e9aed2d20b9ea70aae295
Subproject commit 47c911e9e6f6461f90ce19142031fe16876a3b95

View file

@ -15,27 +15,18 @@ jobs:
changelog:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
# Run
- name: Check Changelog
if: ${{ github.event_name == 'pull_request' }}
run: |
body=$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -s "https://api.github.com/repos/${{ github.repository }}/pulls/$PR_NUMBER" | \
python -c "import sys, json; print(json.load(sys.stdin)['body'])")
output=$(awk '/^changelog:\s*\S/ && !/changelog: \[.*\]: your change/' <<< "$body" | sed "s/changelog:\s*//g")
if [ -z "$output" ]; then
echo "ERROR: pull request message must contain 'changelog: ...' with your changelog. Please add it."
if [[ -z $(grep -oP 'changelog: *\K\S+' <<< "$PR_BODY") ]]; then
echo "::error::Pull request message must contain 'changelog: ...' with your changelog. Please add it."
exit 1
else
echo "changelog: $output"
fi
env:
PYTHONIOENCODING: 'utf-8'
PR_NUMBER: '${{ github.event.number }}'
PR_BODY: ${{ github.event.pull_request.body }})
# We need to have the "conclusion" job also on PR CI, to make it possible
# to add PRs to a merge queue.

View file

@ -6,7 +6,105 @@ document.
## Unreleased / Beta / In Rust Nightly
[3e3715c3...master](https://github.com/rust-lang/rust-clippy/compare/3e3715c3...master)
[1e5237f4...master](https://github.com/rust-lang/rust-clippy/compare/1e5237f4...master)
## Rust 1.87
Current stable, released 2025-05-15
[View all 127 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-02-06T14%3A54%3A28Z..2025-03-20T20%3A07%3A53Z+base%3Amaster)
### New Lints
* Added [`doc_comment_double_space_linebreaks`] to `pedantic` [#12876](https://github.com/rust-lang/rust-clippy/pull/12876)
* Added [`manual_midpoint`] to `pedantic` [#13851](https://github.com/rust-lang/rust-clippy/pull/13851)
* Added [`io_other_error`] to `style` [#14022](https://github.com/rust-lang/rust-clippy/pull/14022)
* Added [`owned_cow`] to `pedantic` [#13948](https://github.com/rust-lang/rust-clippy/pull/13948)
* Added [`manual_contains`] to `perf` [#13817](https://github.com/rust-lang/rust-clippy/pull/13817)
* Added [`unnecessary_debug_formatting`] to `pedantic` [#13893](https://github.com/rust-lang/rust-clippy/pull/13893)
* Added [`elidable_lifetime_names`] to `pedantic` [#13960](https://github.com/rust-lang/rust-clippy/pull/13960)
* Added [`mem_replace_option_with_some`] to `style` [#14197](https://github.com/rust-lang/rust-clippy/pull/14197)
* Added [`unbuffered_bytes`] to `perf` [#14089](https://github.com/rust-lang/rust-clippy/pull/14089)
* Added [`single_option_map`] to `nursery` [#14033](https://github.com/rust-lang/rust-clippy/pull/14033)
### Moves and Deprecations
* Moved [`comparison_chain`] to `pedantic` (from `style`)
[#14219](https://github.com/rust-lang/rust-clippy/pull/14219)
* Moved [`manual_ok_or`] to `style` (from `pedantic`)
[#14027](https://github.com/rust-lang/rust-clippy/pull/14027)
* Deprecated [`option_map_or_err_ok`] in favor of [`manual_ok_or`]
[#14027](https://github.com/rust-lang/rust-clippy/pull/14027)
### Enhancements
* Add `allow_expect_in_consts` and `allow_unwrap_in_consts` configuration options to [`unwrap_used`], [`expect_used`]
[#14200](https://github.com/rust-lang/rust-clippy/pull/14200)
* Add `check-incompatible-msrv-in-tests` configuration option to [`incompatible_msrv`]
[#14279](https://github.com/rust-lang/rust-clippy/pull/14279)
* [`len_zero`] now also triggers if deref target implements `is_empty()`
[#13871](https://github.com/rust-lang/rust-clippy/pull/13871)
* [`ptr_eq`] now handles more cases, including `!=` in addition to `==`
[#14339](https://github.com/rust-lang/rust-clippy/pull/14339)
* [`struct_field_names`] now also checks private fields of public structs
[#14076](https://github.com/rust-lang/rust-clippy/pull/14076)
* [`needless_pass_by_value`] suggests using a reference on the innermost `Option` content
[#14392](https://github.com/rust-lang/rust-clippy/pull/14392)
* [`obfuscated_if_else`] now supports `then().unwrap_or_else()` and `then_some().unwrap_or_else()`
[#14165](https://github.com/rust-lang/rust-clippy/pull/14165)
* Format macros: all format-handling lints now validate `todo!` and `unimplemented!` macros
[#14266](https://github.com/rust-lang/rust-clippy/pull/14266)
* [`disallowed_methods`] now supports replacements
[#13669](https://github.com/rust-lang/rust-clippy/pull/13669)
* Added MSRV checks for several lints:
* [`question_mark`] [#14436](https://github.com/rust-lang/rust-clippy/pull/14436)
* [`repeat_vec_with_capacity`] [#14126](https://github.com/rust-lang/rust-clippy/pull/14126)
* [`manual_flatten`] [#14086](https://github.com/rust-lang/rust-clippy/pull/14086)
* [`lines_filter_map_ok`] [#14130](https://github.com/rust-lang/rust-clippy/pull/14130)
### False Positive Fixes
* [`missing_const_for_fn`] no longer triggers on unstable const traits [#14294](https://github.com/rust-lang/rust-clippy/pull/14294)
* [`unnecessary_to_owned`] now avoids suggesting to call `iter()` on a temporary object [#14243](https://github.com/rust-lang/rust-clippy/pull/14243)
* [`unnecessary_debug_formatting`] no longer triggers in tests [#14347](https://github.com/rust-lang/rust-clippy/pull/14347)
* [`option_if_let_else`] now handles cases when value is partially moved [#14209](https://github.com/rust-lang/rust-clippy/pull/14209)
* [`blocks_in_conditions`] no longer triggers when the condition contains a `return` [#14338](https://github.com/rust-lang/rust-clippy/pull/14338)
* [`undocumented_unsafe_blocks`] no longer triggers on trait/impl items [#13888](https://github.com/rust-lang/rust-clippy/pull/13888)
* [`manual_slice_fill`] no longer triggers due to missing index checks [#14193](https://github.com/rust-lang/rust-clippy/pull/14193)
* [`useless_asref`] no longer suggests using `.clone()` if the target type doesn't implement `Clone` [#14174](https://github.com/rust-lang/rust-clippy/pull/14174)
* [`unnecessary_safety_comment`] no longer triggers on desugared assign [#14371](https://github.com/rust-lang/rust-clippy/pull/14371)
* [`unnecessary_map_or`] no longer consumes the comparison value if it does not implement `Copy` [#14207](https://github.com/rust-lang/rust-clippy/pull/14207)
* [`let_and_return`] no longer triggers involving short-lived block temporary variables [#14180](https://github.com/rust-lang/rust-clippy/pull/14180)
* [`manual_async_fn`] no longer emits suggestions inside macros [#14142](https://github.com/rust-lang/rust-clippy/pull/14142)
* [`use_self`] skips analysis inside macro expansions of a `impl Self` block [#13128](https://github.com/rust-lang/rust-clippy/pull/13128)
* [`double_ended_iterator_last`] no longer triggers on non-reference immutable receiver [#14140](https://github.com/rust-lang/rust-clippy/pull/14140)
### ICE Fixes
* [`macro_use_imports`] Fix ICE when checking attributes
[#14317](https://github.com/rust-lang/rust-clippy/pull/14317)
* [`doc_nested_refdefs`] Fix ICE by avoiding invalid ranges
[#14308](https://github.com/rust-lang/rust-clippy/pull/14308)
* [`just_underscores_and_digits`] Fix ICE in error recovery scenario
[#14168](https://github.com/rust-lang/rust-clippy/pull/14168)
* [`declare_interior_mutable_const`], [`borrow_interior_mutable_const`] Fix ICE by properly resolving `<T as Trait>::AssocT` projections
[#14125](https://github.com/rust-lang/rust-clippy/pull/14125)
### Documentation Improvements
* [`struct_excessive_bools`] Documentation improved with rationale
[#14351](https://github.com/rust-lang/rust-clippy/pull/14351)
### Others
* Use edition=2021 in `rustc_tools_util`
[#14211](https://github.com/rust-lang/rust-clippy/pull/14211)
* Fix rustc_tools_util's `version.host_compiler` release channel, expose the rustc version, and add tests
[#14123](https://github.com/rust-lang/rust-clippy/pull/14123)
* Make UI test annotations mandatory
[#11421](https://github.com/rust-lang/rust-clippy/pull/11421)
[#14388](https://github.com/rust-lang/rust-clippy/pull/14388)
[#14393](https://github.com/rust-lang/rust-clippy/pull/14393)
## Rust 1.86
@ -5583,6 +5681,7 @@ Released 2018-09-13
[`clone_on_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy
[`clone_on_ref_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_ref_ptr
[`cloned_instead_of_copied`]: https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied
[`cloned_ref_to_slice_refs`]: https://rust-lang.github.io/rust-clippy/master/index.html#cloned_ref_to_slice_refs
[`cmp_nan`]: https://rust-lang.github.io/rust-clippy/master/index.html#cmp_nan
[`cmp_null`]: https://rust-lang.github.io/rust-clippy/master/index.html#cmp_null
[`cmp_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#cmp_owned
@ -5594,6 +5693,7 @@ Released 2018-09-13
[`collection_is_never_read`]: https://rust-lang.github.io/rust-clippy/master/index.html#collection_is_never_read
[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
[`comparison_to_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_to_empty
[`confusing_method_to_numeric_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#confusing_method_to_numeric_cast
[`const_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#const_is_empty
[`const_static_lifetime`]: https://rust-lang.github.io/rust-clippy/master/index.html#const_static_lifetime
[`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator
@ -6383,6 +6483,7 @@ Released 2018-09-13
[`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement
[`allow-comparison-to-zero`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-comparison-to-zero
[`allow-dbg-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-dbg-in-tests
[`allow-exact-repetitions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-exact-repetitions
[`allow-expect-in-consts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-consts
[`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests
[`allow-indexing-slicing-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-indexing-slicing-in-tests
@ -6435,6 +6536,7 @@ Released 2018-09-13
[`max-suggested-slice-pattern-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-suggested-slice-pattern-length
[`max-trait-bounds`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-trait-bounds
[`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold
[`missing-docs-allow-unused`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-allow-unused
[`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items
[`module-item-order-groupings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#module-item-order-groupings
[`module-items-ordered-within-groupings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#module-items-ordered-within-groupings

View file

@ -77,7 +77,7 @@ debugging to find the actual problem behind the issue.
[`T-middle`] issues can be more involved and require verifying types. The [`ty`] module contains a
lot of methods that are useful, though one of the most useful would be `expr_ty` (gives the type of
an AST expression). `match_def_path()` in Clippy's `utils` module can also be useful.
an AST expression).
[`good-first-issue`]: https://github.com/rust-lang/rust-clippy/labels/good-first-issue
[`S-inactive-closed`]: https://github.com/rust-lang/rust-clippy/pulls?q=is%3Aclosed+label%3AS-inactive-closed

View file

@ -1,7 +1,7 @@
[package]
name = "clippy"
# begin autogenerated version
version = "0.1.88"
version = "0.1.89"
# end autogenerated version
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
@ -28,7 +28,7 @@ clippy_lints = { path = "clippy_lints" }
clippy_utils = { path = "clippy_utils" }
rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
clippy_lints_internal = { path = "clippy_lints_internal", optional = true }
tempfile = { version = "3.3", optional = true }
tempfile = { version = "3.20", optional = true }
termize = "0.1"
color-print = "0.3.4"
anstream = "0.6.18"
@ -47,7 +47,6 @@ pulldown-cmark = { version = "0.11", default-features = false, features = ["html
askama = { version = "0.13", default-features = false, features = ["alloc", "config", "derive"] }
# UI test dependencies
clippy_utils = { path = "clippy_utils" }
if_chain = "1.0"
quote = "1.0.25"
syn = { version = "2.0", features = ["full"] }

View file

@ -416,7 +416,7 @@ In our example, `is_foo_fn` looks like:
fn is_foo_fn(fn_kind: FnKind<'_>) -> bool {
match fn_kind {
FnKind::Fn(_, ident, ..) => {
FnKind::Fn(_, _, Fn { ident, .. }) => {
// check if `fn` name is `foo`
ident.name.as_str() == "foo"
}

View file

@ -145,42 +145,32 @@ unclear to you.
If you are hacking on Clippy and want to install it from source, do the
following:
First, take note of the toolchain
[override](https://rust-lang.github.io/rustup/overrides.html) in
`/rust-toolchain.toml`. We will use this override to install Clippy into the right
toolchain.
> Tip: You can view the active toolchain for the current directory with `rustup
> show active-toolchain`.
From the Clippy project root, run the following command to build the Clippy
binaries and copy them into the toolchain directory. This will override the
currently installed Clippy component.
binaries and copy them into the toolchain directory. This will create a new
toolchain called `clippy` by default, see `cargo dev setup toolchain --help`
for other options.
```terminal
cargo build --release --bin cargo-clippy --bin clippy-driver -Zunstable-options --out-dir "$(rustc --print=sysroot)/bin"
cargo dev setup toolcahin
```
Now you may run `cargo clippy` in any project, using the toolchain where you
just installed Clippy.
Now you may run `cargo +clippy clippy` in any project using the new toolchain.
```terminal
cd my-project
cargo +nightly-2021-07-01 clippy
cargo +clippy clippy
```
...or `clippy-driver`
```terminal
clippy-driver +nightly-2021-07-01 <filename>
clippy-driver +clippy <filename>
```
If you need to restore the default Clippy installation, run the following (from
the Clippy project root).
If you no longer need the toolchain it can be uninstalled using `rustup`:
```terminal
rustup component remove clippy
rustup component add clippy
rustup toolchain uninstall clippy
```
> **DO NOT** install using `cargo install --path . --force` since this will

View file

@ -86,7 +86,7 @@ arguments have to be checked separately.
```rust
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use clippy_utils::{paths, match_def_path};
use clippy_utils::paths;
use rustc_span::symbol::sym;
use rustc_hir::LangItem;
@ -108,7 +108,7 @@ impl LateLintPass<'_> for MyStructLint {
// 3. Using the type path
// This method should be avoided if possible
if match_def_path(cx, def_id, &paths::RESULT) {
if paths::RESULT.matches_ty(cx, ty) {
// The type is a `core::result::Result`
}
}

View file

@ -51,7 +51,9 @@ Once you've got the correct commit range, run
util/fetch_prs_between.sh commit1 commit2 > changes.txt
```
and open that file in your editor of choice.
where `commit2` is the commit hash from the previous command and `commit1`
is the commit hash from the current CHANGELOG file.
Open `changes.txt` file in your editor of choice.
When updating the changelog it's also a good idea to make sure that `commit1` is
already correct in the current changelog.
@ -60,8 +62,8 @@ already correct in the current changelog.
The above script should have dumped all the relevant PRs to the file you
specified. It should have filtered out most of the irrelevant PRs already, but
it's a good idea to do a manual cleanup pass where you look for more irrelevant
PRs. If you're not sure about some PRs, just leave them in for the review and
it's a good idea to do a manual cleanup pass and choose valuable PRs.
If you're not sure about some PRs, just leave them in for the review and
ask for feedback.
With the PRs filtered, you can start to take each PR and move the `changelog: `
@ -74,10 +76,9 @@ The order should roughly be:
2. Moves or deprecations of lints
3. Changes that expand what code existing lints cover
4. False positive fixes
5. Suggestion fixes/improvements
6. ICE fixes
7. Documentation improvements
8. Others
5. ICE fixes
6. Documentation improvements
7. Others
As section headers, we use:
@ -91,7 +92,6 @@ As section headers, we use:
### Enhancements
### False Positive Fixes
### Suggestion Fixes/Improvements
### ICE Fixes
### Documentation Improvements
### Others
@ -112,7 +112,16 @@ that label in the changelog. If you can, remove the `beta-accepted` labels
### 4. Update `clippy::version` attributes
Next, make sure to check that the `#[clippy::version]` attributes for the added
lints contain the correct version.
lints contain the correct version.
In order to find lints that need a version update, go through the lints in the
"New Lints" section and run the following command for each lint name:
```
grep -rB1 "pub $LINT_NAME" .
```
The version shown should match the version of the release the changelog is
written for. If not, update the version to the changelog version.
[changelog]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md
[forge]: https://forge.rust-lang.org/

View file

@ -73,22 +73,24 @@ impl LateLintPass<'_> for CheckDropTraitLint {
## Using Type Path
If neither diagnostic item nor a language item is available, we can use
[`clippy_utils::paths`][paths] with the `match_trait_method` to determine trait
implementation.
[`clippy_utils::paths`][paths] to determine get a trait's `DefId`.
> **Note**: This approach should be avoided if possible, the best thing to do would be to make a PR to [`rust-lang/rust`][rust] adding a diagnostic item.
Below, we check if the given `expr` implements the `Iterator`'s trait method `cloned` :
Below, we check if the given `expr` implements [`core::iter::Step`](https://doc.rust-lang.org/std/iter/trait.Step.html):
```rust
use clippy_utils::{match_trait_method, paths};
use clippy_utils::{implements_trait, paths};
use rustc_hir::Expr;
use rustc_lint::{LateContext, LateLintPass};
impl LateLintPass<'_> for CheckTokioAsyncReadExtTrait {
impl LateLintPass<'_> for CheckIterStep {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
if match_trait_method(cx, expr, &paths::CORE_ITER_CLONED) {
println!("`expr` implements `CORE_ITER_CLONED` trait!");
let ty = cx.typeck_results().expr_ty(expr);
if let Some(trait_def_id) = paths::ITER_STEP.first(cx)
&& implements_trait(cx, ty, trait_def_id, &[])
{
println!("`expr` implements the `core::iter::Step` trait!");
}
}
}

View file

@ -71,6 +71,16 @@ Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`
* [`dbg_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro)
## `allow-exact-repetitions`
Whether an item should be allowed to have the same name as its containing module
**Default Value:** `true`
---
**Affected lints:**
* [`module_name_repetitions`](https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions)
## `allow-expect-in-consts`
Whether `expect` should be allowed in code always evaluated at compile time
@ -734,6 +744,16 @@ Minimum chars an ident can have, anything below or equal to this will be linted.
* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)
## `missing-docs-allow-unused`
Whether to allow fields starting with an underscore to skip documentation requirements
**Default Value:** `false`
---
**Affected lints:**
* [`missing_docs_in_private_items`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items)
## `missing-docs-in-crate-items`
Whether to **only** check for missing documentation in items visible within the current
crate. For example, `pub(crate)` items.
@ -839,6 +859,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
* [`same_item_push`](https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push)
* [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current)
* [`seek_rewind`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind)
* [`to_digit_is_some`](https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some)
* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref)
* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions)
* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)

View file

@ -7,14 +7,11 @@ lint-commented-code = true
[[disallowed-methods]]
path = "rustc_lint::context::LintContext::lint"
reason = "this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint*` functions instead"
allow-invalid = true
[[disallowed-methods]]
path = "rustc_lint::context::LintContext::span_lint"
reason = "this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint*` functions instead"
allow-invalid = true
[[disallowed-methods]]
path = "rustc_middle::ty::context::TyCtxt::node_span_lint"
reason = "this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead"
allow-invalid = true

View file

@ -1,7 +1,7 @@
[package]
name = "clippy_config"
# begin autogenerated version
version = "0.1.88"
version = "0.1.89"
# end autogenerated version
edition = "2024"
publish = false

View file

@ -360,6 +360,9 @@ define_Conf! {
/// Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`
#[lints(dbg_macro)]
allow_dbg_in_tests: bool = false,
/// Whether an item should be allowed to have the same name as its containing module
#[lints(module_name_repetitions)]
allow_exact_repetitions: bool = true,
/// Whether `expect` should be allowed in code always evaluated at compile time
#[lints(expect_used)]
allow_expect_in_consts: bool = true,
@ -675,6 +678,9 @@ define_Conf! {
/// Minimum chars an ident can have, anything below or equal to this will be linted.
#[lints(min_ident_chars)]
min_ident_chars_threshold: u64 = 1,
/// Whether to allow fields starting with an underscore to skip documentation requirements
#[lints(missing_docs_in_private_items)]
missing_docs_allow_unused: bool = false,
/// Whether to **only** check for missing documentation in items visible within the current
/// crate. For example, `pub(crate)` items.
#[lints(missing_docs_in_private_items)]
@ -756,6 +762,7 @@ define_Conf! {
same_item_push,
seek_from_current,
seek_rewind,
to_digit_is_some,
transmute_ptr_to_ref,
tuple_array_conversions,
type_repetition_in_bounds,

View file

@ -1,4 +1,4 @@
#![feature(rustc_private, array_windows, let_chains)]
#![feature(rustc_private)]
#![warn(
trivial_casts,
trivial_numeric_casts,
@ -12,6 +12,7 @@
rustc::diagnostic_outside_of_impl,
rustc::untranslatable_diagnostic
)]
#![deny(clippy::derive_deserialize_allowing_unknown)]
extern crate rustc_data_structures;
extern crate rustc_errors;

View file

@ -1,16 +1,18 @@
use clippy_utils::paths::{PathNS, find_crates, lookup_path};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, Diag};
use rustc_hir::PrimTy;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefIdMap;
use rustc_middle::ty::TyCtxt;
use rustc_span::Span;
use rustc_span::{Span, Symbol};
use serde::de::{self, Deserializer, Visitor};
use serde::{Deserialize, Serialize, ser};
use std::collections::HashMap;
use std::fmt;
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Rename {
pub path: String,
pub rename: String,
@ -58,7 +60,7 @@ impl<'de, const REPLACEMENT_ALLOWED: bool> Deserialize<'de> for DisallowedPath<R
// `DisallowedPathEnum` is an implementation detail to enable the `Deserialize` implementation just
// above. `DisallowedPathEnum` is not meant to be used outside of this file.
#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
#[serde(untagged, deny_unknown_fields)]
enum DisallowedPathEnum {
Simple(String),
WithReason {
@ -133,6 +135,7 @@ impl DisallowedPathEnum {
pub fn create_disallowed_map<const REPLACEMENT_ALLOWED: bool>(
tcx: TyCtxt<'_>,
disallowed_paths: &'static [DisallowedPath<REPLACEMENT_ALLOWED>],
ns: PathNS,
def_kind_predicate: impl Fn(DefKind) -> bool,
predicate_description: &str,
allow_prim_tys: bool,
@ -145,57 +148,47 @@ pub fn create_disallowed_map<const REPLACEMENT_ALLOWED: bool>(
FxHashMap::default();
for disallowed_path in disallowed_paths {
let path = disallowed_path.path();
let mut resolutions = clippy_utils::def_path_res(tcx, &path.split("::").collect::<Vec<_>>());
let sym_path: Vec<Symbol> = path.split("::").map(Symbol::intern).collect();
let mut resolutions = lookup_path(tcx, ns, &sym_path);
resolutions.retain(|&def_id| def_kind_predicate(tcx.def_kind(def_id)));
let mut found_def_id = None;
let mut found_prim_ty = false;
resolutions.retain(|res| match res {
Res::Def(def_kind, def_id) => {
found_def_id = Some(*def_id);
def_kind_predicate(*def_kind)
},
Res::PrimTy(_) => {
found_prim_ty = true;
allow_prim_tys
},
_ => false,
});
let (prim_ty, found_prim_ty) = if let &[name] = sym_path.as_slice()
&& let Some(prim) = PrimTy::from_name(name)
{
(allow_prim_tys.then_some(prim), true)
} else {
(None, false)
};
if resolutions.is_empty() {
let span = disallowed_path.span();
if let Some(def_id) = found_def_id {
tcx.sess.dcx().span_warn(
span,
format!(
"expected a {predicate_description}, found {} {}",
tcx.def_descr_article(def_id),
tcx.def_descr(def_id)
),
);
if resolutions.is_empty()
&& prim_ty.is_none()
&& !disallowed_path.allow_invalid
// Don't warn about unloaded crates:
// https://github.com/rust-lang/rust-clippy/pull/14397#issuecomment-2848328221
&& (sym_path.len() < 2 || !find_crates(tcx, sym_path[0]).is_empty())
{
// Relookup the path in an arbitrary namespace to get a good `expected, found` message
let found_def_ids = lookup_path(tcx, PathNS::Arbitrary, &sym_path);
let message = if let Some(&def_id) = found_def_ids.first() {
let (article, description) = tcx.article_and_description(def_id);
format!("expected a {predicate_description}, found {article} {description}")
} else if found_prim_ty {
tcx.sess.dcx().span_warn(
span,
format!("expected a {predicate_description}, found a primitive type",),
);
} else if !disallowed_path.allow_invalid {
tcx.sess.dcx().span_warn(
span,
format!("`{path}` does not refer to an existing {predicate_description}"),
);
}
format!("expected a {predicate_description}, found a primitive type")
} else {
format!("`{path}` does not refer to a reachable {predicate_description}")
};
tcx.sess
.dcx()
.struct_span_warn(disallowed_path.span(), message)
.with_help("add `allow-invalid = true` to the entry to suppress this warning")
.emit();
}
for res in resolutions {
match res {
Res::Def(_, def_id) => {
def_ids.insert(def_id, (path, disallowed_path));
},
Res::PrimTy(ty) => {
prim_tys.insert(ty, (path, disallowed_path));
},
_ => unreachable!(),
}
for def_id in resolutions {
def_ids.insert(def_id, (path, disallowed_path));
}
if let Some(ty) = prim_ty {
prim_tys.insert(ty, (path, disallowed_path));
}
}

View file

@ -0,0 +1,174 @@
use crate::update_lints::{
DeprecatedLint, DeprecatedLints, Lint, find_lint_decls, generate_lint_files, read_deprecated_lints,
};
use crate::utils::{UpdateMode, Version};
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::{fs, io};
/// Runs the `deprecate` command
///
/// This does the following:
/// * Adds an entry to `deprecated_lints.rs`.
/// * Removes the lint declaration (and the entire file if applicable)
///
/// # Panics
///
/// If a file path could not read from or written to
pub fn deprecate(clippy_version: Version, name: &str, reason: &str) {
let prefixed_name = if name.starts_with("clippy::") {
name.to_owned()
} else {
format!("clippy::{name}")
};
let stripped_name = &prefixed_name[8..];
let mut lints = find_lint_decls();
let DeprecatedLints {
renamed: renamed_lints,
deprecated: mut deprecated_lints,
file: mut deprecated_file,
contents: mut deprecated_contents,
deprecated_end,
..
} = read_deprecated_lints();
let Some(lint) = lints.iter().find(|l| l.name == stripped_name) else {
eprintln!("error: failed to find lint `{name}`");
return;
};
let mod_path = {
let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));
if mod_path.is_dir() {
mod_path = mod_path.join("mod");
}
mod_path.set_extension("rs");
mod_path
};
if remove_lint_declaration(stripped_name, &mod_path, &mut lints).unwrap_or(false) {
deprecated_contents.insert_str(
deprecated_end as usize,
&format!(
" #[clippy::version = \"{}\"]\n (\"{}\", \"{}\"),\n",
clippy_version.rust_display(),
prefixed_name,
reason,
),
);
deprecated_file.replace_contents(deprecated_contents.as_bytes());
drop(deprecated_file);
deprecated_lints.push(DeprecatedLint {
name: prefixed_name,
reason: reason.into(),
});
generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
println!("info: `{name}` has successfully been deprecated");
println!("note: you must run `cargo uitest` to update the test results");
} else {
eprintln!("error: lint not found");
}
}
fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec<Lint>) -> io::Result<bool> {
fn remove_lint(name: &str, lints: &mut Vec<Lint>) {
lints.iter().position(|l| l.name == name).map(|pos| lints.remove(pos));
}
fn remove_test_assets(name: &str) {
let test_file_stem = format!("tests/ui/{name}");
let path = Path::new(&test_file_stem);
// Some lints have their own directories, delete them
if path.is_dir() {
let _ = fs::remove_dir_all(path);
return;
}
// Remove all related test files
let _ = fs::remove_file(path.with_extension("rs"));
let _ = fs::remove_file(path.with_extension("stderr"));
let _ = fs::remove_file(path.with_extension("fixed"));
}
fn remove_impl_lint_pass(lint_name_upper: &str, content: &mut String) {
let impl_lint_pass_start = content.find("impl_lint_pass!").unwrap_or_else(|| {
content
.find("declare_lint_pass!")
.unwrap_or_else(|| panic!("failed to find `impl_lint_pass`"))
});
let mut impl_lint_pass_end = content[impl_lint_pass_start..]
.find(']')
.expect("failed to find `impl_lint_pass` terminator");
impl_lint_pass_end += impl_lint_pass_start;
if let Some(lint_name_pos) = content[impl_lint_pass_start..impl_lint_pass_end].find(lint_name_upper) {
let mut lint_name_end = impl_lint_pass_start + (lint_name_pos + lint_name_upper.len());
for c in content[lint_name_end..impl_lint_pass_end].chars() {
// Remove trailing whitespace
if c == ',' || c.is_whitespace() {
lint_name_end += 1;
} else {
break;
}
}
content.replace_range(impl_lint_pass_start + lint_name_pos..lint_name_end, "");
}
}
if path.exists()
&& let Some(lint) = lints.iter().find(|l| l.name == name)
{
if lint.module == name {
// The lint name is the same as the file, we can just delete the entire file
fs::remove_file(path)?;
} else {
// We can't delete the entire file, just remove the declaration
if let Some(Some("mod.rs")) = path.file_name().map(OsStr::to_str) {
// Remove clippy_lints/src/some_mod/some_lint.rs
let mut lint_mod_path = path.to_path_buf();
lint_mod_path.set_file_name(name);
lint_mod_path.set_extension("rs");
let _ = fs::remove_file(lint_mod_path);
}
let mut content =
fs::read_to_string(path).unwrap_or_else(|_| panic!("failed to read `{}`", path.to_string_lossy()));
eprintln!(
"warn: you will have to manually remove any code related to `{name}` from `{}`",
path.display()
);
assert!(
content[lint.declaration_range.clone()].contains(&name.to_uppercase()),
"error: `{}` does not contain lint `{}`'s declaration",
path.display(),
lint.name
);
// Remove lint declaration (declare_clippy_lint!)
content.replace_range(lint.declaration_range.clone(), "");
// Remove the module declaration (mod xyz;)
let mod_decl = format!("\nmod {name};");
content = content.replacen(&mod_decl, "", 1);
remove_impl_lint_pass(&lint.name.to_uppercase(), &mut content);
fs::write(path, content).unwrap_or_else(|_| panic!("failed to write to `{}`", path.to_string_lossy()));
}
remove_test_assets(name);
remove_lint(name, lints);
return Ok(true);
}
Ok(false)
}

View file

@ -1,4 +1,4 @@
use crate::utils::{clippy_project_root, exit_if_err};
use crate::utils::exit_if_err;
use std::process::Command;
/// # Panics
@ -8,8 +8,7 @@ use std::process::Command;
pub fn dogfood(fix: bool, allow_dirty: bool, allow_staged: bool, allow_no_vcs: bool) {
let mut cmd = Command::new("cargo");
cmd.current_dir(clippy_project_root())
.args(["test", "--test", "dogfood"])
cmd.args(["test", "--test", "dogfood"])
.args(["--features", "internal"])
.args(["--", "dogfood_clippy", "--nocapture"]);

View file

@ -1,4 +1,3 @@
use crate::utils::clippy_project_root;
use itertools::Itertools;
use rustc_lexer::{TokenKind, tokenize};
use shell_escape::escape;
@ -104,15 +103,8 @@ fn fmt_conf(check: bool) -> Result<(), Error> {
Field,
}
let path: PathBuf = [
clippy_project_root().as_path(),
"clippy_config".as_ref(),
"src".as_ref(),
"conf.rs".as_ref(),
]
.into_iter()
.collect();
let text = fs::read_to_string(&path)?;
let path = "clippy_config/src/conf.rs";
let text = fs::read_to_string(path)?;
let (pre, conf) = text
.split_once("define_Conf! {\n")
@ -203,7 +195,7 @@ fn fmt_conf(check: bool) -> Result<(), Error> {
| (State::Lints, TokenKind::Comma | TokenKind::OpenParen | TokenKind::CloseParen) => {},
_ => {
return Err(Error::Parse(
path,
PathBuf::from(path),
offset_to_line(&text, conf_offset + i),
format!("unexpected token `{}`", &conf[i..i + t.len as usize]),
));
@ -213,7 +205,7 @@ fn fmt_conf(check: bool) -> Result<(), Error> {
if !matches!(state, State::Field) {
return Err(Error::Parse(
path,
PathBuf::from(path),
offset_to_line(&text, conf_offset + conf.len()),
"incomplete field".into(),
));
@ -260,18 +252,16 @@ fn fmt_conf(check: bool) -> Result<(), Error> {
if check {
return Err(Error::CheckFailed);
}
fs::write(&path, new_text.as_bytes())?;
fs::write(path, new_text.as_bytes())?;
}
Ok(())
}
fn run_rustfmt(context: &FmtContext) -> Result<(), Error> {
let project_root = clippy_project_root();
// if we added a local rustc repo as path dependency to clippy for rust analyzer, we do NOT want to
// format because rustfmt would also format the entire rustc repo as it is a local
// dependency
if fs::read_to_string(project_root.join("Cargo.toml"))
if fs::read_to_string("Cargo.toml")
.expect("Failed to read clippy Cargo.toml")
.contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]")
{
@ -280,12 +270,12 @@ fn run_rustfmt(context: &FmtContext) -> Result<(), Error> {
check_for_rustfmt(context)?;
cargo_fmt(context, project_root.as_path())?;
cargo_fmt(context, &project_root.join("clippy_dev"))?;
cargo_fmt(context, &project_root.join("rustc_tools_util"))?;
cargo_fmt(context, &project_root.join("lintcheck"))?;
cargo_fmt(context, ".".as_ref())?;
cargo_fmt(context, "clippy_dev".as_ref())?;
cargo_fmt(context, "rustc_tools_util".as_ref())?;
cargo_fmt(context, "lintcheck".as_ref())?;
let chunks = WalkDir::new(project_root.join("tests"))
let chunks = WalkDir::new("tests")
.into_iter()
.filter_map(|entry| {
let entry = entry.expect("failed to find tests");

View file

@ -1,5 +1,4 @@
#![feature(let_chains)]
#![feature(rustc_private)]
#![feature(rustc_private, if_let_guard, let_chains)]
#![warn(
trivial_casts,
trivial_numeric_casts,
@ -15,11 +14,13 @@ extern crate rustc_driver;
extern crate rustc_lexer;
extern crate rustc_literal_escaper;
pub mod deprecate_lint;
pub mod dogfood;
pub mod fmt;
pub mod lint;
pub mod new_lint;
pub mod release;
pub mod rename_lint;
pub mod serve;
pub mod setup;
pub mod sync;

View file

@ -3,11 +3,18 @@
#![warn(rust_2018_idioms, unused_lifetimes)]
use clap::{Args, Parser, Subcommand};
use clippy_dev::{dogfood, fmt, lint, new_lint, release, serve, setup, sync, update_lints, utils};
use clippy_dev::{
deprecate_lint, dogfood, fmt, lint, new_lint, release, rename_lint, serve, setup, sync, update_lints, utils,
};
use std::convert::Infallible;
use std::env;
fn main() {
let dev = Dev::parse();
let clippy = utils::ClippyInfo::search_for_manifest();
if let Err(e) = env::set_current_dir(&clippy.path) {
panic!("error setting current directory to `{}`: {e}", clippy.path.display());
}
match dev.command {
DevCommand::Bless => {
@ -20,22 +27,14 @@ fn main() {
allow_no_vcs,
} => dogfood::dogfood(fix, allow_dirty, allow_staged, allow_no_vcs),
DevCommand::Fmt { check, verbose } => fmt::run(check, verbose),
DevCommand::UpdateLints { print_only, check } => {
if print_only {
update_lints::print_lints();
} else if check {
update_lints::update(utils::UpdateMode::Check);
} else {
update_lints::update(utils::UpdateMode::Change);
}
},
DevCommand::UpdateLints { check } => update_lints::update(utils::UpdateMode::from_check(check)),
DevCommand::NewLint {
pass,
name,
category,
r#type,
msrv,
} => match new_lint::create(pass, &name, &category, r#type.as_deref(), msrv) {
} => match new_lint::create(clippy.version, pass, &name, &category, r#type.as_deref(), msrv) {
Ok(()) => update_lints::update(utils::UpdateMode::Change),
Err(e) => eprintln!("Unable to create lint: {e}"),
},
@ -79,13 +78,18 @@ fn main() {
old_name,
new_name,
uplift,
} => update_lints::rename(&old_name, new_name.as_ref().unwrap_or(&old_name), uplift),
DevCommand::Deprecate { name, reason } => update_lints::deprecate(&name, &reason),
} => rename_lint::rename(
clippy.version,
&old_name,
new_name.as_ref().unwrap_or(&old_name),
uplift,
),
DevCommand::Deprecate { name, reason } => deprecate_lint::deprecate(clippy.version, &name, &reason),
DevCommand::Sync(SyncCommand { subcommand }) => match subcommand {
SyncSubcommand::UpdateNightly => sync::update_nightly(),
},
DevCommand::Release(ReleaseCommand { subcommand }) => match subcommand {
ReleaseSubcommand::BumpVersion => release::bump_version(),
ReleaseSubcommand::BumpVersion => release::bump_version(clippy.version),
},
}
}
@ -135,11 +139,6 @@ enum DevCommand {
/// * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod` {n}
/// * all lints are registered in the lint store
UpdateLints {
#[arg(long)]
/// Print a table of lints to STDOUT
///
/// This does not include deprecated and internal lints. (Does not modify any files)
print_only: bool,
#[arg(long)]
/// Checks that `cargo dev update_lints` has been run. Used on CI.
check: bool,

View file

@ -1,4 +1,4 @@
use crate::utils::{clippy_project_root, clippy_version};
use crate::utils::{RustSearcher, Token, Version};
use clap::ValueEnum;
use indoc::{formatdoc, writedoc};
use std::fmt::{self, Write as _};
@ -22,11 +22,11 @@ impl fmt::Display for Pass {
}
struct LintData<'a> {
clippy_version: Version,
pass: Pass,
name: &'a str,
category: &'a str,
ty: Option<&'a str>,
project_root: PathBuf,
}
trait Context {
@ -50,18 +50,25 @@ impl<T> Context for io::Result<T> {
/// # Errors
///
/// This function errors out if the files couldn't be created or written to.
pub fn create(pass: Pass, name: &str, category: &str, mut ty: Option<&str>, msrv: bool) -> io::Result<()> {
pub fn create(
clippy_version: Version,
pass: Pass,
name: &str,
category: &str,
mut ty: Option<&str>,
msrv: bool,
) -> io::Result<()> {
if category == "cargo" && ty.is_none() {
// `cargo` is a special category, these lints should always be in `clippy_lints/src/cargo`
ty = Some("cargo");
}
let lint = LintData {
clippy_version,
pass,
name,
category,
ty,
project_root: clippy_project_root(),
};
create_lint(&lint, msrv).context("Unable to create lint implementation")?;
@ -88,7 +95,7 @@ fn create_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
} else {
let lint_contents = get_lint_file_contents(lint, enable_msrv);
let lint_path = format!("clippy_lints/src/{}.rs", lint.name);
write_file(lint.project_root.join(&lint_path), lint_contents.as_bytes())?;
write_file(&lint_path, lint_contents.as_bytes())?;
println!("Generated lint file: `{lint_path}`");
Ok(())
@ -115,8 +122,7 @@ fn create_test(lint: &LintData<'_>, msrv: bool) -> io::Result<()> {
}
if lint.category == "cargo" {
let relative_test_dir = format!("tests/ui-cargo/{}", lint.name);
let test_dir = lint.project_root.join(&relative_test_dir);
let test_dir = format!("tests/ui-cargo/{}", lint.name);
fs::create_dir(&test_dir)?;
create_project_layout(
@ -134,11 +140,11 @@ fn create_test(lint: &LintData<'_>, msrv: bool) -> io::Result<()> {
false,
)?;
println!("Generated test directories: `{relative_test_dir}/pass`, `{relative_test_dir}/fail`");
println!("Generated test directories: `{test_dir}/pass`, `{test_dir}/fail`");
} else {
let test_path = format!("tests/ui/{}.rs", lint.name);
let test_contents = get_test_file_contents(lint.name, msrv);
write_file(lint.project_root.join(&test_path), test_contents)?;
write_file(&test_path, test_contents)?;
println!("Generated test file: `{test_path}`");
}
@ -193,11 +199,6 @@ fn to_camel_case(name: &str) -> String {
.collect()
}
pub(crate) fn get_stabilization_version() -> String {
let (minor, patch) = clippy_version();
format!("{minor}.{patch}.0")
}
fn get_test_file_contents(lint_name: &str, msrv: bool) -> String {
let mut test = formatdoc!(
r"
@ -292,7 +293,11 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
);
}
let _: fmt::Result = writeln!(result, "{}", get_lint_declaration(&name_upper, category));
let _: fmt::Result = writeln!(
result,
"{}",
get_lint_declaration(lint.clippy_version, &name_upper, category)
);
if enable_msrv {
let _: fmt::Result = writedoc!(
@ -330,7 +335,7 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
result
}
fn get_lint_declaration(name_upper: &str, category: &str) -> String {
fn get_lint_declaration(version: Version, name_upper: &str, category: &str) -> String {
let justification_heading = if category == "restriction" {
"Why restrict this?"
} else {
@ -355,9 +360,8 @@ fn get_lint_declaration(name_upper: &str, category: &str) -> String {
pub {name_upper},
{category},
"default lint description"
}}
"#,
get_stabilization_version(),
}}"#,
version.rust_display(),
)
}
@ -371,7 +375,7 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
_ => {},
}
let ty_dir = lint.project_root.join(format!("clippy_lints/src/{ty}"));
let ty_dir = PathBuf::from(format!("clippy_lints/src/{ty}"));
assert!(
ty_dir.exists() && ty_dir.is_dir(),
"Directory `{}` does not exist!",
@ -441,95 +445,25 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
#[allow(clippy::too_many_lines)]
fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str> {
use super::update_lints::{LintDeclSearchResult, match_tokens};
use rustc_lexer::TokenKind;
let lint_name_upper = lint.name.to_uppercase();
let mut file_contents = fs::read_to_string(path)?;
assert!(
!file_contents.contains(&lint_name_upper),
!file_contents.contains(&format!("pub {lint_name_upper},")),
"Lint `{}` already defined in `{}`",
lint.name,
path.display()
);
let mut offset = 0usize;
let mut last_decl_curly_offset = None;
let mut lint_context = None;
let mut iter = rustc_lexer::tokenize(&file_contents).map(|t| {
let range = offset..offset + t.len as usize;
offset = range.end;
LintDeclSearchResult {
token_kind: t.kind,
content: &file_contents[range.clone()],
range,
}
});
// Find both the last lint declaration (declare_clippy_lint!) and the lint pass impl
while let Some(LintDeclSearchResult { content, .. }) = iter.find(|result| result.token_kind == TokenKind::Ident) {
let mut iter = iter
.by_ref()
.filter(|t| !matches!(t.token_kind, TokenKind::Whitespace | TokenKind::LineComment { .. }));
match content {
"declare_clippy_lint" => {
// matches `!{`
match_tokens!(iter, Bang OpenBrace);
if let Some(LintDeclSearchResult { range, .. }) =
iter.find(|result| result.token_kind == TokenKind::CloseBrace)
{
last_decl_curly_offset = Some(range.end);
}
},
"impl" => {
let mut token = iter.next();
match token {
// matches <'foo>
Some(LintDeclSearchResult {
token_kind: TokenKind::Lt,
..
}) => {
match_tokens!(iter, Lifetime { .. } Gt);
token = iter.next();
},
None => break,
_ => {},
}
if let Some(LintDeclSearchResult {
token_kind: TokenKind::Ident,
content,
..
}) = token
{
// Get the appropriate lint context struct
lint_context = match content {
"LateLintPass" => Some("LateContext"),
"EarlyLintPass" => Some("EarlyContext"),
_ => continue,
};
}
},
_ => {},
}
}
drop(iter);
let last_decl_curly_offset =
last_decl_curly_offset.unwrap_or_else(|| panic!("No lint declarations found in `{}`", path.display()));
let lint_context =
lint_context.unwrap_or_else(|| panic!("No lint pass implementation found in `{}`", path.display()));
let (lint_context, lint_decl_end) = parse_mod_file(path, &file_contents);
// Add the lint declaration to `mod.rs`
file_contents.replace_range(
// Remove the trailing newline, which should always be present
last_decl_curly_offset..=last_decl_curly_offset,
&format!("\n\n{}", get_lint_declaration(&lint_name_upper, lint.category)),
file_contents.insert_str(
lint_decl_end,
&format!(
"\n\n{}",
get_lint_declaration(lint.clippy_version, &lint_name_upper, lint.category)
),
);
// Add the lint to `impl_lint_pass`/`declare_lint_pass`
@ -580,6 +514,41 @@ fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str>
Ok(lint_context)
}
// Find both the last lint declaration (declare_clippy_lint!) and the lint pass impl
fn parse_mod_file(path: &Path, contents: &str) -> (&'static str, usize) {
#[allow(clippy::enum_glob_use)]
use Token::*;
let mut context = None;
let mut decl_end = None;
let mut searcher = RustSearcher::new(contents);
while let Some(name) = searcher.find_capture_token(CaptureIdent) {
match name {
"declare_clippy_lint" => {
if searcher.match_tokens(&[Bang, OpenBrace], &mut []) && searcher.find_token(CloseBrace) {
decl_end = Some(searcher.pos());
}
},
"impl" => {
let mut capture = "";
if searcher.match_tokens(&[Lt, Lifetime, Gt, CaptureIdent], &mut [&mut capture]) {
match capture {
"LateLintPass" => context = Some("LateContext"),
"EarlyLintPass" => context = Some("EarlyContext"),
_ => {},
}
}
},
_ => {},
}
}
(
context.unwrap_or_else(|| panic!("No lint pass implementation found in `{}`", path.display())),
decl_end.unwrap_or_else(|| panic!("No lint declarations found in `{}`", path.display())) as usize,
)
}
#[test]
fn test_camel_case() {
let s = "a_lint";

View file

@ -1,27 +1,27 @@
use crate::utils::{FileUpdater, Version, update_text_region_fn};
use std::fmt::Write;
use std::path::Path;
use crate::utils::{UpdateMode, clippy_version, replace_region_in_file};
const CARGO_TOML_FILES: [&str; 4] = [
static CARGO_TOML_FILES: &[&str] = &[
"clippy_config/Cargo.toml",
"clippy_lints/Cargo.toml",
"clippy_utils/Cargo.toml",
"Cargo.toml",
];
pub fn bump_version() {
let (minor, mut patch) = clippy_version();
patch += 1;
for file in &CARGO_TOML_FILES {
replace_region_in_file(
UpdateMode::Change,
Path::new(file),
"# begin autogenerated version\n",
"# end autogenerated version",
|res| {
writeln!(res, "version = \"0.{minor}.{patch}\"").unwrap();
},
pub fn bump_version(mut version: Version) {
version.minor += 1;
let mut updater = FileUpdater::default();
for file in CARGO_TOML_FILES {
updater.update_file(
file,
&mut update_text_region_fn(
"# begin autogenerated version\n",
"# end autogenerated version",
|dst| {
writeln!(dst, "version = \"{}\"", version.toml_display()).unwrap();
},
),
);
}
}

View file

@ -0,0 +1,194 @@
use crate::update_lints::{
DeprecatedLints, RenamedLint, find_lint_decls, gen_renamed_lints_test_fn, generate_lint_files,
read_deprecated_lints,
};
use crate::utils::{FileUpdater, StringReplacer, UpdateMode, Version, try_rename_file};
use std::ffi::OsStr;
use std::path::Path;
use walkdir::WalkDir;
/// Runs the `rename_lint` command.
///
/// This does the following:
/// * Adds an entry to `renamed_lints.rs`.
/// * Renames all lint attributes to the new name (e.g. `#[allow(clippy::lint_name)]`).
/// * Renames the lint struct to the new name.
/// * Renames the module containing the lint struct to the new name if it shares a name with the
/// lint.
///
/// # Panics
/// Panics for the following conditions:
/// * If a file path could not read from or then written to
/// * If either lint name has a prefix
/// * If `old_name` doesn't name an existing lint.
/// * If `old_name` names a deprecated or renamed lint.
#[allow(clippy::too_many_lines)]
pub fn rename(clippy_version: Version, old_name: &str, new_name: &str, uplift: bool) {
if let Some((prefix, _)) = old_name.split_once("::") {
panic!("`{old_name}` should not contain the `{prefix}` prefix");
}
if let Some((prefix, _)) = new_name.split_once("::") {
panic!("`{new_name}` should not contain the `{prefix}` prefix");
}
let mut updater = FileUpdater::default();
let mut lints = find_lint_decls();
let DeprecatedLints {
renamed: mut renamed_lints,
deprecated: deprecated_lints,
file: mut deprecated_file,
contents: mut deprecated_contents,
renamed_end,
..
} = read_deprecated_lints();
let mut old_lint_index = None;
let mut found_new_name = false;
for (i, lint) in lints.iter().enumerate() {
if lint.name == old_name {
old_lint_index = Some(i);
} else if lint.name == new_name {
found_new_name = true;
}
}
let old_lint_index = old_lint_index.unwrap_or_else(|| panic!("could not find lint `{old_name}`"));
let lint = RenamedLint {
old_name: format!("clippy::{old_name}"),
new_name: if uplift {
new_name.into()
} else {
format!("clippy::{new_name}")
},
};
// Renamed lints and deprecated lints shouldn't have been found in the lint list, but check just in
// case.
assert!(
!renamed_lints.iter().any(|l| lint.old_name == l.old_name),
"`{old_name}` has already been renamed"
);
assert!(
!deprecated_lints.iter().any(|l| lint.old_name == l.name),
"`{old_name}` has already been deprecated"
);
// Update all lint level attributes. (`clippy::lint_name`)
let replacements = &[(&*lint.old_name, &*lint.new_name)];
let replacer = StringReplacer::new(replacements);
for file in WalkDir::new(".").into_iter().map(Result::unwrap).filter(|f| {
let name = f.path().file_name();
let ext = f.path().extension();
(ext == Some(OsStr::new("rs")) || ext == Some(OsStr::new("fixed")))
&& name != Some(OsStr::new("rename.rs"))
&& name != Some(OsStr::new("deprecated_lints.rs"))
}) {
updater.update_file(file.path(), &mut replacer.replace_ident_fn());
}
deprecated_contents.insert_str(
renamed_end as usize,
&format!(
" #[clippy::version = \"{}\"]\n (\"{}\", \"{}\"),\n",
clippy_version.rust_display(),
lint.old_name,
lint.new_name,
),
);
deprecated_file.replace_contents(deprecated_contents.as_bytes());
drop(deprecated_file);
renamed_lints.push(lint);
renamed_lints.sort_by(|lhs, rhs| {
lhs.new_name
.starts_with("clippy::")
.cmp(&rhs.new_name.starts_with("clippy::"))
.reverse()
.then_with(|| lhs.old_name.cmp(&rhs.old_name))
});
if uplift {
updater.update_file("tests/ui/rename.rs", &mut gen_renamed_lints_test_fn(&renamed_lints));
println!(
"`{old_name}` has be uplifted. All the code inside `clippy_lints` related to it needs to be removed manually."
);
} else if found_new_name {
updater.update_file("tests/ui/rename.rs", &mut gen_renamed_lints_test_fn(&renamed_lints));
println!(
"`{new_name}` is already defined. The old linting code inside `clippy_lints` needs to be updated/removed manually."
);
} else {
// Rename the lint struct and source files sharing a name with the lint.
let lint = &mut lints[old_lint_index];
let old_name_upper = old_name.to_uppercase();
let new_name_upper = new_name.to_uppercase();
lint.name = new_name.into();
// Rename test files. only rename `.stderr` and `.fixed` files if the new test name doesn't exist.
if try_rename_file(
Path::new(&format!("tests/ui/{old_name}.rs")),
Path::new(&format!("tests/ui/{new_name}.rs")),
) {
try_rename_file(
Path::new(&format!("tests/ui/{old_name}.stderr")),
Path::new(&format!("tests/ui/{new_name}.stderr")),
);
try_rename_file(
Path::new(&format!("tests/ui/{old_name}.fixed")),
Path::new(&format!("tests/ui/{new_name}.fixed")),
);
}
// Try to rename the file containing the lint if the file name matches the lint's name.
let replacements;
let replacements = if lint.module == old_name
&& try_rename_file(
Path::new(&format!("clippy_lints/src/{old_name}.rs")),
Path::new(&format!("clippy_lints/src/{new_name}.rs")),
) {
// Edit the module name in the lint list. Note there could be multiple lints.
for lint in lints.iter_mut().filter(|l| l.module == old_name) {
lint.module = new_name.into();
}
replacements = [(&*old_name_upper, &*new_name_upper), (old_name, new_name)];
replacements.as_slice()
} else if !lint.module.contains("::")
// Catch cases like `methods/lint_name.rs` where the lint is stored in `methods/mod.rs`
&& try_rename_file(
Path::new(&format!("clippy_lints/src/{}/{old_name}.rs", lint.module)),
Path::new(&format!("clippy_lints/src/{}/{new_name}.rs", lint.module)),
)
{
// Edit the module name in the lint list. Note there could be multiple lints, or none.
let renamed_mod = format!("{}::{old_name}", lint.module);
for lint in lints.iter_mut().filter(|l| l.module == renamed_mod) {
lint.module = format!("{}::{new_name}", lint.module);
}
replacements = [(&*old_name_upper, &*new_name_upper), (old_name, new_name)];
replacements.as_slice()
} else {
replacements = [(&*old_name_upper, &*new_name_upper), ("", "")];
&replacements[0..1]
};
// Don't change `clippy_utils/src/renamed_lints.rs` here as it would try to edit the lint being
// renamed.
let replacer = StringReplacer::new(replacements);
for file in WalkDir::new("clippy_lints/src") {
let file = file.expect("error reading `clippy_lints/src`");
if file
.path()
.as_os_str()
.to_str()
.is_some_and(|x| x.ends_with("*.rs") && x["clippy_lints/src/".len()..] != *"deprecated_lints.rs")
{
updater.update_file(file.path(), &mut replacer.replace_ident_fn());
}
}
generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
println!("{old_name} has been successfully renamed");
}
println!("note: `cargo uitest` still needs to be run to update the test results");
}

View file

@ -1,33 +1,18 @@
use std::fmt::Write;
use std::path::Path;
use crate::utils::{FileUpdater, update_text_region_fn};
use chrono::offset::Utc;
use crate::utils::{UpdateMode, replace_region_in_file};
use std::fmt::Write;
pub fn update_nightly() {
// Update rust-toolchain nightly version
let date = Utc::now().format("%Y-%m-%d").to_string();
replace_region_in_file(
UpdateMode::Change,
Path::new("rust-toolchain.toml"),
let update = &mut update_text_region_fn(
"# begin autogenerated nightly\n",
"# end autogenerated nightly",
|res| {
writeln!(res, "channel = \"nightly-{date}\"").unwrap();
|dst| {
writeln!(dst, "channel = \"nightly-{date}\"").unwrap();
},
);
// Update clippy_utils nightly version
replace_region_in_file(
UpdateMode::Change,
Path::new("clippy_utils/README.md"),
"<!-- begin autogenerated nightly -->\n",
"<!-- end autogenerated nightly -->",
|res| {
writeln!(res, "```").unwrap();
writeln!(res, "nightly-{date}").unwrap();
writeln!(res, "```").unwrap();
},
);
let mut updater = FileUpdater::default();
updater.update_file("rust-toolchain.toml", update);
updater.update_file("clippy_utils/README.md", update);
}

File diff suppressed because it is too large Load diff

View file

@ -1,12 +1,113 @@
use aho_corasick::{AhoCorasick, AhoCorasickBuilder};
use core::fmt::{self, Display};
use core::slice;
use core::str::FromStr;
use rustc_lexer::{self as lexer, FrontmatterAllowed};
use std::env;
use std::fs::{self, OpenOptions};
use std::io::{self, Read as _, Seek as _, SeekFrom, Write};
use std::path::{Path, PathBuf};
use std::process::{self, ExitStatus};
use std::{fs, io};
#[cfg(not(windows))]
static CARGO_CLIPPY_EXE: &str = "cargo-clippy";
#[cfg(windows)]
static CARGO_CLIPPY_EXE: &str = "cargo-clippy.exe";
#[derive(Clone, Copy)]
pub enum FileAction {
Open,
Read,
Write,
Create,
Rename,
}
impl FileAction {
fn as_str(self) -> &'static str {
match self {
Self::Open => "opening",
Self::Read => "reading",
Self::Write => "writing",
Self::Create => "creating",
Self::Rename => "renaming",
}
}
}
#[cold]
#[track_caller]
pub fn panic_file(err: &impl Display, action: FileAction, path: &Path) -> ! {
panic!("error {} `{}`: {}", action.as_str(), path.display(), *err)
}
/// Wrapper around `std::fs::File` which panics with a path on failure.
pub struct File<'a> {
pub inner: fs::File,
pub path: &'a Path,
}
impl<'a> File<'a> {
/// Opens a file panicking on failure.
#[track_caller]
pub fn open(path: &'a (impl AsRef<Path> + ?Sized), options: &mut OpenOptions) -> Self {
let path = path.as_ref();
match options.open(path) {
Ok(inner) => Self { inner, path },
Err(e) => panic_file(&e, FileAction::Open, path),
}
}
/// Opens a file if it exists, panicking on any other failure.
#[track_caller]
pub fn open_if_exists(path: &'a (impl AsRef<Path> + ?Sized), options: &mut OpenOptions) -> Option<Self> {
let path = path.as_ref();
match options.open(path) {
Ok(inner) => Some(Self { inner, path }),
Err(e) if e.kind() == io::ErrorKind::NotFound => None,
Err(e) => panic_file(&e, FileAction::Open, path),
}
}
/// Opens and reads a file into a string, panicking of failure.
#[track_caller]
pub fn open_read_to_cleared_string<'dst>(
path: &'a (impl AsRef<Path> + ?Sized),
dst: &'dst mut String,
) -> &'dst mut String {
Self::open(path, OpenOptions::new().read(true)).read_to_cleared_string(dst)
}
/// Read the entire contents of a file to the given buffer.
#[track_caller]
pub fn read_append_to_string<'dst>(&mut self, dst: &'dst mut String) -> &'dst mut String {
match self.inner.read_to_string(dst) {
Ok(_) => {},
Err(e) => panic_file(&e, FileAction::Read, self.path),
}
dst
}
#[track_caller]
pub fn read_to_cleared_string<'dst>(&mut self, dst: &'dst mut String) -> &'dst mut String {
dst.clear();
self.read_append_to_string(dst)
}
/// Replaces the entire contents of a file.
#[track_caller]
pub fn replace_contents(&mut self, data: &[u8]) {
let res = match self.inner.seek(SeekFrom::Start(0)) {
Ok(_) => match self.inner.write_all(data) {
Ok(()) => self.inner.set_len(data.len() as u64),
Err(e) => Err(e),
},
Err(e) => Err(e),
};
if let Err(e) = res {
panic_file(&e, FileAction::Write, self.path);
}
}
}
/// Returns the path to the `cargo-clippy` binary
///
/// # Panics
@ -14,34 +115,107 @@ static CARGO_CLIPPY_EXE: &str = "cargo-clippy.exe";
/// Panics if the path of current executable could not be retrieved.
#[must_use]
pub fn cargo_clippy_path() -> PathBuf {
let mut path = std::env::current_exe().expect("failed to get current executable name");
let mut path = env::current_exe().expect("failed to get current executable name");
path.set_file_name(CARGO_CLIPPY_EXE);
path
}
/// Returns the path to the Clippy project directory
///
/// # Panics
///
/// Panics if the current directory could not be retrieved, there was an error reading any of the
/// Cargo.toml files or ancestor directory is the clippy root directory
#[must_use]
pub fn clippy_project_root() -> PathBuf {
let current_dir = std::env::current_dir().unwrap();
for path in current_dir.ancestors() {
let result = fs::read_to_string(path.join("Cargo.toml"));
if let Err(err) = &result
&& err.kind() == io::ErrorKind::NotFound
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Version {
pub major: u16,
pub minor: u16,
}
impl FromStr for Version {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Some(s) = s.strip_prefix("0.")
&& let Some((major, minor)) = s.split_once('.')
&& let Ok(major) = major.parse()
&& let Ok(minor) = minor.parse()
{
continue;
}
let content = result.unwrap();
if content.contains("[package]\nname = \"clippy\"") {
return path.to_path_buf();
Ok(Self { major, minor })
} else {
Err(())
}
}
}
impl Version {
/// Displays the version as a rust version. i.e. `x.y.0`
#[must_use]
pub fn rust_display(self) -> impl Display {
struct X(Version);
impl Display for X {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}.{}.0", self.0.major, self.0.minor)
}
}
X(self)
}
/// Displays the version as it should appear in clippy's toml files. i.e. `0.x.y`
#[must_use]
pub fn toml_display(self) -> impl Display {
struct X(Version);
impl Display for X {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "0.{}.{}", self.0.major, self.0.minor)
}
}
X(self)
}
}
pub struct ClippyInfo {
pub path: PathBuf,
pub version: Version,
}
impl ClippyInfo {
#[must_use]
pub fn search_for_manifest() -> Self {
let mut path = env::current_dir().expect("error reading the working directory");
let mut buf = String::new();
loop {
path.push("Cargo.toml");
if let Some(mut file) = File::open_if_exists(&path, OpenOptions::new().read(true)) {
let mut in_package = false;
let mut is_clippy = false;
let mut version: Option<Version> = None;
// Ad-hoc parsing to avoid dependencies. We control all the file so this
// isn't actually a problem
for line in file.read_to_cleared_string(&mut buf).lines() {
if line.starts_with('[') {
in_package = line.starts_with("[package]");
} else if in_package && let Some((name, value)) = line.split_once('=') {
match name.trim() {
"name" => is_clippy = value.trim() == "\"clippy\"",
"version"
if let Some(value) = value.trim().strip_prefix('"')
&& let Some(value) = value.strip_suffix('"') =>
{
version = value.parse().ok();
},
_ => {},
}
}
}
if is_clippy {
let Some(version) = version else {
panic!("error reading clippy version from {}", file.path.display());
};
path.pop();
return ClippyInfo { path, version };
}
}
path.pop();
assert!(
path.pop(),
"error finding project root, please run from inside the clippy directory"
);
}
}
panic!("error: Can't determine root of project. Please run inside a Clippy working dir.");
}
/// # Panics
@ -57,86 +231,396 @@ pub fn exit_if_err(status: io::Result<ExitStatus>) {
}
}
pub(crate) fn clippy_version() -> (u32, u32) {
fn parse_manifest(contents: &str) -> Option<(u32, u32)> {
let version = contents
.lines()
.filter_map(|l| l.split_once('='))
.find_map(|(k, v)| (k.trim() == "version").then(|| v.trim()))?;
let Some(("0", version)) = version.get(1..version.len() - 1)?.split_once('.') else {
return None;
};
let (minor, patch) = version.split_once('.')?;
Some((minor.parse().ok()?, patch.parse().ok()?))
#[derive(Clone, Copy)]
pub enum UpdateStatus {
Unchanged,
Changed,
}
impl UpdateStatus {
#[must_use]
pub fn from_changed(value: bool) -> Self {
if value { Self::Changed } else { Self::Unchanged }
}
#[must_use]
pub fn is_changed(self) -> bool {
matches!(self, Self::Changed)
}
let contents = fs::read_to_string("Cargo.toml").expect("Unable to read `Cargo.toml`");
parse_manifest(&contents).expect("Unable to find package version in `Cargo.toml`")
}
#[derive(Clone, Copy, PartialEq, Eq)]
#[derive(Clone, Copy)]
pub enum UpdateMode {
Check,
Change,
Check,
}
impl UpdateMode {
#[must_use]
pub fn from_check(check: bool) -> Self {
if check { Self::Check } else { Self::Change }
}
}
pub(crate) fn exit_with_failure() {
println!(
"Not all lints defined properly. \
Please run `cargo dev update_lints` to make sure all lints are defined properly."
);
process::exit(1);
#[derive(Default)]
pub struct FileUpdater {
src_buf: String,
dst_buf: String,
}
impl FileUpdater {
fn update_file_checked_inner(
&mut self,
tool: &str,
mode: UpdateMode,
path: &Path,
update: &mut dyn FnMut(&Path, &str, &mut String) -> UpdateStatus,
) {
let mut file = File::open(path, OpenOptions::new().read(true).write(true));
file.read_to_cleared_string(&mut self.src_buf);
self.dst_buf.clear();
match (mode, update(path, &self.src_buf, &mut self.dst_buf)) {
(UpdateMode::Check, UpdateStatus::Changed) => {
eprintln!(
"the contents of `{}` are out of date\nplease run `{tool}` to update",
path.display()
);
process::exit(1);
},
(UpdateMode::Change, UpdateStatus::Changed) => file.replace_contents(self.dst_buf.as_bytes()),
(UpdateMode::Check | UpdateMode::Change, UpdateStatus::Unchanged) => {},
}
}
/// Replaces a region in a file delimited by two lines matching regexes.
///
/// `path` is the relative path to the file on which you want to perform the replacement.
///
/// See `replace_region_in_text` for documentation of the other options.
///
/// # Panics
///
/// Panics if the path could not read or then written
pub(crate) fn replace_region_in_file(
update_mode: UpdateMode,
path: &Path,
start: &str,
end: &str,
write_replacement: impl FnMut(&mut String),
) {
let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {e}", path.display()));
let new_contents = match replace_region_in_text(&contents, start, end, write_replacement) {
Ok(x) => x,
Err(delim) => panic!("Couldn't find `{delim}` in file `{}`", path.display()),
};
fn update_file_inner(&mut self, path: &Path, update: &mut dyn FnMut(&Path, &str, &mut String) -> UpdateStatus) {
let mut file = File::open(path, OpenOptions::new().read(true).write(true));
file.read_to_cleared_string(&mut self.src_buf);
self.dst_buf.clear();
if update(path, &self.src_buf, &mut self.dst_buf).is_changed() {
file.replace_contents(self.dst_buf.as_bytes());
}
}
match update_mode {
UpdateMode::Check if contents != new_contents => exit_with_failure(),
UpdateMode::Check => (),
UpdateMode::Change => {
if let Err(e) = fs::write(path, new_contents.as_bytes()) {
panic!("Cannot write to `{}`: {e}", path.display());
}
},
pub fn update_file_checked(
&mut self,
tool: &str,
mode: UpdateMode,
path: impl AsRef<Path>,
update: &mut dyn FnMut(&Path, &str, &mut String) -> UpdateStatus,
) {
self.update_file_checked_inner(tool, mode, path.as_ref(), update);
}
#[expect(clippy::type_complexity)]
pub fn update_files_checked(
&mut self,
tool: &str,
mode: UpdateMode,
files: &mut [(
impl AsRef<Path>,
&mut dyn FnMut(&Path, &str, &mut String) -> UpdateStatus,
)],
) {
for (path, update) in files {
self.update_file_checked_inner(tool, mode, path.as_ref(), update);
}
}
pub fn update_file(
&mut self,
path: impl AsRef<Path>,
update: &mut dyn FnMut(&Path, &str, &mut String) -> UpdateStatus,
) {
self.update_file_inner(path.as_ref(), update);
}
}
/// Replaces a region in a text delimited by two strings. Returns the new text if both delimiters
/// were found, or the missing delimiter if not.
pub(crate) fn replace_region_in_text<'a>(
text: &str,
start: &'a str,
end: &'a str,
mut write_replacement: impl FnMut(&mut String),
) -> Result<String, &'a str> {
let (text_start, rest) = text.split_once(start).ok_or(start)?;
let (_, text_end) = rest.split_once(end).ok_or(end)?;
let mut res = String::with_capacity(text.len() + 4096);
res.push_str(text_start);
res.push_str(start);
write_replacement(&mut res);
res.push_str(end);
res.push_str(text_end);
Ok(res)
pub fn update_text_region(
path: &Path,
start: &str,
end: &str,
src: &str,
dst: &mut String,
insert: &mut impl FnMut(&mut String),
) -> UpdateStatus {
let Some((src_start, src_end)) = src.split_once(start) else {
panic!("`{}` does not contain `{start}`", path.display());
};
let Some((replaced_text, src_end)) = src_end.split_once(end) else {
panic!("`{}` does not contain `{end}`", path.display());
};
dst.push_str(src_start);
dst.push_str(start);
let new_start = dst.len();
insert(dst);
let changed = dst[new_start..] != *replaced_text;
dst.push_str(end);
dst.push_str(src_end);
UpdateStatus::from_changed(changed)
}
pub fn update_text_region_fn(
start: &str,
end: &str,
mut insert: impl FnMut(&mut String),
) -> impl FnMut(&Path, &str, &mut String) -> UpdateStatus {
move |path, src, dst| update_text_region(path, start, end, src, dst, &mut insert)
}
#[must_use]
pub fn is_ident_char(c: u8) -> bool {
matches!(c, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'_')
}
pub struct StringReplacer<'a> {
searcher: AhoCorasick,
replacements: &'a [(&'a str, &'a str)],
}
impl<'a> StringReplacer<'a> {
#[must_use]
pub fn new(replacements: &'a [(&'a str, &'a str)]) -> Self {
Self {
searcher: AhoCorasickBuilder::new()
.match_kind(aho_corasick::MatchKind::LeftmostLongest)
.build(replacements.iter().map(|&(x, _)| x))
.unwrap(),
replacements,
}
}
/// Replace substrings if they aren't bordered by identifier characters.
pub fn replace_ident_fn(&self) -> impl Fn(&Path, &str, &mut String) -> UpdateStatus {
move |_, src, dst| {
let mut pos = 0;
let mut changed = false;
for m in self.searcher.find_iter(src) {
if !is_ident_char(src.as_bytes().get(m.start().wrapping_sub(1)).copied().unwrap_or(0))
&& !is_ident_char(src.as_bytes().get(m.end()).copied().unwrap_or(0))
{
changed = true;
dst.push_str(&src[pos..m.start()]);
dst.push_str(self.replacements[m.pattern()].1);
pos = m.end();
}
}
dst.push_str(&src[pos..]);
UpdateStatus::from_changed(changed)
}
}
}
#[derive(Clone, Copy)]
pub enum Token {
/// Matches any number of doc comments.
AnyDoc,
Ident(&'static str),
CaptureIdent,
LitStr,
CaptureLitStr,
Bang,
CloseBrace,
CloseBracket,
CloseParen,
/// This will consume the first colon even if the second doesn't exist.
DoubleColon,
Comma,
Eq,
Lifetime,
Lt,
Gt,
OpenBrace,
OpenBracket,
OpenParen,
Pound,
}
pub struct RustSearcher<'txt> {
text: &'txt str,
cursor: lexer::Cursor<'txt>,
pos: u32,
// Either the next token or a zero-sized whitespace sentinel.
next_token: lexer::Token,
}
impl<'txt> RustSearcher<'txt> {
#[must_use]
pub fn new(text: &'txt str) -> Self {
Self {
text,
cursor: lexer::Cursor::new(text, FrontmatterAllowed::Yes),
pos: 0,
// Sentinel value indicating there is no read token.
next_token: lexer::Token {
len: 0,
kind: lexer::TokenKind::Whitespace,
},
}
}
#[must_use]
pub fn peek_text(&self) -> &'txt str {
&self.text[self.pos as usize..(self.pos + self.next_token.len) as usize]
}
#[must_use]
pub fn peek(&self) -> lexer::TokenKind {
self.next_token.kind
}
#[must_use]
pub fn pos(&self) -> u32 {
self.pos
}
#[must_use]
pub fn at_end(&self) -> bool {
self.next_token.kind == lexer::TokenKind::Eof
}
pub fn step(&mut self) {
// `next_len` is zero for the sentinel value and the eof marker.
self.pos += self.next_token.len;
self.next_token = self.cursor.advance_token();
}
/// Consumes the next token if it matches the requested value and captures the value if
/// requested. Returns true if a token was matched.
fn read_token(&mut self, token: Token, captures: &mut slice::IterMut<'_, &mut &'txt str>) -> bool {
loop {
match (token, self.next_token.kind) {
// Has to be the first match arm so the empty sentinel token will be handled.
// This will also skip all whitespace/comments preceding any tokens.
(
_,
lexer::TokenKind::Whitespace
| lexer::TokenKind::LineComment { doc_style: None }
| lexer::TokenKind::BlockComment {
doc_style: None,
terminated: true,
},
) => {
self.step();
if self.at_end() {
// `AnyDoc` always matches.
return matches!(token, Token::AnyDoc);
}
},
(
Token::AnyDoc,
lexer::TokenKind::BlockComment { terminated: true, .. } | lexer::TokenKind::LineComment { .. },
) => {
self.step();
if self.at_end() {
// `AnyDoc` always matches.
return true;
}
},
(Token::AnyDoc, _) => return true,
(Token::Bang, lexer::TokenKind::Bang)
| (Token::CloseBrace, lexer::TokenKind::CloseBrace)
| (Token::CloseBracket, lexer::TokenKind::CloseBracket)
| (Token::CloseParen, lexer::TokenKind::CloseParen)
| (Token::Comma, lexer::TokenKind::Comma)
| (Token::Eq, lexer::TokenKind::Eq)
| (Token::Lifetime, lexer::TokenKind::Lifetime { .. })
| (Token::Lt, lexer::TokenKind::Lt)
| (Token::Gt, lexer::TokenKind::Gt)
| (Token::OpenBrace, lexer::TokenKind::OpenBrace)
| (Token::OpenBracket, lexer::TokenKind::OpenBracket)
| (Token::OpenParen, lexer::TokenKind::OpenParen)
| (Token::Pound, lexer::TokenKind::Pound)
| (
Token::LitStr,
lexer::TokenKind::Literal {
kind: lexer::LiteralKind::Str { terminated: true } | lexer::LiteralKind::RawStr { .. },
..
},
) => {
self.step();
return true;
},
(Token::Ident(x), lexer::TokenKind::Ident) if x == self.peek_text() => {
self.step();
return true;
},
(Token::DoubleColon, lexer::TokenKind::Colon) => {
self.step();
if !self.at_end() && matches!(self.next_token.kind, lexer::TokenKind::Colon) {
self.step();
return true;
}
return false;
},
(
Token::CaptureLitStr,
lexer::TokenKind::Literal {
kind: lexer::LiteralKind::Str { terminated: true } | lexer::LiteralKind::RawStr { .. },
..
},
)
| (Token::CaptureIdent, lexer::TokenKind::Ident) => {
**captures.next().unwrap() = self.peek_text();
self.step();
return true;
},
_ => return false,
}
}
}
#[must_use]
pub fn find_token(&mut self, token: Token) -> bool {
let mut capture = [].iter_mut();
while !self.read_token(token, &mut capture) {
self.step();
if self.at_end() {
return false;
}
}
true
}
#[must_use]
pub fn find_capture_token(&mut self, token: Token) -> Option<&'txt str> {
let mut res = "";
let mut capture = &mut res;
let mut capture = slice::from_mut(&mut capture).iter_mut();
while !self.read_token(token, &mut capture) {
self.step();
if self.at_end() {
return None;
}
}
Some(res)
}
#[must_use]
pub fn match_tokens(&mut self, tokens: &[Token], captures: &mut [&mut &'txt str]) -> bool {
let mut captures = captures.iter_mut();
tokens.iter().all(|&t| self.read_token(t, &mut captures))
}
}
#[expect(clippy::must_use_candidate)]
pub fn try_rename_file(old_name: &Path, new_name: &Path) -> bool {
match OpenOptions::new().create_new(true).write(true).open(new_name) {
Ok(file) => drop(file),
Err(e) if matches!(e.kind(), io::ErrorKind::AlreadyExists | io::ErrorKind::NotFound) => return false,
Err(e) => panic_file(&e, FileAction::Create, new_name),
}
match fs::rename(old_name, new_name) {
Ok(()) => true,
Err(e) => {
drop(fs::remove_file(new_name));
if e.kind() == io::ErrorKind::NotFound {
false
} else {
panic_file(&e, FileAction::Rename, old_name);
}
},
}
}
pub fn write_file(path: &Path, contents: &str) {
fs::write(path, contents).unwrap_or_else(|e| panic_file(&e, FileAction::Write, path));
}

View file

@ -1,7 +1,7 @@
[package]
name = "clippy_lints"
# begin autogenerated version
version = "0.1.88"
version = "0.1.89"
# end autogenerated version
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"

View file

@ -468,7 +468,7 @@ declare_clippy_lint! {
/// #[ignore = "Some good reason"]
/// fn test() {}
/// ```
#[clippy::version = "1.85.0"]
#[clippy::version = "1.88.0"]
pub IGNORE_WITHOUT_REASON,
pedantic,
"ignored tests without messages"

View file

@ -26,16 +26,16 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
if namespace.is_none()
&& matches!(
name.as_str(),
"ambiguous_glob_reexports"
| "dead_code"
| "deprecated"
| "hidden_glob_reexports"
| "unreachable_pub"
| "unused"
| "unused_braces"
| "unused_import_braces"
| "unused_imports"
name,
sym::ambiguous_glob_reexports
| sym::dead_code
| sym::deprecated
| sym::hidden_glob_reexports
| sym::unreachable_pub
| sym::unused
| sym::unused_braces
| sym::unused_import_braces
| sym::unused_imports
)
{
return;
@ -43,16 +43,16 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
if namespace == Some(sym::clippy)
&& matches!(
name.as_str(),
"wildcard_imports"
| "enum_glob_use"
| "redundant_pub_crate"
| "macro_use_imports"
| "unsafe_removed_from_name"
| "module_name_repetitions"
| "single_component_path_imports"
| "disallowed_types"
| "unused_trait_names"
name,
sym::wildcard_imports
| sym::enum_glob_use
| sym::redundant_pub_crate
| sym::macro_use_imports
| sym::unsafe_removed_from_name
| sym::module_name_repetitions
| sym::single_component_path_imports
| sym::disallowed_types
| sym::unused_trait_names
)
{
return;

View file

@ -1,7 +1,7 @@
use clippy_config::Conf;
use clippy_config::types::{DisallowedPathWithoutReplacement, create_disallowed_map};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::{match_def_path, paths};
use clippy_utils::paths::{self, PathNS};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, DefIdMap};
use rustc_lint::{LateContext, LateLintPass};
@ -182,6 +182,7 @@ impl AwaitHolding {
let (def_ids, _) = create_disallowed_map(
tcx,
&conf.await_holding_invalid_types,
PathNS::Type,
crate::disallowed_types::def_kind_predicate,
"type",
false,
@ -275,12 +276,10 @@ fn emit_invalid_type(
}
fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {
cx.tcx.is_diagnostic_item(sym::MutexGuard, def_id)
|| cx.tcx.is_diagnostic_item(sym::RwLockReadGuard, def_id)
|| cx.tcx.is_diagnostic_item(sym::RwLockWriteGuard, def_id)
|| match_def_path(cx, def_id, &paths::PARKING_LOT_MUTEX_GUARD)
|| match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_READ_GUARD)
|| match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_WRITE_GUARD)
match cx.tcx.get_diagnostic_name(def_id) {
Some(name) => matches!(name, sym::MutexGuard | sym::RwLockReadGuard | sym::RwLockWriteGuard),
None => paths::PARKING_LOT_GUARDS.iter().any(|guard| guard.matches(cx, def_id)),
}
}
fn is_refcell_ref(cx: &LateContext<'_>, def_id: DefId) -> bool {

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::macros::{find_assert_eq_args, root_macro_call_first_node};
use clippy_utils::sugg::Sugg;
use clippy_utils::sym;
use clippy_utils::ty::{implements_trait, is_copy};
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
@ -73,10 +74,9 @@ impl<'tcx> LateLintPass<'tcx> for BoolAssertComparison {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
let macro_name = cx.tcx.item_name(macro_call.def_id);
let eq_macro = match macro_name.as_str() {
"assert_eq" | "debug_assert_eq" => true,
"assert_ne" | "debug_assert_ne" => false,
let eq_macro = match cx.tcx.get_diagnostic_name(macro_call.def_id) {
Some(sym::assert_eq_macro | sym::debug_assert_eq_macro) => true,
Some(sym::assert_ne_macro | sym::debug_assert_ne_macro) => false,
_ => return,
};
let Some((a, b, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else {
@ -115,6 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for BoolAssertComparison {
return;
}
let macro_name = cx.tcx.item_name(macro_call.def_id);
let macro_name = macro_name.as_str();
let non_eq_mac = &macro_name[..macro_name.len() - 3];
span_lint_and_then(

View file

@ -0,0 +1,82 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability;
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty::{self, GenericArg, Ty};
use rustc_span::def_id::DefId;
use rustc_span::{Symbol, sym};
use super::CONFUSING_METHOD_TO_NUMERIC_CAST;
fn get_primitive_ty_name(ty: Ty<'_>) -> Option<&'static str> {
match ty.kind() {
ty::Char => Some("char"),
ty::Int(int) => Some(int.name_str()),
ty::Uint(uint) => Some(uint.name_str()),
ty::Float(float) => Some(float.name_str()),
_ => None,
}
}
fn get_const_name_and_ty_name(
cx: &LateContext<'_>,
method_name: Symbol,
method_def_id: DefId,
generics: &[GenericArg<'_>],
) -> Option<(&'static str, &'static str)> {
let method_name = method_name.as_str();
let diagnostic_name = cx.tcx.get_diagnostic_name(method_def_id);
let ty_name = if diagnostic_name.is_some_and(|diag| diag == sym::cmp_ord_min || diag == sym::cmp_ord_max) {
// We get the type on which the `min`/`max` method of the `Ord` trait is implemented.
if let [ty] = generics
&& let Some(ty) = ty.as_type()
{
get_primitive_ty_name(ty)?
} else {
return None;
}
} else if let Some(impl_id) = cx.tcx.impl_of_method(method_def_id)
&& let Some(ty_name) = get_primitive_ty_name(cx.tcx.type_of(impl_id).instantiate_identity())
&& ["min", "max", "minimum", "maximum", "min_value", "max_value"].contains(&method_name)
{
ty_name
} else {
return None;
};
let const_name = if method_name.starts_with("max") { "MAX" } else { "MIN" };
Some((const_name, ty_name))
}
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
// We allow casts from any function type to any function type.
match cast_to.kind() {
ty::FnDef(..) | ty::FnPtr(..) => return,
_ => { /* continue to checks */ },
}
if let ty::FnDef(def_id, generics) = cast_from.kind()
&& let Some(method_name) = cx.tcx.opt_item_name(*def_id)
&& let Some((const_name, ty_name)) = get_const_name_and_ty_name(cx, method_name, *def_id, generics.as_slice())
{
let mut applicability = Applicability::MaybeIncorrect;
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "..", &mut applicability);
span_lint_and_then(
cx,
CONFUSING_METHOD_TO_NUMERIC_CAST,
expr.span,
format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
|diag| {
diag.span_suggestion_verbose(
expr.span,
"did you mean to use the associated constant?",
format!("{ty_name}::{const_name} as {cast_to}"),
applicability,
);
},
);
}
}

View file

@ -1,7 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::SpanRangeExt;
use clippy_utils::ty::is_normalizable;
use clippy_utils::{expr_or_init, match_def_path, path_def_id, paths, std_or_core};
use clippy_utils::{expr_or_init, path_def_id, paths, std_or_core};
use rustc_ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, GenericArg, Mutability, QPath, Ty, TyKind};
@ -55,7 +54,7 @@ fn is_expr_const_aligned(cx: &LateContext<'_>, expr: &Expr<'_>, to: &Ty<'_>) ->
fn is_align_of_call(cx: &LateContext<'_>, fun: &Expr<'_>, to: &Ty<'_>) -> bool {
if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind
&& let Some(fun_id) = path_def_id(cx, fun)
&& match_def_path(cx, fun_id, &paths::ALIGN_OF)
&& paths::ALIGN_OF.matches(cx, fun_id)
&& let Some(args) = path.segments.last().and_then(|seg| seg.args)
&& let [GenericArg::Type(generic_ty)] = args.args
{
@ -71,12 +70,10 @@ fn is_literal_aligned(cx: &LateContext<'_>, lit: &Spanned<LitKind>, to: &Ty<'_>)
return false;
}
let to_mid_ty = cx.typeck_results().node_type(to.hir_id);
is_normalizable(cx, cx.param_env, to_mid_ty)
&& cx
.tcx
.layout_of(cx.typing_env().as_query_input(to_mid_ty))
.is_ok_and(|layout| {
let align = u128::from(layout.align.abi.bytes());
u128::from(val) <= align
})
cx.tcx
.layout_of(cx.typing_env().as_query_input(to_mid_ty))
.is_ok_and(|layout| {
let align = u128::from(layout.align.abi.bytes());
u128::from(val) <= align
})
}

View file

@ -14,6 +14,7 @@ mod cast_sign_loss;
mod cast_slice_different_sizes;
mod cast_slice_from_raw_parts;
mod char_lit_as_u8;
mod confusing_method_to_numeric_cast;
mod fn_to_numeric_cast;
mod fn_to_numeric_cast_any;
mod fn_to_numeric_cast_with_truncation;
@ -780,12 +781,38 @@ declare_clippy_lint! {
/// let aligned = std::ptr::dangling::<u32>();
/// let mut_ptr: *mut i64 = std::ptr::dangling_mut();
/// ```
#[clippy::version = "1.87.0"]
#[clippy::version = "1.88.0"]
pub MANUAL_DANGLING_PTR,
style,
"casting small constant literals to pointers to create dangling pointers"
}
declare_clippy_lint! {
/// ### What it does
/// Checks for casts of a primitive method pointer like `max`/`min` to any integer type.
///
/// ### Why restrict this?
/// Casting a function pointer to an integer can have surprising results and can occur
/// accidentally if parentheses are omitted from a function call. If you aren't doing anything
/// low-level with function pointers then you can opt out of casting functions to integers in
/// order to avoid mistakes. Alternatively, you can use this lint to audit all uses of function
/// pointer casts in your code.
///
/// ### Example
/// ```no_run
/// let _ = u16::max as usize;
/// ```
///
/// Use instead:
/// ```no_run
/// let _ = u16::MAX as usize;
/// ```
#[clippy::version = "1.86.0"]
pub CONFUSING_METHOD_TO_NUMERIC_CAST,
suspicious,
"casting a primitive method pointer to any integer type"
}
pub struct Casts {
msrv: Msrv,
}
@ -823,6 +850,7 @@ impl_lint_pass!(Casts => [
REF_AS_PTR,
AS_POINTER_UNDERSCORE,
MANUAL_DANGLING_PTR,
CONFUSING_METHOD_TO_NUMERIC_CAST,
]);
impl<'tcx> LateLintPass<'tcx> for Casts {
@ -847,6 +875,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
ptr_cast_constness::check(cx, expr, cast_from_expr, cast_from, cast_to, self.msrv);
as_ptr_cast_mut::check(cx, expr, cast_from_expr, cast_to);
fn_to_numeric_cast_any::check(cx, expr, cast_from_expr, cast_from, cast_to);
confusing_method_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);
fn_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_from_expr, cast_from, cast_to);
zero_ptr::check(cx, expr, cast_from_expr, cast_to_hir);

View file

@ -0,0 +1,100 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::sugg::Sugg;
use clippy_utils::visitors::is_const_evaluatable;
use clippy_utils::{is_in_const_context, is_mutable, is_trait_method};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
///
/// Checks for slice references with cloned references such as `&[f.clone()]`.
///
/// ### Why is this bad
///
/// A reference does not need to be owned in order to used as a slice.
///
/// ### Known problems
///
/// This lint does not know whether or not a clone implementation has side effects.
///
/// ### Example
///
/// ```ignore
/// let data = 10;
/// let data_ref = &data;
/// take_slice(&[data_ref.clone()]);
/// ```
/// Use instead:
/// ```ignore
/// use std::slice;
/// let data = 10;
/// let data_ref = &data;
/// take_slice(slice::from_ref(data_ref));
/// ```
#[clippy::version = "1.87.0"]
pub CLONED_REF_TO_SLICE_REFS,
perf,
"cloning a reference for slice references"
}
pub struct ClonedRefToSliceRefs<'a> {
msrv: &'a Msrv,
}
impl<'a> ClonedRefToSliceRefs<'a> {
pub fn new(conf: &'a Conf) -> Self {
Self { msrv: &conf.msrv }
}
}
impl_lint_pass!(ClonedRefToSliceRefs<'_> => [CLONED_REF_TO_SLICE_REFS]);
impl<'tcx> LateLintPass<'tcx> for ClonedRefToSliceRefs<'_> {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
if self.msrv.meets(cx, {
if is_in_const_context(cx) {
msrvs::CONST_SLICE_FROM_REF
} else {
msrvs::SLICE_FROM_REF
}
})
// `&[foo.clone()]` expressions
&& let ExprKind::AddrOf(_, mutability, arr) = &expr.kind
// mutable references would have a different meaning
&& mutability.is_not()
// check for single item arrays
&& let ExprKind::Array([item]) = &arr.kind
// check for clones
&& let ExprKind::MethodCall(_, val, _, _) = item.kind
&& is_trait_method(cx, item, sym::Clone)
// check for immutability or purity
&& (!is_mutable(cx, val) || is_const_evaluatable(cx, val))
// get appropriate crate for `slice::from_ref`
&& let Some(builtin_crate) = clippy_utils::std_or_core(cx)
{
let mut sugg = Sugg::hir(cx, val, "_");
if !cx.typeck_results().expr_ty(val).is_ref() {
sugg = sugg.addr();
}
span_lint_and_sugg(
cx,
CLONED_REF_TO_SLICE_REFS,
expr.span,
format!("this call to `clone` can be replaced with `{builtin_crate}::slice::from_ref`"),
"try",
format!("{builtin_crate}::slice::from_ref({sugg})"),
Applicability::MaybeIncorrect,
);
}
}
}

View file

@ -1,11 +1,11 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{IntoSpan as _, SpanRangeExt, snippet, snippet_block, snippet_block_with_applicability};
use rustc_ast::BinOpKind;
use rustc_errors::Applicability;
use rustc_hir::{Block, Expr, ExprKind, StmtKind};
use rustc_hir::{Block, Expr, ExprKind, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyCtxt;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
@ -78,14 +78,14 @@ declare_clippy_lint! {
}
pub struct CollapsibleIf {
let_chains_enabled: bool,
msrv: Msrv,
lint_commented_code: bool,
}
impl CollapsibleIf {
pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
pub fn new(conf: &'static Conf) -> Self {
Self {
let_chains_enabled: tcx.features().let_chains(),
msrv: conf.msrv,
lint_commented_code: conf.lint_commented_code,
}
}
@ -127,7 +127,7 @@ impl CollapsibleIf {
if let Some(inner) = expr_block(then)
&& cx.tcx.hir_attrs(inner.hir_id).is_empty()
&& let ExprKind::If(check_inner, _, None) = &inner.kind
&& self.eligible_condition(check_inner)
&& self.eligible_condition(cx, check_inner)
&& let ctxt = expr.span.ctxt()
&& inner.span.ctxt() == ctxt
&& (self.lint_commented_code || !block_starts_with_comment(cx, then))
@ -163,8 +163,9 @@ impl CollapsibleIf {
}
}
pub fn eligible_condition(&self, cond: &Expr<'_>) -> bool {
self.let_chains_enabled || !matches!(cond.kind, ExprKind::Let(..))
fn eligible_condition(&self, cx: &LateContext<'_>, cond: &Expr<'_>) -> bool {
!matches!(cond.kind, ExprKind::Let(..))
|| (cx.tcx.sess.edition().at_least_rust_2024() && self.msrv.meets(cx, msrvs::LET_CHAINS))
}
}
@ -180,7 +181,7 @@ impl LateLintPass<'_> for CollapsibleIf {
{
Self::check_collapsible_else_if(cx, then.span, else_);
} else if else_.is_none()
&& self.eligible_condition(cond)
&& self.eligible_condition(cx, cond)
&& let ExprKind::Block(then, None) = then.kind
{
self.check_collapsible_if_if(cx, expr, cond, then);
@ -202,13 +203,12 @@ fn block_starts_with_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
fn expr_block<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> {
match block.stmts {
[] => block.expr,
[stmt] => {
if let StmtKind::Semi(expr) = stmt.kind {
Some(expr)
} else {
None
}
},
[
Stmt {
kind: StmtKind::Semi(expr),
..
},
] if block.expr.is_none() => Some(expr),
_ => None,
}
}

View file

@ -64,6 +64,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
crate::casts::CAST_SLICE_DIFFERENT_SIZES_INFO,
crate::casts::CAST_SLICE_FROM_RAW_PARTS_INFO,
crate::casts::CHAR_LIT_AS_U8_INFO,
crate::casts::CONFUSING_METHOD_TO_NUMERIC_CAST_INFO,
crate::casts::FN_TO_NUMERIC_CAST_INFO,
crate::casts::FN_TO_NUMERIC_CAST_ANY_INFO,
crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO,
@ -75,6 +76,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
crate::casts::ZERO_PTR_INFO,
crate::cfg_not_test::CFG_NOT_TEST_INFO,
crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
crate::cloned_ref_to_slice_refs::CLONED_REF_TO_SLICE_REFS_INFO,
crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO,
crate::collapsible_if::COLLAPSIBLE_ELSE_IF_INFO,
crate::collapsible_if::COLLAPSIBLE_IF_INFO,
@ -705,13 +707,9 @@ pub static LINTS: &[&crate::LintInfo] = &[
crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS_INFO,
crate::transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS_INFO,
crate::transmute::TRANSMUTE_BYTES_TO_STR_INFO,
crate::transmute::TRANSMUTE_FLOAT_TO_INT_INFO,
crate::transmute::TRANSMUTE_INT_TO_BOOL_INFO,
crate::transmute::TRANSMUTE_INT_TO_CHAR_INFO,
crate::transmute::TRANSMUTE_INT_TO_FLOAT_INFO,
crate::transmute::TRANSMUTE_INT_TO_NON_ZERO_INFO,
crate::transmute::TRANSMUTE_NULL_TO_FN_INFO,
crate::transmute::TRANSMUTE_NUM_TO_BYTES_INFO,
crate::transmute::TRANSMUTE_PTR_TO_PTR_INFO,
crate::transmute::TRANSMUTE_PTR_TO_REF_INFO,
crate::transmute::TRANSMUTE_UNDEFINED_REPR_INFO,

View file

@ -2,18 +2,18 @@
// Prefer to use those when possible.
macro_rules! declare_with_version {
($name:ident($name_version:ident): &[$ty:ty] = &[$(
($name:ident($name_version:ident) = [$(
#[clippy::version = $version:literal]
$e:expr,
)*]) => {
pub static $name: &[$ty] = &[$($e),*];
pub static $name: &[(&str, &str)] = &[$($e),*];
#[allow(unused)]
pub static $name_version: &[&str] = &[$($version),*];
};
}
#[rustfmt::skip]
declare_with_version! { DEPRECATED(DEPRECATED_VERSION): &[(&str, &str)] = &[
declare_with_version! { DEPRECATED(DEPRECATED_VERSION) = [
#[clippy::version = "pre 1.29.0"]
("clippy::should_assert_eq", "`assert!(a == b)` can now print the values the same way `assert_eq!(a, b) can"),
#[clippy::version = "pre 1.29.0"]
@ -44,11 +44,10 @@ declare_with_version! { DEPRECATED(DEPRECATED_VERSION): &[(&str, &str)] = &[
("clippy::option_map_or_err_ok", "`clippy::manual_ok_or` covers this case"),
#[clippy::version = "1.86.0"]
("clippy::match_on_vec_items", "`clippy::indexing_slicing` covers indexing and slicing on `Vec<_>`"),
// end deprecated lints. used by `cargo dev deprecate_lint`
]}
#[rustfmt::skip]
declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[
declare_with_version! { RENAMED(RENAMED_VERSION) = [
#[clippy::version = ""]
("clippy::almost_complete_letter_range", "clippy::almost_complete_range"),
#[clippy::version = ""]
@ -187,5 +186,12 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[
("clippy::vtable_address_comparisons", "ambiguous_wide_pointer_comparisons"),
#[clippy::version = ""]
("clippy::reverse_range_loop", "clippy::reversed_empty_ranges"),
// end renamed lints. used by `cargo dev rename_lint`
#[clippy::version = "1.88.0"]
("clippy::transmute_int_to_float", "unnecessary_transmutes"),
#[clippy::version = "1.88.0"]
("clippy::transmute_int_to_char", "unnecessary_transmutes"),
#[clippy::version = "1.88.0"]
("clippy::transmute_float_to_int", "unnecessary_transmutes"),
#[clippy::version = "1.88.0"]
("clippy::transmute_num_to_bytes", "unnecessary_transmutes"),
]}

View file

@ -2,7 +2,7 @@ use std::ops::ControlFlow;
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then, span_lint_hir_and_then};
use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy};
use clippy_utils::{has_non_exhaustive_attr, is_lint_allowed, match_def_path, paths};
use clippy_utils::{has_non_exhaustive_attr, is_lint_allowed, paths};
use rustc_errors::Applicability;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn, walk_item};
@ -377,7 +377,7 @@ fn check_unsafe_derive_deserialize<'tcx>(
}
if let Some(trait_def_id) = trait_ref.trait_def_id()
&& match_def_path(cx, trait_def_id, &paths::SERDE_DESERIALIZE)
&& paths::SERDE_DESERIALIZE.matches(cx, trait_def_id)
&& let ty::Adt(def, _) = ty.kind()
&& let Some(local_def_id) = def.did().as_local()
&& let adt_hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id)

View file

@ -3,6 +3,7 @@ use clippy_config::Conf;
use clippy_config::types::{DisallowedPath, create_disallowed_map};
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
use clippy_utils::macros::macro_backtrace;
use clippy_utils::paths::PathNS;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefIdMap;
@ -76,6 +77,7 @@ impl DisallowedMacros {
let (disallowed, _) = create_disallowed_map(
tcx,
&conf.disallowed_macros,
PathNS::Macro,
|def_kind| matches!(def_kind, DefKind::Macro(_)),
"macro",
false,

View file

@ -1,6 +1,7 @@
use clippy_config::Conf;
use clippy_config::types::{DisallowedPath, create_disallowed_map};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::paths::PathNS;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefIdMap;
use rustc_hir::{Expr, ExprKind};
@ -66,6 +67,7 @@ impl DisallowedMethods {
let (disallowed, _) = create_disallowed_map(
tcx,
&conf.disallowed_methods,
PathNS::Value,
|def_kind| {
matches!(
def_kind,

View file

@ -1,6 +1,7 @@
use clippy_config::Conf;
use clippy_config::types::{DisallowedPath, create_disallowed_map};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::paths::PathNS;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefIdMap;
@ -60,7 +61,14 @@ pub struct DisallowedTypes {
impl DisallowedTypes {
pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
let (def_ids, prim_tys) = create_disallowed_map(tcx, &conf.disallowed_types, def_kind_predicate, "type", true);
let (def_ids, prim_tys) = create_disallowed_map(
tcx,
&conf.disallowed_types,
PathNS::Type,
def_kind_predicate,
"type",
true,
);
Self { def_ids, prim_tys }
}

View file

@ -93,7 +93,7 @@ declare_clippy_lint! {
/// ```no_run
/// //! <code>[first](x)second</code>
/// ```
#[clippy::version = "1.86.0"]
#[clippy::version = "1.87.0"]
pub DOC_LINK_CODE,
nursery,
"link with code back-to-back with other code"

View file

@ -759,12 +759,12 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {
let recv_ty = cx.typeck_results().expr_ty(receiver);
if recv_ty.is_floating_point() && !is_no_std_crate(cx) && is_inherent_method_call(cx, expr) {
match path.ident.name.as_str() {
"ln" => check_ln1p(cx, expr, receiver),
"log" => check_log_base(cx, expr, receiver, args),
"powf" => check_powf(cx, expr, receiver, args),
"powi" => check_powi(cx, expr, receiver, args),
"sqrt" => check_hypot(cx, expr, receiver),
match path.ident.name {
sym::ln => check_ln1p(cx, expr, receiver),
sym::log => check_log_base(cx, expr, receiver, args),
sym::powf => check_powf(cx, expr, receiver, args),
sym::powi => check_powi(cx, expr, receiver, args),
sym::sqrt => check_hypot(cx, expr, receiver),
_ => {},
}
}

View file

@ -9,8 +9,8 @@ mod too_many_arguments;
mod too_many_lines;
use clippy_config::Conf;
use clippy_utils::def_path_def_ids;
use clippy_utils::msrvs::Msrv;
use clippy_utils::paths::{PathNS, lookup_path_str};
use rustc_hir as hir;
use rustc_hir::intravisit;
use rustc_lint::{LateContext, LateLintPass};
@ -469,7 +469,7 @@ impl Functions {
trait_ids: conf
.allow_renamed_params_for
.iter()
.flat_map(|p| def_path_def_ids(tcx, &p.split("::").collect::<Vec<_>>()))
.flat_map(|p| lookup_path_str(tcx, PathNS::Type, p))
.collect(),
msrv: conf.msrv,
}

View file

@ -69,7 +69,7 @@ declare_clippy_lint! {
///
/// let result = a.saturating_sub(b);
/// ```
#[clippy::version = "1.44.0"]
#[clippy::version = "1.83.0"]
pub INVERTED_SATURATING_SUB,
correctness,
"Check if a variable is smaller than another one and still subtract from it even if smaller"

View file

@ -5,7 +5,7 @@ use clippy_utils::macros::span_is_local;
use clippy_utils::source::is_present_in_source;
use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start, to_camel_case, to_snake_case};
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData};
use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, QPath, TyKind, Variant, VariantData};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
use rustc_span::symbol::Symbol;
@ -162,6 +162,7 @@ pub struct ItemNameRepetitions {
enum_threshold: u64,
struct_threshold: u64,
avoid_breaking_exported_api: bool,
allow_exact_repetitions: bool,
allow_private_module_inception: bool,
allowed_prefixes: FxHashSet<String>,
}
@ -173,6 +174,7 @@ impl ItemNameRepetitions {
enum_threshold: conf.enum_variant_name_threshold,
struct_threshold: conf.struct_field_name_threshold,
avoid_breaking_exported_api: conf.avoid_breaking_exported_api,
allow_exact_repetitions: conf.allow_exact_repetitions,
allow_private_module_inception: conf.allow_private_module_inception,
allowed_prefixes: conf.allowed_prefixes.iter().map(|s| to_camel_case(s)).collect(),
}
@ -405,6 +407,7 @@ fn check_enum_start(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>
if count_match_start(item_name, name).char_count == item_name_chars
&& name.chars().nth(item_name_chars).is_some_and(|c| !c.is_lowercase())
&& name.chars().nth(item_name_chars + 1).is_some_and(|c| !c.is_numeric())
&& !check_enum_tuple_path_match(name, variant.data)
{
span_lint_hir(
cx,
@ -420,7 +423,9 @@ fn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>)
let name = variant.ident.name.as_str();
let item_name_chars = item_name.chars().count();
if count_match_end(item_name, name).char_count == item_name_chars {
if count_match_end(item_name, name).char_count == item_name_chars
&& !check_enum_tuple_path_match(name, variant.data)
{
span_lint_hir(
cx,
ENUM_VARIANT_NAMES,
@ -431,6 +436,27 @@ fn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>)
}
}
/// Checks if an enum tuple variant contains a single field
/// whose qualified path contains the variant's name.
fn check_enum_tuple_path_match(variant_name: &str, variant_data: VariantData<'_>) -> bool {
// Only check single-field tuple variants
let VariantData::Tuple(fields, ..) = variant_data else {
return false;
};
if fields.len() != 1 {
return false;
}
// Check if field type is a path and contains the variant name
match fields[0].ty.kind {
TyKind::Path(QPath::Resolved(_, path)) => path
.segments
.iter()
.any(|segment| segment.ident.name.as_str() == variant_name),
TyKind::Path(QPath::TypeRelative(_, segment)) => segment.ident.name.as_str() == variant_name,
_ => false,
}
}
impl LateLintPass<'_> for ItemNameRepetitions {
fn check_item_post(&mut self, _cx: &LateContext<'_>, item: &Item<'_>) {
let Some(_ident) = item.kind.ident() else { return };
@ -462,11 +488,21 @@ impl LateLintPass<'_> for ItemNameRepetitions {
}
// The `module_name_repetitions` lint should only trigger if the item has the module in its
// name. Having the same name is accepted.
if cx.tcx.visibility(item.owner_id).is_public()
&& cx.tcx.visibility(mod_owner_id.def_id).is_public()
&& item_camel.len() > mod_camel.len()
{
// name. Having the same name is only accepted if `allow_exact_repetition` is set to `true`.
let both_are_public =
cx.tcx.visibility(item.owner_id).is_public() && cx.tcx.visibility(mod_owner_id.def_id).is_public();
if both_are_public && !self.allow_exact_repetitions && item_camel == *mod_camel {
span_lint(
cx,
MODULE_NAME_REPETITIONS,
ident.span,
"item name is the same as its containing module's name",
);
}
if both_are_public && item_camel.len() > mod_camel.len() {
let matching = count_match_start(mod_camel, &item_camel);
let rmatching = count_match_end(mod_camel, &item_camel);
let nchars = mod_camel.chars().count();

View file

@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
use clippy_utils::ty::{implements_trait, is_must_use_ty};
use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};
use rustc_hir::{LetStmt, LocalSource, PatKind};
use rustc_lint::{LateContext, LateLintPass};
@ -129,12 +129,6 @@ declare_clippy_lint! {
declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK, LET_UNDERSCORE_FUTURE, LET_UNDERSCORE_UNTYPED]);
const SYNC_GUARD_PATHS: [&[&str]; 3] = [
&paths::PARKING_LOT_MUTEX_GUARD,
&paths::PARKING_LOT_RWLOCK_READ_GUARD,
&paths::PARKING_LOT_RWLOCK_WRITE_GUARD,
];
impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &LetStmt<'tcx>) {
if matches!(local.source, LocalSource::Normal)
@ -144,7 +138,9 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
{
let init_ty = cx.typeck_results().expr_ty(init);
let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
GenericArgKind::Type(inner_ty) => SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path)),
GenericArgKind::Type(inner_ty) => inner_ty
.ty_adt_def()
.is_some_and(|adt| paths::PARKING_LOT_GUARDS.iter().any(|path| path.matches(cx, adt.did()))),
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
});
if contains_sync_guard {

View file

@ -1,5 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro;
use rustc_errors::Applicability;
use rustc_hir::{LetStmt, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;
@ -32,13 +33,19 @@ impl<'tcx> LateLintPass<'tcx> for UnderscoreTyped {
&& !local.span.in_external_macro(cx.tcx.sess.source_map())
&& !is_from_proc_macro(cx, ty)
{
span_lint_and_help(
span_lint_and_then(
cx,
LET_WITH_TYPE_UNDERSCORE,
local.span,
"variable declared with type underscore",
Some(ty.span.with_lo(local.pat.span.hi())),
"remove the explicit type `_` declaration",
|diag| {
diag.span_suggestion_verbose(
ty.span.with_lo(local.pat.span.hi()),
"remove the explicit type `_` declaration",
"",
Applicability::MachineApplicable,
);
},
);
}
}

View file

@ -1,5 +1,4 @@
#![feature(array_windows)]
#![feature(binary_heap_into_iter_sorted)]
#![feature(box_patterns)]
#![feature(macro_metavar_expr_concat)]
#![feature(f128)]
@ -7,7 +6,6 @@
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(iter_partition_in_place)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(round_char_boundary)]
#![feature(rustc_private)]
@ -96,6 +94,7 @@ mod cargo;
mod casts;
mod cfg_not_test;
mod checked_conversions;
mod cloned_ref_to_slice_refs;
mod cognitive_complexity;
mod collapsible_if;
mod collection_is_never_read;
@ -731,7 +730,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_early_pass(|| Box::new(unused_unit::UnusedUnit));
store.register_late_pass(|_| Box::new(unused_unit::UnusedUnit));
store.register_late_pass(|_| Box::new(returns::Return));
store.register_late_pass(move |tcx| Box::new(collapsible_if::CollapsibleIf::new(tcx, conf)));
store.register_late_pass(move |_| Box::new(collapsible_if::CollapsibleIf::new(conf)));
store.register_late_pass(|_| Box::new(items_after_statements::ItemsAfterStatements));
store.register_early_pass(|| Box::new(precedence::Precedence));
store.register_late_pass(|_| Box::new(needless_parens_on_range_literals::NeedlessParensOnRangeLiterals));
@ -748,7 +747,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(move |_| Box::new(unused_self::UnusedSelf::new(conf)));
store.register_late_pass(|_| Box::new(mutable_debug_assertion::DebugAssertWithMutCall));
store.register_late_pass(|_| Box::new(exit::Exit));
store.register_late_pass(|_| Box::new(to_digit_is_some::ToDigitIsSome));
store.register_late_pass(move |_| Box::new(to_digit_is_some::ToDigitIsSome::new(conf)));
store.register_late_pass(move |_| Box::new(large_stack_arrays::LargeStackArrays::new(conf)));
store.register_late_pass(move |_| Box::new(large_const_arrays::LargeConstArrays::new(conf)));
store.register_late_pass(|_| Box::new(floating_point_arithmetic::FloatingPointArithmetic));
@ -944,5 +943,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(|_| Box::new(manual_option_as_slice::ManualOptionAsSlice::new(conf)));
store.register_late_pass(|_| Box::new(single_option_map::SingleOptionMap));
store.register_late_pass(move |_| Box::new(redundant_test_prefix::RedundantTestPrefix));
store.register_late_pass(|_| Box::new(cloned_ref_to_slice_refs::ClonedRefToSliceRefs::new(conf)));
// add lints here, do not remove this comment, it's used in `new_lint`
}

View file

@ -88,7 +88,7 @@ declare_clippy_lint! {
/// x.chars()
/// }
/// ```
#[clippy::version = "1.84.0"]
#[clippy::version = "1.87.0"]
pub ELIDABLE_LIFETIME_NAMES,
pedantic,
"lifetime name that can be replaced with the anonymous lifetime"

Some files were not shown because too many files have changed in this diff Show more