Merge from rustc

This commit is contained in:
Ralf Jung 2025-01-08 09:23:40 +01:00
commit 2d180714e1
1351 changed files with 53386 additions and 14824 deletions

View file

@ -1,7 +1,5 @@
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
use std::path::PathBuf;
use crate::core::build_steps::compile::{
add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make,
};
@ -10,7 +8,8 @@ use crate::core::builder::{
self, Alias, Builder, Kind, RunConfig, ShouldRun, Step, crate_description,
};
use crate::core::config::TargetSelection;
use crate::{Compiler, Mode, Subcommand};
use crate::utils::build_stamp::{self, BuildStamp};
use crate::{Mode, Subcommand};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Std {
@ -83,22 +82,16 @@ impl Step for Std {
format_args!("library artifacts{}", crate_description(&self.crates)),
target,
);
run_cargo(
builder,
cargo,
builder.config.free_args.clone(),
&libstd_stamp(builder, compiler, target),
vec![],
true,
false,
);
let stamp = build_stamp::libstd_stamp(builder, compiler, target).with_prefix("check");
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
// We skip populating the sysroot in non-zero stage because that'll lead
// to rlib/rmeta conflicts if std gets built during this session.
if compiler.stage == 0 {
let libdir = builder.sysroot_target_libdir(compiler, target);
let hostdir = builder.sysroot_target_libdir(compiler, compiler.host);
add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
add_to_sysroot(builder, &libdir, &hostdir, &stamp);
}
drop(_guard);
@ -139,16 +132,9 @@ impl Step for Std {
cargo.arg("-p").arg(krate);
}
let stamp = build_stamp::libstd_stamp(builder, compiler, target).with_prefix("check-test");
let _guard = builder.msg_check("library test/bench/example targets", target);
run_cargo(
builder,
cargo,
builder.config.free_args.clone(),
&libstd_test_stamp(builder, compiler, target),
vec![],
true,
false,
);
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
}
}
@ -249,19 +235,14 @@ impl Step for Rustc {
format_args!("compiler artifacts{}", crate_description(&self.crates)),
target,
);
run_cargo(
builder,
cargo,
builder.config.free_args.clone(),
&librustc_stamp(builder, compiler, target),
vec![],
true,
false,
);
let stamp = build_stamp::librustc_stamp(builder, compiler, target).with_prefix("check");
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
let libdir = builder.sysroot_target_libdir(compiler, target);
let hostdir = builder.sysroot_target_libdir(compiler, compiler.host);
add_to_sysroot(builder, &libdir, &hostdir, &librustc_stamp(builder, compiler, target));
add_to_sysroot(builder, &libdir, &hostdir, &stamp);
}
}
@ -315,15 +296,10 @@ impl Step for CodegenBackend {
let _guard = builder.msg_check(backend, target);
run_cargo(
builder,
cargo,
builder.config.free_args.clone(),
&codegen_backend_stamp(builder, compiler, target, backend),
vec![],
true,
false,
);
let stamp = build_stamp::codegen_backend_stamp(builder, compiler, target, backend)
.with_prefix("check");
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
}
}
@ -344,7 +320,7 @@ impl Step for RustAnalyzer {
.config
.tools
.as_ref()
.map_or(true, |tools| tools.iter().any(|tool| tool == "rust-analyzer")),
.is_none_or(|tools| tools.iter().any(|tool| tool == "rust-analyzer")),
)
}
@ -380,22 +356,13 @@ impl Step for RustAnalyzer {
cargo.arg("--benches");
}
let _guard = builder.msg_check("rust-analyzer artifacts", target);
run_cargo(
builder,
cargo,
builder.config.free_args.clone(),
&stamp(builder, compiler, target),
vec![],
true,
false,
);
// Cargo's output path in a given stage, compiled by a particular
// compiler for the specified target.
let stamp = BuildStamp::new(&builder.cargo_out(compiler, Mode::ToolRustc, target))
.with_prefix("rust-analyzer-check");
/// Cargo's output path in a given stage, compiled by a particular
/// compiler for the specified target.
fn stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
builder.cargo_out(compiler, Mode::ToolRustc, target).join(".rust-analyzer-check.stamp")
}
let _guard = builder.msg_check("rust-analyzer artifacts", target);
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
}
}
@ -469,9 +436,8 @@ fn run_tool_check_step(
cargo.arg("--all-targets");
}
let stamp = builder
.cargo_out(compiler, Mode::ToolRustc, target)
.join(format!(".{}-check.stamp", step_type_name.to_lowercase()));
let stamp = BuildStamp::new(&builder.cargo_out(compiler, Mode::ToolRustc, target))
.with_prefix(&format!("{}-check", step_type_name.to_lowercase()));
let _guard = builder.msg_check(format!("{display_name} artifacts"), target);
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
@ -499,38 +465,3 @@ tool_check_step!(RunMakeSupport { path: "src/tools/run-make-support", default: f
// Compiletest is implicitly "checked" when it gets built in order to run tests,
// so this is mainly for people working on compiletest to run locally.
tool_check_step!(Compiletest { path: "src/tools/compiletest", default: false });
/// Cargo's output path for the standard library in a given stage, compiled
/// by a particular compiler for the specified target.
fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
}
/// Cargo's output path for the standard library in a given stage, compiled
/// by a particular compiler for the specified target.
fn libstd_test_stamp(
builder: &Builder<'_>,
compiler: Compiler,
target: TargetSelection,
) -> PathBuf {
builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check-test.stamp")
}
/// Cargo's output path for librustc in a given stage, compiled by a particular
/// compiler for the specified target.
fn librustc_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc-check.stamp")
}
/// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
/// compiler for the specified target and backend.
fn codegen_backend_stamp(
builder: &Builder<'_>,
compiler: Compiler,
target: TargetSelection,
backend: &str,
) -> PathBuf {
builder
.cargo_out(compiler, Mode::Codegen, target)
.join(format!(".librustc_codegen_{backend}-check.stamp"))
}

View file

@ -10,6 +10,7 @@ use std::io::{self, ErrorKind};
use std::path::Path;
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step, crate_description};
use crate::utils::build_stamp::BuildStamp;
use crate::utils::helpers::t;
use crate::{Build, Compiler, Kind, Mode, Subcommand};
@ -146,7 +147,7 @@ fn clean_default(build: &Build) {
rm_rf(&build.out.join("dist"));
rm_rf(&build.out.join("bootstrap").join(".last-warned-change-id"));
rm_rf(&build.out.join("bootstrap-shims-dump"));
rm_rf(&build.out.join("rustfmt.stamp"));
rm_rf(BuildStamp::new(&build.out).with_prefix("rustfmt").path());
let mut hosts: Vec<_> = build.hosts.iter().map(|t| build.out.join(t)).collect();
// After cross-compilation, artifacts of the host architecture (which may differ from build.host)

View file

@ -1,12 +1,13 @@
//! Implementation of running clippy on the compiler, standard library and various tools.
use super::compile::{librustc_stamp, libstd_stamp, run_cargo, rustc_cargo, std_cargo};
use super::compile::{run_cargo, rustc_cargo, std_cargo};
use super::tool::{SourceType, prepare_tool_cargo};
use super::{check, compile};
use crate::builder::{Builder, ShouldRun};
use crate::core::build_steps::compile::std_crates_for_run_make;
use crate::core::builder;
use crate::core::builder::{Alias, Kind, RunConfig, Step, crate_description};
use crate::utils::build_stamp::{self, BuildStamp};
use crate::{Mode, Subcommand, TargetSelection};
/// Disable the most spammy clippy lints
@ -167,7 +168,7 @@ impl Step for Std {
builder,
cargo,
lint_args(builder, &self.config, IGNORED_RULES_FOR_STD_AND_RUSTC),
&libstd_stamp(builder, compiler, target),
&build_stamp::libstd_stamp(builder, compiler, target),
vec![],
true,
false,
@ -243,7 +244,7 @@ impl Step for Rustc {
builder,
cargo,
lint_args(builder, &self.config, IGNORED_RULES_FOR_STD_AND_RUSTC),
&librustc_stamp(builder, compiler, target),
&build_stamp::librustc_stamp(builder, compiler, target),
vec![],
true,
false,
@ -307,9 +308,9 @@ macro_rules! lint_any {
&target,
);
let stamp = builder
.cargo_out(compiler, Mode::ToolRustc, target)
.join(format!(".{}-check.stamp", stringify!($name).to_lowercase()));
let stringified_name = stringify!($name).to_lowercase();
let stamp = BuildStamp::new(&builder.cargo_out(compiler, Mode::ToolRustc, target))
.with_prefix(&format!("{}-check", stringified_name));
run_cargo(
builder,

View file

@ -24,6 +24,8 @@ use crate::core::builder::{
Builder, Cargo, Kind, PathSet, RunConfig, ShouldRun, Step, TaskPath, crate_description,
};
use crate::core::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection};
use crate::utils::build_stamp;
use crate::utils::build_stamp::BuildStamp;
use crate::utils::exec::command;
use crate::utils::helpers::{
exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date,
@ -254,7 +256,7 @@ impl Step for Std {
builder,
cargo,
vec![],
&libstd_stamp(builder, compiler, target),
&build_stamp::libstd_stamp(builder, compiler, target),
target_deps,
self.is_for_mir_opt_tests, // is_check
false,
@ -469,7 +471,7 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
// If `compiler-rt` is available ensure that the `c` feature of the
// `compiler-builtins` crate is enabled and it's configured to learn where
// `compiler-rt` is located.
let compiler_builtins_c_feature = if builder.config.optimized_compiler_builtins {
let compiler_builtins_c_feature = if builder.config.optimized_compiler_builtins(target) {
// NOTE: this interacts strangely with `llvm-has-rust-patches`. In that case, we enforce `submodules = false`, so this is a no-op.
// But, the user could still decide to manually use an in-tree submodule.
//
@ -644,7 +646,12 @@ impl Step for StdLink {
(libdir, hostdir)
};
add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
add_to_sysroot(
builder,
&libdir,
&hostdir,
&build_stamp::libstd_stamp(builder, compiler, target),
);
// Special case for stage0, to make `rustup toolchain link` and `x dist --stage 0`
// work for stage0-sysroot. We only do this if the stage0 compiler comes from beta,
@ -973,7 +980,7 @@ impl Step for Rustc {
compiler.host,
target,
);
let stamp = librustc_stamp(builder, compiler, target);
let stamp = build_stamp::librustc_stamp(builder, compiler, target);
run_cargo(
builder,
cargo,
@ -984,7 +991,7 @@ impl Step for Rustc {
true, // Only ship rustc_driver.so and .rmeta files, not all intermediate .rlib files.
);
let target_root_dir = stamp.parent().unwrap();
let target_root_dir = stamp.path().parent().unwrap();
// When building `librustc_driver.so` (like `libLLVM.so`) on linux, it can contain
// unexpected debuginfo from dependencies, for example from the C++ standard library used in
// our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with
@ -1207,6 +1214,15 @@ pub fn rustc_cargo_env(
rustc_llvm_env(builder, cargo, target)
}
}
// Build jemalloc on AArch64 with support for page sizes up to 64K
// See: https://github.com/rust-lang/rust/pull/135081
if builder.config.jemalloc
&& target.starts_with("aarch64")
&& env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none()
{
cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16");
}
}
/// Pass down configuration from the LLVM build into the build of
@ -1320,7 +1336,7 @@ impl Step for RustcLink {
builder,
&builder.sysroot_target_libdir(previous_stage_compiler, target),
&builder.sysroot_target_libdir(previous_stage_compiler, compiler.host),
&librustc_stamp(builder, compiler, target),
&build_stamp::librustc_stamp(builder, compiler, target),
);
}
}
@ -1438,7 +1454,7 @@ impl Step for CodegenBackend {
.arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
rustc_cargo_env(builder, &mut cargo, target, compiler.stage);
let tmp_stamp = out_dir.join(".tmp.stamp");
let tmp_stamp = BuildStamp::new(&out_dir).with_prefix("tmp");
let _guard = builder.msg_build(compiler, format_args!("codegen backend {backend}"), target);
let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false, false);
@ -1460,9 +1476,9 @@ impl Step for CodegenBackend {
f.display()
);
}
let stamp = codegen_backend_stamp(builder, compiler, target, &backend);
let stamp = build_stamp::codegen_backend_stamp(builder, compiler, target, &backend);
let codegen_backend = codegen_backend.to_str().unwrap();
t!(fs::write(stamp, codegen_backend));
t!(stamp.add_stamp(codegen_backend).write());
}
}
@ -1499,8 +1515,8 @@ fn copy_codegen_backends_to_sysroot(
continue; // Already built as part of rustc
}
let stamp = codegen_backend_stamp(builder, compiler, target, backend);
let dylib = t!(fs::read_to_string(&stamp));
let stamp = build_stamp::codegen_backend_stamp(builder, compiler, target, backend);
let dylib = t!(fs::read_to_string(stamp.path()));
let file = Path::new(&dylib);
let filename = file.file_name().unwrap().to_str().unwrap();
// change `librustc_codegen_cranelift-xxxxxx.so` to
@ -1514,35 +1530,6 @@ fn copy_codegen_backends_to_sysroot(
}
}
/// Cargo's output path for the standard library in a given stage, compiled
/// by a particular compiler for the specified target.
pub fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
builder.cargo_out(compiler, Mode::Std, target).join(".libstd.stamp")
}
/// Cargo's output path for librustc in a given stage, compiled by a particular
/// compiler for the specified target.
pub fn librustc_stamp(
builder: &Builder<'_>,
compiler: Compiler,
target: TargetSelection,
) -> PathBuf {
builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc.stamp")
}
/// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
/// compiler for the specified target and backend.
fn codegen_backend_stamp(
builder: &Builder<'_>,
compiler: Compiler,
target: TargetSelection,
backend: &str,
) -> PathBuf {
builder
.cargo_out(compiler, Mode::Codegen, target)
.join(format!(".librustc_codegen_{backend}.stamp"))
}
pub fn compiler_file(
builder: &Builder<'_>,
compiler: &Path,
@ -1664,10 +1651,10 @@ impl Step for Sysroot {
];
let ci_rustc_dir = builder.config.ci_rustc_dir();
builder.cp_link_filtered(&ci_rustc_dir, &sysroot, &|path| {
if path.extension().map_or(true, |ext| !filtered_extensions.contains(&ext)) {
if path.extension().is_none_or(|ext| !filtered_extensions.contains(&ext)) {
return true;
}
if !path.parent().map_or(true, |p| p.ends_with(&suffix)) {
if !path.parent().is_none_or(|p| p.ends_with(&suffix)) {
return true;
}
if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) {
@ -1899,7 +1886,7 @@ impl Step for Assemble {
builder.info(&msg);
// Link in all dylibs to the libdir
let stamp = librustc_stamp(builder, build_compiler, target_compiler.host);
let stamp = build_stamp::librustc_stamp(builder, build_compiler, target_compiler.host);
let proc_macros = builder
.read_stamp_file(&stamp)
.into_iter()
@ -2005,7 +1992,7 @@ pub fn add_to_sysroot(
builder: &Builder<'_>,
sysroot_dst: &Path,
sysroot_host_dst: &Path,
stamp: &Path,
stamp: &BuildStamp,
) {
let self_contained_dst = &sysroot_dst.join("self-contained");
t!(fs::create_dir_all(sysroot_dst));
@ -2025,13 +2012,13 @@ pub fn run_cargo(
builder: &Builder<'_>,
cargo: Cargo,
tail_args: Vec<String>,
stamp: &Path,
stamp: &BuildStamp,
additional_target_deps: Vec<(PathBuf, DependencyType)>,
is_check: bool,
rlib_only_metadata: bool,
) -> Vec<PathBuf> {
// `target_root_dir` looks like $dir/$target/release
let target_root_dir = stamp.parent().unwrap();
let target_root_dir = stamp.path().parent().unwrap();
// `target_deps_dir` looks like $dir/$target/release/deps
let target_deps_dir = target_root_dir.join("deps");
// `host_root_dir` looks like $dir/release
@ -2184,7 +2171,7 @@ pub fn run_cargo(
new_contents.extend(dep.to_str().unwrap().as_bytes());
new_contents.extend(b"\0");
}
t!(fs::write(stamp, &new_contents));
t!(fs::write(stamp.path(), &new_contents));
deps.into_iter().map(|(d, _)| d).collect()
}

View file

@ -23,6 +23,7 @@ use crate::core::build_steps::vendor::default_paths_to_vendor;
use crate::core::build_steps::{compile, llvm};
use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
use crate::core::config::TargetSelection;
use crate::utils::build_stamp::{self, BuildStamp};
use crate::utils::channel::{self, Info};
use crate::utils::exec::{BootstrapCommand, command};
use crate::utils::helpers::{
@ -47,7 +48,7 @@ fn should_build_extended_tool(builder: &Builder<'_>, tool: &str) -> bool {
if !builder.config.extended {
return false;
}
builder.config.tools.as_ref().map_or(true, |tools| tools.contains(tool))
builder.config.tools.as_ref().is_none_or(|tools| tools.contains(tool))
}
#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
@ -410,7 +411,7 @@ impl Step for Rustc {
.config
.tools
.as_ref()
.map_or(true, |tools| tools.iter().any(|tool| tool == "rustdoc"))
.is_none_or(|tools| tools.iter().any(|tool| tool == "rustdoc"))
{
let rustdoc = builder.rustdoc(compiler);
builder.install(&rustdoc, &image.join("bin"), 0o755);
@ -584,7 +585,7 @@ fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
/// Check that all objects in rlibs for UEFI targets are COFF. This
/// ensures that the C compiler isn't producing ELF objects, which would
/// not link correctly with the COFF objects.
fn verify_uefi_rlib_format(builder: &Builder<'_>, target: TargetSelection, stamp: &Path) {
fn verify_uefi_rlib_format(builder: &Builder<'_>, target: TargetSelection, stamp: &BuildStamp) {
if !target.ends_with("-uefi") {
return;
}
@ -615,7 +616,12 @@ fn verify_uefi_rlib_format(builder: &Builder<'_>, target: TargetSelection, stamp
}
/// Copy stamped files into an image's `target/lib` directory.
fn copy_target_libs(builder: &Builder<'_>, target: TargetSelection, image: &Path, stamp: &Path) {
fn copy_target_libs(
builder: &Builder<'_>,
target: TargetSelection,
image: &Path,
stamp: &BuildStamp,
) {
let dst = image.join("lib/rustlib").join(target).join("lib");
let self_contained_dst = dst.join("self-contained");
t!(fs::create_dir_all(&dst));
@ -668,7 +674,7 @@ impl Step for Std {
tarball.include_target_in_component_name(true);
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
let stamp = compile::libstd_stamp(builder, compiler_to_use, target);
let stamp = build_stamp::libstd_stamp(builder, compiler_to_use, target);
verify_uefi_rlib_format(builder, target, &stamp);
copy_target_libs(builder, target, tarball.image_dir(), &stamp);
@ -718,7 +724,7 @@ impl Step for RustcDev {
let tarball = Tarball::new(builder, "rustc-dev", &target.triple);
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
let stamp = compile::librustc_stamp(builder, compiler_to_use, target);
let stamp = build_stamp::librustc_stamp(builder, compiler_to_use, target);
copy_target_libs(builder, target, tarball.image_dir(), &stamp);
let src_files = &["Cargo.lock"];
@ -1592,15 +1598,9 @@ impl Step for Extended {
prepare("cargo");
prepare("rust-std");
prepare("rust-analysis");
for tool in &[
"clippy",
"rustfmt",
"rust-analyzer",
"rust-docs",
"miri",
"rustc-codegen-cranelift",
] {
prepare("clippy");
prepare("rust-analyzer");
for tool in &["rust-docs", "miri", "rustc-codegen-cranelift"] {
if built_tools.contains(tool) {
prepare(tool);
}
@ -1640,8 +1640,6 @@ impl Step for Extended {
"rust-analyzer-preview".to_string()
} else if name == "clippy" {
"clippy-preview".to_string()
} else if name == "rustfmt" {
"rustfmt-preview".to_string()
} else if name == "miri" {
"miri-preview".to_string()
} else if name == "rustc-codegen-cranelift" {
@ -1661,7 +1659,7 @@ impl Step for Extended {
prepare("cargo");
prepare("rust-analysis");
prepare("rust-std");
for tool in &["clippy", "rustfmt", "rust-analyzer", "rust-docs", "miri"] {
for tool in &["clippy", "rust-analyzer", "rust-docs", "miri"] {
if built_tools.contains(tool) {
prepare(tool);
}
@ -1779,24 +1777,6 @@ impl Step for Extended {
.arg(etc.join("msi/remove-duplicates.xsl"))
.run(builder);
}
if built_tools.contains("rustfmt") {
command(&heat)
.current_dir(&exe)
.arg("dir")
.arg("rustfmt")
.args(heat_flags)
.arg("-cg")
.arg("RustFmtGroup")
.arg("-dr")
.arg("RustFmt")
.arg("-var")
.arg("var.RustFmtDir")
.arg("-out")
.arg(exe.join("RustFmtGroup.wxs"))
.arg("-t")
.arg(etc.join("msi/remove-duplicates.xsl"))
.run(builder);
}
if built_tools.contains("miri") {
command(&heat)
.current_dir(&exe)
@ -1868,9 +1848,6 @@ impl Step for Extended {
if built_tools.contains("clippy") {
cmd.arg("-dClippyDir=clippy");
}
if built_tools.contains("rustfmt") {
cmd.arg("-dRustFmtDir=rustfmt");
}
if built_tools.contains("rust-docs") {
cmd.arg("-dDocsDir=rust-docs");
}
@ -1897,9 +1874,6 @@ impl Step for Extended {
if built_tools.contains("clippy") {
candle("ClippyGroup.wxs".as_ref());
}
if built_tools.contains("rustfmt") {
candle("RustFmtGroup.wxs".as_ref());
}
if built_tools.contains("miri") {
candle("MiriGroup.wxs".as_ref());
}
@ -1938,9 +1912,6 @@ impl Step for Extended {
if built_tools.contains("clippy") {
cmd.arg("ClippyGroup.wixobj");
}
if built_tools.contains("rustfmt") {
cmd.arg("RustFmtGroup.wixobj");
}
if built_tools.contains("miri") {
cmd.arg("MiriGroup.wixobj");
}

View file

@ -11,8 +11,9 @@ use build_helper::git::get_git_modified_files;
use ignore::WalkBuilder;
use crate::core::builder::Builder;
use crate::utils::build_stamp::BuildStamp;
use crate::utils::exec::command;
use crate::utils::helpers::{self, program_out_of_date, t};
use crate::utils::helpers::{self, t};
#[must_use]
enum RustfmtStatus {
@ -55,8 +56,8 @@ fn rustfmt(
}
}
fn get_rustfmt_version(build: &Builder<'_>) -> Option<(String, PathBuf)> {
let stamp_file = build.out.join("rustfmt.stamp");
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()?);
cmd.arg("--version");
@ -73,7 +74,7 @@ fn verify_rustfmt_version(build: &Builder<'_>) -> bool {
let Some((version, stamp_file)) = get_rustfmt_version(build) else {
return false;
};
!program_out_of_date(&stamp_file, &version)
stamp_file.add_stamp(version).is_up_to_date()
}
/// Updates the last rustfmt version used.
@ -81,7 +82,7 @@ fn update_rustfmt_version(build: &Builder<'_>) {
let Some((version, stamp_file)) = get_rustfmt_version(build) else {
return;
};
t!(std::fs::write(stamp_file, version))
t!(std::fs::write(stamp_file.path(), version))
}
/// Returns the Rust files modified between the `merge-base` of HEAD and
@ -114,6 +115,9 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
} else {
println!("fmt: {verb} {len} {adjective}files");
}
if len > 1000 && !CiEnv::is_ci() {
println!("hint: if this number seems too high, try running `git fetch origin master");
}
}
pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {

View file

@ -12,14 +12,15 @@ use std::fs;
use std::path::PathBuf;
use std::sync::OnceLock;
use crate::Kind;
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::core::config::TargetSelection;
use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash};
use crate::utils::exec::command;
use crate::utils::helpers::{self, HashStamp, t};
use crate::{Kind, generate_smart_stamp_hash};
use crate::utils::helpers::{self, t};
pub struct Meta {
stamp: HashStamp,
stamp: BuildStamp,
out_dir: PathBuf,
install_dir: PathBuf,
root: PathBuf,
@ -54,18 +55,17 @@ pub fn prebuilt_gcc_config(builder: &Builder<'_>, target: TargetSelection) -> Gc
)
});
let stamp = out_dir.join("gcc-finished-building");
let stamp = HashStamp::new(stamp, Some(smart_stamp_hash));
let stamp = BuildStamp::new(&out_dir).with_prefix("gcc").add_stamp(smart_stamp_hash);
if stamp.is_done() {
if stamp.hash.is_none() {
if stamp.is_up_to_date() {
if stamp.stamp().is_empty() {
builder.info(
"Could not determine the GCC submodule commit hash. \
Assuming that an GCC rebuild is not necessary.",
);
builder.info(&format!(
"To force GCC to rebuild, remove the file `{}`",
stamp.path.display()
stamp.path().display()
));
}
return GccBuildStatus::AlreadyBuilt;

View file

@ -307,7 +307,7 @@ impl Step for Src {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let config = &run.builder.config;
let cond = config.extended && config.tools.as_ref().map_or(true, |t| t.contains("src"));
let cond = config.extended && config.tools.as_ref().is_none_or(|t| t.contains("src"));
run.path("src").default_condition(cond)
}

View file

@ -8,23 +8,23 @@
//! LLVM and compiler-rt are essentially just wired up to everything else to
//! ensure that they're always in place if needed.
use std::env;
use std::env::consts::EXE_EXTENSION;
use std::ffi::{OsStr, OsString};
use std::fs::{self, File};
use std::path::{Path, PathBuf};
use std::sync::OnceLock;
use std::{env, fs};
use build_helper::ci::CiEnv;
use build_helper::git::get_closest_merge_commit;
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::core::config::{Config, TargetSelection};
use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash};
use crate::utils::exec::command;
use crate::utils::helpers::{
self, HashStamp, exe, get_clang_cl_resource_dir, t, unhashed_basename, up_to_date,
self, exe, get_clang_cl_resource_dir, t, unhashed_basename, up_to_date,
};
use crate::{CLang, GitRepo, Kind, generate_smart_stamp_hash};
use crate::{CLang, GitRepo, Kind};
#[derive(Clone)]
pub struct LlvmResult {
@ -36,7 +36,7 @@ pub struct LlvmResult {
}
pub struct Meta {
stamp: HashStamp,
stamp: BuildStamp,
res: LlvmResult,
out_dir: PathBuf,
root: String,
@ -135,18 +135,17 @@ pub fn prebuilt_llvm_config(
)
});
let stamp = out_dir.join("llvm-finished-building");
let stamp = HashStamp::new(stamp, Some(smart_stamp_hash));
let stamp = BuildStamp::new(&out_dir).with_prefix("llvm").add_stamp(smart_stamp_hash);
if stamp.is_done() {
if stamp.hash.is_none() {
if stamp.is_up_to_date() {
if stamp.stamp().is_empty() {
builder.info(
"Could not determine the LLVM submodule commit hash. \
Assuming that an LLVM rebuild is not necessary.",
);
builder.info(&format!(
"To force LLVM to rebuild, remove the file `{}`",
stamp.path.display()
stamp.path().display()
));
}
return LlvmBuildStatus::AlreadyBuilt(res);
@ -922,18 +921,17 @@ impl Step for Enzyme {
});
let out_dir = builder.enzyme_out(target);
let stamp = out_dir.join("enzyme-finished-building");
let stamp = HashStamp::new(stamp, Some(smart_stamp_hash));
let stamp = BuildStamp::new(&out_dir).with_prefix("enzyme").add_stamp(smart_stamp_hash);
if stamp.is_done() {
if stamp.hash.is_none() {
if stamp.is_up_to_date() {
if stamp.stamp().is_empty() {
builder.info(
"Could not determine the Enzyme submodule commit hash. \
Assuming that an Enzyme rebuild is not necessary.",
);
builder.info(&format!(
"To force Enzyme to rebuild, remove the file `{}`",
stamp.path.display()
stamp.path().display()
));
}
return out_dir;
@ -1016,8 +1014,9 @@ impl Step for Lld {
}
let out_dir = builder.lld_out(target);
let done_stamp = out_dir.join("lld-finished-building");
if done_stamp.exists() {
let lld_stamp = BuildStamp::new(&out_dir).with_prefix("lld");
if lld_stamp.path().exists() {
return out_dir;
}
@ -1092,7 +1091,7 @@ impl Step for Lld {
cfg.build();
t!(File::create(&done_stamp));
t!(lld_stamp.write());
out_dir
}
}
@ -1122,25 +1121,32 @@ impl Step for Sanitizers {
let out_dir = builder.native_dir(self.target).join("sanitizers");
let runtimes = supported_sanitizers(&out_dir, self.target, &builder.config.channel);
if runtimes.is_empty() {
if builder.config.dry_run() || runtimes.is_empty() {
return runtimes;
}
let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: builder.config.build });
if builder.config.dry_run() {
return runtimes;
}
let stamp = out_dir.join("sanitizers-finished-building");
let stamp = HashStamp::new(stamp, builder.in_tree_llvm_info.sha());
static STAMP_HASH_MEMO: OnceLock<String> = OnceLock::new();
let smart_stamp_hash = STAMP_HASH_MEMO.get_or_init(|| {
generate_smart_stamp_hash(
builder,
&builder.config.src.join("src/llvm-project/compiler-rt"),
builder.in_tree_llvm_info.sha().unwrap_or_default(),
)
});
if stamp.is_done() {
if stamp.hash.is_none() {
let stamp = BuildStamp::new(&out_dir).with_prefix("sanitizers").add_stamp(smart_stamp_hash);
if stamp.is_up_to_date() {
if stamp.stamp().is_empty() {
builder.info(&format!(
"Rebuild sanitizers by removing the file `{}`",
stamp.path.display()
stamp.path().display()
));
}
return runtimes;
}

View file

@ -21,16 +21,18 @@ use crate::core::builder::{
};
use crate::core::config::TargetSelection;
use crate::core::config::flags::{Subcommand, get_completion};
use crate::utils::build_stamp::{self, BuildStamp};
use crate::utils::exec::{BootstrapCommand, command};
use crate::utils::helpers::{
self, LldThreads, add_link_lib_path, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var,
linker_args, linker_flags, t, target_supports_cranelift_backend, up_to_date,
};
use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests};
use crate::{CLang, DocTests, GitRepo, Mode, envify};
use crate::{CLang, DocTests, GitRepo, Mode, PathSet, envify};
const ADB_TEST_DIR: &str = "/data/local/tmp/work";
/// Runs `cargo test` on various internal tools used by bootstrap.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CrateBootstrap {
path: PathBuf,
@ -43,13 +45,21 @@ impl Step for CrateBootstrap {
const DEFAULT: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
// This step is responsible for several different tool paths. By default
// it will test all of them, but requesting specific tools on the
// command-line (e.g. `./x test suggest-tests`) will test only the
// specified tools.
run.path("src/tools/jsondoclint")
.path("src/tools/suggest-tests")
.path("src/tools/replace-version-placeholder")
// We want `./x test tidy` to _run_ the tidy tool, not its tests.
// So we need a separate alias to test the tidy tool itself.
.alias("tidyselftest")
}
fn make_run(run: RunConfig<'_>) {
// Create and ensure a separate instance of this step for each path
// that was selected on the command-line (or selected by default).
for path in run.paths {
let path = path.assert_single_path().path.clone();
run.builder.ensure(CrateBootstrap { host: run.target, path });
@ -60,6 +70,8 @@ impl Step for CrateBootstrap {
let bootstrap_host = builder.config.build;
let compiler = builder.compiler(0, bootstrap_host);
let mut path = self.path.to_str().unwrap();
// Map alias `tidyselftest` back to the actual crate path of tidy.
if path == "tidyselftest" {
path = "src/tools/tidy";
}
@ -212,6 +224,9 @@ impl Step for HtmlCheck {
}
}
/// Builds cargo and then runs the `src/tools/cargotest` tool, which checks out
/// some representative crate repositories and runs `cargo test` on them, in
/// order to test cargo.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Cargotest {
stage: u32,
@ -257,6 +272,7 @@ impl Step for Cargotest {
}
}
/// Runs `cargo test` for cargo itself.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Cargo {
stage: u32,
@ -385,6 +401,7 @@ impl Step for RustAnalyzer {
}
}
/// Runs `cargo test` for rustfmt.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Rustfmt {
stage: u32,
@ -528,7 +545,7 @@ impl Step for Miri {
// The mtime of `miri_sysroot` changes when the sysroot gets rebuilt (also see
// <https://github.com/RalfJung/rustc-build-sysroot/commit/10ebcf60b80fe2c3dc765af0ff19fdc0da4b7466>).
// We can hence use that directly as a signal to clear the ui test dir.
builder.clear_if_dirty(&ui_test_dep_dir, &miri_sysroot);
build_stamp::clear_if_dirty(builder, &ui_test_dep_dir, &miri_sysroot);
}
// Run `cargo test`.
@ -589,6 +606,8 @@ impl Step for Miri {
}
}
/// Runs `cargo miri test` to demonstrate that `src/tools/miri/cargo-miri`
/// works and that libtest works under miri.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CargoMiri {
target: TargetSelection,
@ -963,7 +982,7 @@ impl Step for RustdocGUI {
let mut cmd = builder.tool_cmd(Tool::RustdocGUITest);
let out_dir = builder.test_out(self.target).join("rustdoc-gui");
builder.clear_if_dirty(&out_dir, &builder.rustdoc(self.compiler));
build_stamp::clear_if_dirty(builder, &out_dir, &builder.rustdoc(self.compiler));
if let Some(src) = builder.config.src.to_str() {
cmd.arg("--rust-src").arg(src);
@ -1020,6 +1039,10 @@ impl Step for RustdocGUI {
}
}
/// Runs `src/tools/tidy` and `cargo fmt --check` to detect various style
/// problems in the repository.
///
/// (To run the tidy tool's internal tests, use the alias "tidyselftest" instead.)
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Tidy;
@ -1185,53 +1208,6 @@ macro_rules! test {
};
}
/// Declares an alias for running the [`Coverage`] tests in only one mode.
/// Adapted from [`test`].
macro_rules! coverage_test_alias {
(
$( #[$attr:meta] )* // allow docstrings and attributes
$name:ident {
alias_and_mode: $alias_and_mode:expr, // &'static str
default: $default:expr, // bool
only_hosts: $only_hosts:expr // bool
$( , )? // optional trailing comma
}
) => {
$( #[$attr] )*
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct $name {
pub compiler: Compiler,
pub target: TargetSelection,
}
impl $name {
const MODE: &'static str = $alias_and_mode;
}
impl Step for $name {
type Output = ();
const DEFAULT: bool = $default;
const ONLY_HOSTS: bool = $only_hosts;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
// Register the mode name as a command-line alias.
// This allows `x test coverage-map` and `x test coverage-run`.
run.alias($alias_and_mode)
}
fn make_run(run: RunConfig<'_>) {
let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
run.builder.ensure($name { compiler, target: run.target });
}
fn run(self, builder: &Builder<'_>) {
Coverage::run_coverage_tests(builder, self.compiler, self.target, Self::MODE);
}
}
};
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
pub struct RunMakeSupport {
pub compiler: Compiler,
@ -1277,6 +1253,8 @@ impl Step for RunMakeSupport {
}
}
/// Runs `cargo test` on the `src/tools/run-make-support` crate.
/// That crate is used by run-make tests.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CrateRunMakeSupport {
host: TargetSelection,
@ -1473,44 +1451,88 @@ impl Step for RunMake {
test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly", default: true });
/// Coverage tests are a bit more complicated than other test suites, because
/// we want to run the same set of test files in multiple different modes,
/// in a way that's convenient and flexible when invoked manually.
///
/// This combined step runs the specified tests (or all of `tests/coverage`)
/// in both "coverage-map" and "coverage-run" modes.
///
/// Used by:
/// - `x test coverage`
/// - `x test tests/coverage`
/// - `x test tests/coverage/trivial.rs` (etc)
///
/// (Each individual mode also has its own step that will run the tests in
/// just that mode.)
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
/// Runs the coverage test suite at `tests/coverage` in some or all of the
/// coverage test modes.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Coverage {
pub compiler: Compiler,
pub target: TargetSelection,
pub mode: &'static str,
}
impl Coverage {
const PATH: &'static str = "tests/coverage";
const SUITE: &'static str = "coverage";
const ALL_MODES: &[&str] = &["coverage-map", "coverage-run"];
}
/// Runs the coverage test suite (or a user-specified subset) in one mode.
///
/// This same function is used by the multi-mode step ([`Coverage`]) and by
/// the single-mode steps ([`CoverageMap`] and [`CoverageRun`]), to help
/// ensure that they all behave consistently with each other, regardless of
/// how the coverage tests have been invoked.
fn run_coverage_tests(
builder: &Builder<'_>,
compiler: Compiler,
target: TargetSelection,
mode: &'static str,
) {
// Like many other test steps, we delegate to a `Compiletest` step to
// actually run the tests. (See `test_definitions!`.)
impl Step for Coverage {
type Output = ();
const DEFAULT: bool = true;
/// Compiletest will automatically skip the "coverage-run" tests if necessary.
const ONLY_HOSTS: bool = false;
fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> {
// Support various invocation styles, including:
// - `./x test coverage`
// - `./x test tests/coverage/trivial.rs`
// - `./x test coverage-map`
// - `./x test coverage-run -- tests/coverage/trivial.rs`
run = run.suite_path(Self::PATH);
for mode in Self::ALL_MODES {
run = run.alias(mode);
}
run
}
fn make_run(run: RunConfig<'_>) {
let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
let target = run.target;
// List of (coverage) test modes that the coverage test suite will be
// run in. It's OK for this to contain duplicates, because the call to
// `Builder::ensure` below will take care of deduplication.
let mut modes = vec![];
// From the pathsets that were selected on the command-line (or by default),
// determine which modes to run in.
for path in &run.paths {
match path {
PathSet::Set(_) => {
for mode in Self::ALL_MODES {
if path.assert_single_path().path == Path::new(mode) {
modes.push(mode);
break;
}
}
}
PathSet::Suite(_) => {
modes.extend(Self::ALL_MODES);
break;
}
}
}
// Skip any modes that were explicitly skipped/excluded on the command-line.
// FIXME(Zalathar): Integrate this into central skip handling somehow?
modes.retain(|mode| !run.builder.config.skip.iter().any(|skip| skip == Path::new(mode)));
// FIXME(Zalathar): Make these commands skip all coverage tests, as expected:
// - `./x test --skip=tests`
// - `./x test --skip=tests/coverage`
// - `./x test --skip=coverage`
// Skip handling currently doesn't have a way to know that skipping the coverage
// suite should also skip the `coverage-map` and `coverage-run` aliases.
for mode in modes {
run.builder.ensure(Coverage { compiler, target, mode });
}
}
fn run(self, builder: &Builder<'_>) {
let Self { compiler, target, mode } = self;
// Like other compiletest suite test steps, delegate to an internal
// compiletest task to actually run the tests.
builder.ensure(Compiletest {
compiler,
target,
@ -1522,53 +1544,6 @@ impl Coverage {
}
}
impl Step for Coverage {
type Output = ();
/// We rely on the individual CoverageMap/CoverageRun steps to run themselves.
const DEFAULT: bool = false;
/// When manually invoked, try to run as much as possible.
/// Compiletest will automatically skip the "coverage-run" tests if necessary.
const ONLY_HOSTS: bool = false;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
// Take responsibility for command-line paths within `tests/coverage`.
run.suite_path(Self::PATH)
}
fn make_run(run: RunConfig<'_>) {
let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
run.builder.ensure(Coverage { compiler, target: run.target });
}
fn run(self, builder: &Builder<'_>) {
// Run the specified coverage tests (possibly all of them) in both modes.
Self::run_coverage_tests(builder, self.compiler, self.target, CoverageMap::MODE);
Self::run_coverage_tests(builder, self.compiler, self.target, CoverageRun::MODE);
}
}
coverage_test_alias! {
/// Runs the `tests/coverage` test suite in "coverage-map" mode only.
/// Used by `x test` and `x test coverage-map`.
CoverageMap {
alias_and_mode: "coverage-map",
default: true,
only_hosts: false,
}
}
coverage_test_alias! {
/// Runs the `tests/coverage` test suite in "coverage-run" mode only.
/// Used by `x test` and `x test coverage-run`.
CoverageRun {
alias_and_mode: "coverage-run",
default: true,
// Compiletest knows how to automatically skip these tests when cross-compiling,
// but skipping the whole step here makes it clearer that they haven't run at all.
only_hosts: true,
}
}
test!(CoverageRunRustdoc {
path: "tests/coverage-run-rustdoc",
mode: "coverage-run",
@ -1663,7 +1638,10 @@ impl Step for Compiletest {
return;
}
if builder.top_stage == 0 && env::var("COMPILETEST_FORCE_STAGE0").is_err() {
if builder.top_stage == 0
&& env::var("COMPILETEST_FORCE_STAGE0").is_err()
&& self.mode != "js-doc-test"
{
eprintln!("\
ERROR: `--stage 0` runs compiletest on the beta compiler, not your local changes, and will almost always cause tests to fail
HELP: to test the compiler, use `--stage 1` instead
@ -2284,10 +2262,8 @@ impl BookTest {
&[],
);
let stamp = builder
.cargo_out(compiler, mode, target)
.join(PathBuf::from(dep).file_name().unwrap())
.with_extension("stamp");
let stamp = BuildStamp::new(&builder.cargo_out(compiler, mode, target))
.with_prefix(PathBuf::from(dep).file_name().and_then(|v| v.to_str()).unwrap());
let output_paths = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false);
let directories = output_paths
@ -2516,6 +2492,10 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) ->
}
}
/// Runs `cargo test` for the compiler crates in `compiler/`.
///
/// (This step does not test `rustc_codegen_cranelift` or `rustc_codegen_gcc`,
/// which have their own separate test steps.)
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CrateLibrustc {
compiler: Compiler,
@ -2544,6 +2524,7 @@ impl Step for CrateLibrustc {
fn run(self, builder: &Builder<'_>) {
builder.ensure(compile::Std::new(self.compiler, self.target));
// To actually run the tests, delegate to a copy of the `Crate` step.
builder.ensure(Crate {
compiler: self.compiler,
target: self.target,
@ -2669,6 +2650,13 @@ fn prepare_cargo_test(
cargo
}
/// Runs `cargo test` for standard library crates.
///
/// (Also used internally to run `cargo test` for compiler crates.)
///
/// FIXME(Zalathar): Try to split this into two separate steps: a user-visible
/// step for testing standard library crates, and an internal step used for both
/// library crates and compiler crates.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Crate {
pub compiler: Compiler,
@ -3602,6 +3590,10 @@ impl Step for CodegenGCC {
}
}
/// Test step that does two things:
/// - Runs `cargo test` for the `src/etc/test-float-parse` tool.
/// - Invokes the `test-float-parse` tool to test the standard library's
/// float parsing routines.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TestFloatParse {
path: PathBuf,
@ -3675,6 +3667,9 @@ impl Step for TestFloatParse {
}
}
/// Runs the tool `src/tools/collect-license-metadata` in `ONLY_CHECK=1` mode,
/// which verifies that `license-metadata.json` is up-to-date and therefore
/// running the tool normally would not update anything.
#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
pub struct CollectLicenseMetadata;

View file

@ -7,6 +7,7 @@ use crate::core::build_steps::tool::SourceType;
use crate::core::build_steps::{compile, test};
use crate::core::config::SplitDebuginfo;
use crate::core::config::flags::Color;
use crate::utils::build_stamp;
use crate::utils::helpers::{
self, LldThreads, add_link_lib_path, check_cfg_arg, linker_args, linker_flags,
};
@ -454,7 +455,7 @@ impl Builder<'_> {
// Codegen backends are not yet tracked by -Zbinary-dep-depinfo,
// so we need to explicitly clear out if they've been updated.
for backend in self.codegen_backends(compiler) {
self.clear_if_dirty(&out_dir, &backend);
build_stamp::clear_if_dirty(self, &out_dir, &backend);
}
if cmd_kind == Kind::Doc {
@ -471,7 +472,7 @@ impl Builder<'_> {
_ => panic!("doc mode {mode:?} not expected"),
};
let rustdoc = self.rustdoc(compiler);
self.clear_if_dirty(&my_out, &rustdoc);
build_stamp::clear_if_dirty(self, &my_out, &rustdoc);
}
let profile_var = |name: &str| {
@ -624,8 +625,6 @@ impl Builder<'_> {
// get warnings about it being unexpected.
hostflags.arg("-Zunstable-options");
hostflags.arg("--check-cfg=cfg(bootstrap)");
// #[cfg(bootstrap)] as we are transition `test` to userspace cfg
hostflags.arg("--check-cfg=cfg(test)");
// FIXME: It might be better to use the same value for both `RUSTFLAGS` and `RUSTDOCFLAGS`,
// but this breaks CI. At the very least, stage0 `rustdoc` needs `--cfg bootstrap`. See
@ -765,7 +764,7 @@ impl Builder<'_> {
// Only clear out the directory if we're compiling std; otherwise, we
// should let Cargo take care of things for us (via depdep info)
if !self.config.dry_run() && mode == Mode::Std && cmd_kind == Kind::Build {
self.clear_if_dirty(&out_dir, &self.rustc(compiler));
build_stamp::clear_if_dirty(self, &out_dir, &self.rustc(compiler));
}
let rustdoc_path = match cmd_kind {
@ -1206,10 +1205,7 @@ impl Builder<'_> {
// so that it'll be available when downstream consumers of std try to use it.
rustflags.arg("-Zinline-mir-preserve-debug");
// FIXME: always pass this after the next `#[cfg(bootstrap)]` update.
if compiler.stage != 0 {
rustflags.arg("-Zmir_strip_debuginfo=locals-in-tiny-functions");
}
rustflags.arg("-Zmir_strip_debuginfo=locals-in-tiny-functions");
}
Cargo {

View file

@ -944,8 +944,6 @@ impl<'a> Builder<'a> {
test::Ui,
test::Crashes,
test::Coverage,
test::CoverageMap,
test::CoverageRun,
test::MirOpt,
test::Codegen,
test::CodegenUnits,
@ -1445,7 +1443,7 @@ impl<'a> Builder<'a> {
let mut stack = self.stack.borrow_mut();
for stack_step in stack.iter() {
// should skip
if stack_step.downcast_ref::<S>().map_or(true, |stack_step| *stack_step != step) {
if stack_step.downcast_ref::<S>().is_none_or(|stack_step| *stack_step != step) {
continue;
}
let mut out = String::new();

View file

@ -828,3 +828,36 @@ fn test_test_compiler() {
assert_eq!((compiler, cranelift, gcc), (true, false, false));
}
#[test]
fn test_test_coverage() {
struct Case {
cmd: &'static [&'static str],
expected: &'static [&'static str],
}
let cases = &[
Case { cmd: &["test"], expected: &["coverage-map", "coverage-run"] },
Case { cmd: &["test", "coverage"], expected: &["coverage-map", "coverage-run"] },
Case { cmd: &["test", "coverage-map"], expected: &["coverage-map"] },
Case { cmd: &["test", "coverage-run"], expected: &["coverage-run"] },
Case { cmd: &["test", "coverage", "--skip=coverage"], expected: &[] },
Case { cmd: &["test", "coverage", "--skip=tests/coverage"], expected: &[] },
Case { cmd: &["test", "coverage", "--skip=coverage-map"], expected: &["coverage-run"] },
Case { cmd: &["test", "coverage", "--skip=coverage-run"], expected: &["coverage-map"] },
Case { cmd: &["test", "--skip=coverage-map", "--skip=coverage-run"], expected: &[] },
Case { cmd: &["test", "coverage", "--skip=tests"], expected: &[] },
];
for &Case { cmd, expected } in cases {
// Print each test case so that if one fails, the most recently printed
// case is the one that failed.
println!("Testing case: {cmd:?}");
let cmd = cmd.iter().copied().map(str::to_owned).collect::<Vec<_>>();
let config = configure_with_args(&cmd, &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]);
let mut cache = run_build(&config.paths.clone(), config);
let modes =
cache.all::<test::Coverage>().iter().map(|(step, ())| step.mode).collect::<Vec<_>>();
assert_eq!(modes, expected);
}
}

View file

@ -634,6 +634,7 @@ pub struct Target {
pub runner: Option<String>,
pub no_std: bool,
pub codegen_backends: Option<Vec<String>>,
pub optimized_compiler_builtins: Option<bool>,
}
impl Target {
@ -1125,7 +1126,7 @@ impl<'de> Deserialize<'de> for LldMode {
match v {
"external" => Ok(LldMode::External),
"self-contained" => Ok(LldMode::SelfContained),
_ => Err(E::custom("unknown mode {v}")),
_ => Err(E::custom(format!("unknown mode {v}"))),
}
}
}
@ -1219,6 +1220,7 @@ define_config! {
no_std: Option<bool> = "no-std",
codegen_backends: Option<Vec<String>> = "codegen-backends",
runner: Option<String> = "runner",
optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
}
}
@ -2096,6 +2098,7 @@ impl Config {
target.sanitizers = cfg.sanitizers;
target.profiler = cfg.profiler;
target.rpath = cfg.rpath;
target.optimized_compiler_builtins = cfg.optimized_compiler_builtins;
if let Some(ref backends) = cfg.codegen_backends {
let available_backends = ["llvm", "cranelift", "gcc"];
@ -2609,6 +2612,13 @@ impl Config {
self.target_config.get(&target).and_then(|t| t.rpath).unwrap_or(self.rust_rpath)
}
pub fn optimized_compiler_builtins(&self, target: TargetSelection) -> bool {
self.target_config
.get(&target)
.and_then(|t| t.optimized_compiler_builtins)
.unwrap_or(self.optimized_compiler_builtins)
}
pub fn llvm_enabled(&self, target: TargetSelection) -> bool {
self.codegen_backends(target).contains(&"llvm".to_owned())
}
@ -3162,6 +3172,9 @@ fn check_incompatible_options_for_ci_rustc(
let profiler = &ci_cfg.profiler;
err!(current_cfg.profiler, profiler, "build");
let optimized_compiler_builtins = &ci_cfg.optimized_compiler_builtins;
err!(current_cfg.optimized_compiler_builtins, optimized_compiler_builtins, "build");
}
}

View file

@ -120,6 +120,7 @@ fn override_toml() {
"--set=change-id=1".to_owned(),
"--set=rust.lto=fat".to_owned(),
"--set=rust.deny-warnings=false".to_owned(),
"--set=build.optimized-compiler-builtins=true".to_owned(),
"--set=build.gdb=\"bar\"".to_owned(),
"--set=build.tools=[\"cargo\"]".to_owned(),
"--set=llvm.build-config={\"foo\" = \"bar\"}".to_owned(),
@ -127,6 +128,7 @@ fn override_toml() {
"--set=target.x86_64-unknown-linux-gnu.rpath=false".to_owned(),
"--set=target.aarch64-unknown-linux-gnu.sanitizers=false".to_owned(),
"--set=target.aarch64-apple-darwin.runner=apple".to_owned(),
"--set=target.aarch64-apple-darwin.optimized-compiler-builtins=false".to_owned(),
]),
|&_| {
toml::from_str(
@ -167,6 +169,7 @@ runner = "x86_64-runner"
);
assert_eq!(config.gdb, Some("bar".into()), "setting string value with quotes");
assert!(!config.deny_warnings, "setting boolean value");
assert!(config.optimized_compiler_builtins, "setting boolean value");
assert_eq!(
config.tools,
Some(["cargo".to_string()].into_iter().collect()),
@ -193,7 +196,11 @@ runner = "x86_64-runner"
..Default::default()
};
let darwin = TargetSelection::from_user("aarch64-apple-darwin");
let darwin_values = Target { runner: Some("apple".into()), ..Default::default() };
let darwin_values = Target {
runner: Some("apple".into()),
optimized_compiler_builtins: Some(false),
..Default::default()
};
assert_eq!(
config.target_config,
[(x86_64, x86_64_values), (aarch64, aarch64_values), (darwin, darwin_values)]

View file

@ -10,8 +10,9 @@ use build_helper::ci::CiEnv;
use xz2::bufread::XzDecoder;
use crate::core::config::BUILDER_CONFIG_FILENAME;
use crate::utils::build_stamp::BuildStamp;
use crate::utils::exec::{BootstrapCommand, command};
use crate::utils::helpers::{check_run, exe, hex_encode, move_file, program_out_of_date};
use crate::utils::helpers::{check_run, exe, hex_encode, move_file};
use crate::{Config, t};
static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock<bool> = OnceLock::new();
@ -46,7 +47,7 @@ impl Config {
self.verbose > 0
}
pub(crate) fn create(&self, path: &Path, s: &str) {
pub(crate) fn create<P: AsRef<Path>>(&self, path: P, s: &str) {
if self.dry_run() {
return;
}
@ -426,9 +427,10 @@ impl Config {
let version = &self.stage0_metadata.compiler.version;
let host = self.build;
let clippy_stamp = self.initial_sysroot.join(".clippy-stamp");
let clippy_stamp =
BuildStamp::new(&self.initial_sysroot).with_prefix("clippy").add_stamp(date);
let cargo_clippy = self.initial_sysroot.join("bin").join(exe("cargo-clippy", host));
if cargo_clippy.exists() && !program_out_of_date(&clippy_stamp, date) {
if cargo_clippy.exists() && clippy_stamp.is_up_to_date() {
return cargo_clippy;
}
@ -439,7 +441,7 @@ impl Config {
self.fix_bin_or_dylib(&cargo_clippy.with_file_name(exe("clippy-driver", host)));
}
self.create(&clippy_stamp, date);
t!(clippy_stamp.write());
cargo_clippy
}
@ -460,8 +462,8 @@ impl Config {
let host = self.build;
let bin_root = self.out.join(host).join("rustfmt");
let rustfmt_path = bin_root.join("bin").join(exe("rustfmt", host));
let rustfmt_stamp = bin_root.join(".rustfmt-stamp");
if rustfmt_path.exists() && !program_out_of_date(&rustfmt_stamp, &channel) {
let rustfmt_stamp = BuildStamp::new(&bin_root).with_prefix("rustfmt").add_stamp(channel);
if rustfmt_path.exists() && rustfmt_stamp.is_up_to_date() {
return Some(rustfmt_path);
}
@ -492,7 +494,7 @@ impl Config {
}
}
self.create(&rustfmt_stamp, &channel);
t!(rustfmt_stamp.write());
Some(rustfmt_path)
}
@ -567,10 +569,10 @@ impl Config {
) {
let host = self.build.triple;
let bin_root = self.out.join(host).join(sysroot);
let rustc_stamp = bin_root.join(".rustc-stamp");
let rustc_stamp = BuildStamp::new(&bin_root).with_prefix("rustc").add_stamp(stamp_key);
if !bin_root.join("bin").join(exe("rustc", self.build)).exists()
|| program_out_of_date(&rustc_stamp, stamp_key)
|| !rustc_stamp.is_up_to_date()
{
if bin_root.exists() {
t!(fs::remove_dir_all(&bin_root));
@ -601,7 +603,7 @@ impl Config {
}
}
t!(fs::write(rustc_stamp, stamp_key));
t!(rustc_stamp.write());
}
}
@ -728,10 +730,10 @@ download-rustc = false
}
let llvm_root = self.ci_llvm_root();
let llvm_stamp = llvm_root.join(".llvm-stamp");
let llvm_sha = detect_llvm_sha(self, self.rust_info.is_managed_git_subrepository());
let key = format!("{}{}", llvm_sha, self.llvm_assertions);
if program_out_of_date(&llvm_stamp, &key) && !self.dry_run() {
let stamp_key = format!("{}{}", llvm_sha, self.llvm_assertions);
let llvm_stamp = BuildStamp::new(&llvm_root).with_prefix("llvm").add_stamp(stamp_key);
if !llvm_stamp.is_up_to_date() && !self.dry_run() {
self.download_ci_llvm(&llvm_sha);
if self.should_fix_bins_and_dylibs() {
@ -764,7 +766,7 @@ download-rustc = false
}
}
t!(fs::write(llvm_stamp, key));
t!(llvm_stamp.write());
}
if let Some(config_path) = &self.config {

View file

@ -19,27 +19,23 @@
use std::cell::{Cell, RefCell};
use std::collections::{BTreeSet, HashMap, HashSet};
use std::fmt::Display;
use std::fs::{self, File};
use std::path::{Path, PathBuf};
use std::process::Command;
use std::sync::OnceLock;
use std::time::SystemTime;
use std::{env, io, str};
use std::{env, fs, io, str};
use build_helper::ci::gha;
use build_helper::exit;
use sha2::digest::Digest;
use termcolor::{ColorChoice, StandardStream, WriteColor};
use utils::build_stamp::BuildStamp;
use utils::channel::GitInfo;
use utils::helpers::hex_encode;
use crate::core::builder;
use crate::core::builder::{Builder, Kind};
use crate::core::builder::Kind;
use crate::core::config::{DryRun, LldMode, LlvmLibunwind, Target, TargetSelection, flags};
use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode, command};
use crate::utils::helpers::{
self, dir_is_empty, exe, libdir, mtime, output, set_file_times, symlink_dir,
};
use crate::utils::helpers::{self, dir_is_empty, exe, libdir, output, set_file_times, symlink_dir};
mod core;
mod utils;
@ -77,8 +73,6 @@ const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"];
#[allow(clippy::type_complexity)] // It's fine for hard-coded list and type is explained above.
const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
(None, "bootstrap", None),
// #[cfg(bootstrap)] to be removed when Cargo is updated
(None, "test", None),
(Some(Mode::Rustc), "llvm_enzyme", None),
(Some(Mode::Codegen), "llvm_enzyme", None),
(Some(Mode::ToolRustc), "llvm_enzyme", None),
@ -600,24 +594,6 @@ impl Build {
self.metrics.persist(self);
}
/// Clear out `dir` if `input` is newer.
///
/// After this executes, it will also ensure that `dir` exists.
fn clear_if_dirty(&self, dir: &Path, input: &Path) -> bool {
let stamp = dir.join(".stamp");
let mut cleared = false;
if mtime(&stamp) < mtime(input) {
self.verbose(|| println!("Dirty - {}", dir.display()));
let _ = fs::remove_dir_all(dir);
cleared = true;
} else if stamp.exists() {
return cleared;
}
t!(fs::create_dir_all(dir));
t!(File::create(stamp));
cleared
}
fn rust_info(&self) -> &GitInfo {
&self.config.rust_info
}
@ -1624,21 +1600,21 @@ Executed at: {executed_at}"#,
ret
}
fn read_stamp_file(&self, stamp: &Path) -> Vec<(PathBuf, DependencyType)> {
fn read_stamp_file(&self, stamp: &BuildStamp) -> Vec<(PathBuf, DependencyType)> {
if self.config.dry_run() {
return Vec::new();
}
if !stamp.exists() {
if !stamp.path().exists() {
eprintln!(
"ERROR: Unable to find the stamp file {}, did you try to keep a nonexistent build stage?",
stamp.display()
stamp.path().display()
);
crate::exit!(1);
}
let mut paths = Vec::new();
let contents = t!(fs::read(stamp), &stamp);
let contents = t!(fs::read(stamp.path()), stamp.path());
// This is the method we use for extracting paths from the stamp file passed to us. See
// run_cargo for more information (in compile.rs).
for part in contents.split(|b| *b == 0) {
@ -1924,52 +1900,6 @@ fn envify(s: &str) -> String {
.collect()
}
/// Computes a hash representing the state of a repository/submodule and additional input.
///
/// It uses `git diff` for the actual changes, and `git status` for including the untracked
/// files in the specified directory. The additional input is also incorporated into the
/// computation of the hash.
///
/// # Parameters
///
/// - `dir`: A reference to the directory path of the target repository/submodule.
/// - `additional_input`: An additional input to be included in the hash.
///
/// # Panics
///
/// In case of errors during `git` command execution (e.g., in tarball sources), default values
/// are used to prevent panics.
pub fn generate_smart_stamp_hash(
builder: &Builder<'_>,
dir: &Path,
additional_input: &str,
) -> String {
let diff = helpers::git(Some(dir))
.allow_failure()
.arg("diff")
.run_capture_stdout(builder)
.stdout_if_ok()
.unwrap_or_default();
let status = helpers::git(Some(dir))
.allow_failure()
.arg("status")
.arg("--porcelain")
.arg("-z")
.arg("--untracked-files=normal")
.run_capture_stdout(builder)
.stdout_if_ok()
.unwrap_or_default();
let mut hasher = sha2::Sha256::new();
hasher.update(diff);
hasher.update(status);
hasher.update(additional_input);
hex_encode(hasher.finalize().as_slice())
}
/// Ensures that the behavior dump directory is properly initialized.
pub fn prepare_behaviour_dump_dir(build: &Build) {
static INITIALIZED: OnceLock<bool> = OnceLock::new();

View file

@ -0,0 +1,204 @@
//! Module for managing build stamp files.
//!
//! Contains the core implementation of how bootstrap utilizes stamp files on build processes.
use std::path::{Path, PathBuf};
use std::{fs, io};
use sha2::digest::Digest;
use crate::core::builder::Builder;
use crate::core::config::TargetSelection;
use crate::utils::helpers::{hex_encode, mtime};
use crate::{Compiler, Mode, helpers, t};
#[cfg(test)]
mod tests;
/// Manages a stamp file to track build state. The file is created in the given
/// directory and can have custom content and name.
#[derive(Clone)]
pub struct BuildStamp {
path: PathBuf,
stamp: String,
}
impl BuildStamp {
/// Creates a new `BuildStamp` for a given directory.
///
/// By default, stamp will be an empty file named `.stamp` within the specified directory.
pub fn new(dir: &Path) -> Self {
// Avoid using `is_dir()` as the directory may not exist yet.
// It is more appropriate to assert that the path is not a file.
assert!(!dir.is_file(), "can't be a file path");
Self { path: dir.join(".stamp"), stamp: String::new() }
}
/// Returns path of the stamp file.
pub fn path(&self) -> &Path {
&self.path
}
/// Returns the value of the stamp.
///
/// Note that this is empty by default and is populated using `BuildStamp::add_stamp`.
/// It is not read from an actual file, but rather it holds the value that will be used
/// when `BuildStamp::write` is called.
pub fn stamp(&self) -> &str {
&self.stamp
}
/// Adds specified stamp content to the current value.
///
/// This method can be used incrementally e.g., `add_stamp("x").add_stamp("y").add_stamp("z")`.
pub fn add_stamp<S: ToString>(mut self, stamp: S) -> Self {
self.stamp.push_str(&stamp.to_string());
self
}
/// Adds a prefix to stamp's name.
///
/// Prefix cannot start or end with a dot (`.`).
pub fn with_prefix(mut self, prefix: &str) -> Self {
assert!(
!prefix.starts_with('.') && !prefix.ends_with('.'),
"prefix can not start or end with '.'"
);
let stamp_filename = self.path.file_name().unwrap().to_str().unwrap();
let stamp_filename = stamp_filename.strip_prefix('.').unwrap_or(stamp_filename);
self.path.set_file_name(format!(".{prefix}-{stamp_filename}"));
self
}
/// Removes the stamp file if it exists.
pub fn remove(&self) -> io::Result<()> {
match fs::remove_file(&self.path) {
Ok(()) => Ok(()),
Err(e) => {
if e.kind() == io::ErrorKind::NotFound {
Ok(())
} else {
Err(e)
}
}
}
}
/// Creates the stamp file.
pub fn write(&self) -> io::Result<()> {
fs::write(&self.path, &self.stamp)
}
/// Checks if the stamp file is up-to-date.
///
/// It is considered up-to-date if file content matches with the stamp string.
pub fn is_up_to_date(&self) -> bool {
match fs::read(&self.path) {
Ok(h) => self.stamp.as_bytes() == h.as_slice(),
Err(e) if e.kind() == io::ErrorKind::NotFound => false,
Err(e) => {
panic!("failed to read stamp file `{}`: {}", self.path.display(), e);
}
}
}
}
/// Clear out `dir` if `input` is newer.
///
/// After this executes, it will also ensure that `dir` exists.
pub fn clear_if_dirty(builder: &Builder<'_>, dir: &Path, input: &Path) -> bool {
let stamp = BuildStamp::new(dir);
let mut cleared = false;
if mtime(stamp.path()) < mtime(input) {
builder.verbose(|| println!("Dirty - {}", dir.display()));
let _ = fs::remove_dir_all(dir);
cleared = true;
} else if stamp.path().exists() {
return cleared;
}
t!(fs::create_dir_all(dir));
t!(fs::File::create(stamp.path()));
cleared
}
/// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
/// compiler for the specified target and backend.
pub fn codegen_backend_stamp(
builder: &Builder<'_>,
compiler: Compiler,
target: TargetSelection,
backend: &str,
) -> BuildStamp {
BuildStamp::new(&builder.cargo_out(compiler, Mode::Codegen, target))
.with_prefix(&format!("librustc_codegen_{backend}"))
}
/// Cargo's output path for the standard library in a given stage, compiled
/// by a particular compiler for the specified target.
pub fn libstd_stamp(
builder: &Builder<'_>,
compiler: Compiler,
target: TargetSelection,
) -> BuildStamp {
BuildStamp::new(&builder.cargo_out(compiler, Mode::Std, target)).with_prefix("libstd")
}
/// Cargo's output path for librustc in a given stage, compiled by a particular
/// compiler for the specified target.
pub fn librustc_stamp(
builder: &Builder<'_>,
compiler: Compiler,
target: TargetSelection,
) -> BuildStamp {
BuildStamp::new(&builder.cargo_out(compiler, Mode::Rustc, target)).with_prefix("librustc")
}
/// Computes a hash representing the state of a repository/submodule and additional input.
///
/// It uses `git diff` for the actual changes, and `git status` for including the untracked
/// files in the specified directory. The additional input is also incorporated into the
/// computation of the hash.
///
/// # Parameters
///
/// - `dir`: A reference to the directory path of the target repository/submodule.
/// - `additional_input`: An additional input to be included in the hash.
///
/// # Panics
///
/// In case of errors during `git` command execution (e.g., in tarball sources), default values
/// are used to prevent panics.
pub fn generate_smart_stamp_hash(
builder: &Builder<'_>,
dir: &Path,
additional_input: &str,
) -> String {
let diff = helpers::git(Some(dir))
.allow_failure()
.arg("diff")
.arg(".")
.run_capture_stdout(builder)
.stdout_if_ok()
.unwrap_or_default();
let status = helpers::git(Some(dir))
.allow_failure()
.arg("status")
.arg(".")
.arg("--porcelain")
.arg("-z")
.arg("--untracked-files=normal")
.run_capture_stdout(builder)
.stdout_if_ok()
.unwrap_or_default();
let mut hasher = sha2::Sha256::new();
hasher.update(diff);
hasher.update(status);
hasher.update(additional_input);
hex_encode(hasher.finalize().as_slice())
}

View file

@ -0,0 +1,60 @@
use std::path::PathBuf;
use crate::{BuildStamp, Config, Flags};
fn temp_dir() -> PathBuf {
let config =
Config::parse(Flags::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]));
config.tempdir()
}
#[test]
#[should_panic(expected = "prefix can not start or end with '.'")]
fn test_with_invalid_prefix() {
let dir = temp_dir();
BuildStamp::new(&dir).with_prefix(".invalid");
}
#[test]
#[should_panic(expected = "prefix can not start or end with '.'")]
fn test_with_invalid_prefix2() {
let dir = temp_dir();
BuildStamp::new(&dir).with_prefix("invalid.");
}
#[test]
fn test_is_up_to_date() {
let dir = temp_dir();
let mut build_stamp = BuildStamp::new(&dir).add_stamp("v1.0.0");
build_stamp.write().unwrap();
assert!(
build_stamp.is_up_to_date(),
"Expected stamp file to be up-to-date, but contents do not match the expected value."
);
build_stamp.stamp = "dummy value".to_owned();
assert!(
!build_stamp.is_up_to_date(),
"Stamp should no longer be up-to-date as we changed its content right above."
);
build_stamp.remove().unwrap();
}
#[test]
fn test_with_prefix() {
let dir = temp_dir();
let stamp = BuildStamp::new(&dir).add_stamp("v1.0.0");
assert_eq!(stamp.path.file_name().unwrap(), ".stamp");
let stamp = stamp.with_prefix("test");
let expected_filename = ".test-stamp";
assert_eq!(stamp.path.file_name().unwrap(), expected_filename);
let stamp = stamp.with_prefix("extra-prefix");
let expected_filename = ".extra-prefix-test-stamp";
assert_eq!(stamp.path.file_name().unwrap(), expected_filename);
}

View file

@ -325,4 +325,14 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
severity: ChangeSeverity::Warning,
summary: "Removed `rust.parallel-compiler` as it was deprecated in #132282 long time ago.",
},
ChangeInfo {
change_id: 135326,
severity: ChangeSeverity::Warning,
summary: "It is now possible to configure `optimized-compiler-builtins` for per target.",
},
ChangeInfo {
change_id: 135281,
severity: ChangeSeverity::Warning,
summary: "Some stamp names in the build artifacts may have changed slightly (e.g., from `llvm-finished-building` to `.llvm-stamp`).",
},
];

View file

@ -120,7 +120,7 @@ impl BootstrapCommand {
Self { failure_behavior: BehaviorOnFailure::DelayFail, ..self }
}
#[must_use]
#[allow(dead_code)]
pub fn fail_fast(self) -> Self {
Self { failure_behavior: BehaviorOnFailure::Exit, ..self }
}
@ -275,7 +275,7 @@ impl CommandOutput {
!self.is_success()
}
#[must_use]
#[allow(dead_code)]
pub fn status(&self) -> Option<ExitStatus> {
match self.status {
CommandStatus::Finished(status) => Some(status),

View file

@ -16,6 +16,7 @@ use object::read::archive::ArchiveFile;
use crate::LldMode;
use crate::core::builder::Builder;
use crate::core::config::{Config, TargetSelection};
use crate::utils::exec::{BootstrapCommand, command};
pub use crate::utils::shared_helpers::{dylib_path, dylib_path_var};
#[cfg(test)]
@ -45,10 +46,8 @@ macro_rules! t {
}
};
}
pub use t;
use crate::utils::exec::{BootstrapCommand, command};
pub fn exe(name: &str, target: TargetSelection) -> String {
crate::utils::shared_helpers::exe(name, &target.triple)
}
@ -148,14 +147,6 @@ impl Drop for TimeIt {
}
}
/// Used for download caching
pub(crate) fn program_out_of_date(stamp: &Path, key: &str) -> bool {
if !stamp.exists() {
return true;
}
t!(fs::read_to_string(stamp)) != key
}
/// Symlinks two directories, using junctions on Windows and normal symlinks on
/// Unix.
pub fn symlink_dir(config: &Config, original: &Path, link: &Path) -> io::Result<()> {
@ -181,10 +172,7 @@ pub fn symlink_dir(config: &Config, original: &Path, link: &Path) -> io::Result<
/// copy and remove the file otherwise
pub fn move_file<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
match fs::rename(&from, &to) {
// FIXME: Once `ErrorKind::CrossesDevices` is stabilized use
// if e.kind() == io::ErrorKind::CrossesDevices {
#[cfg(unix)]
Err(e) if e.raw_os_error() == Some(libc::EXDEV) => {
Err(e) if e.kind() == io::ErrorKind::CrossesDevices => {
std::fs::copy(&from, &to)?;
std::fs::remove_file(&from)
}
@ -601,41 +589,3 @@ pub fn set_file_times<P: AsRef<Path>>(path: P, times: fs::FileTimes) -> io::Resu
};
f.set_times(times)
}
pub struct HashStamp {
pub path: PathBuf,
pub hash: Option<Vec<u8>>,
}
impl HashStamp {
pub fn new(path: PathBuf, hash: Option<&str>) -> Self {
HashStamp { path, hash: hash.map(|s| s.as_bytes().to_owned()) }
}
pub fn is_done(&self) -> bool {
match fs::read(&self.path) {
Ok(h) => self.hash.as_deref().unwrap_or(b"") == h.as_slice(),
Err(e) if e.kind() == io::ErrorKind::NotFound => false,
Err(e) => {
panic!("failed to read stamp file `{}`: {}", self.path.display(), e);
}
}
}
pub fn remove(&self) -> io::Result<()> {
match fs::remove_file(&self.path) {
Ok(()) => Ok(()),
Err(e) => {
if e.kind() == io::ErrorKind::NotFound {
Ok(())
} else {
Err(e)
}
}
}
}
pub fn write(&self) -> io::Result<()> {
fs::write(&self.path, self.hash.as_deref().unwrap_or(b""))
}
}

View file

@ -1,10 +1,10 @@
use std::fs::{self, File, remove_file};
use std::fs::{self, File};
use std::io::Write;
use std::path::PathBuf;
use crate::utils::helpers::{
check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, set_file_times,
submodule_path_of, symlink_dir,
check_cfg_arg, extract_beta_rev, hex_encode, make, set_file_times, submodule_path_of,
symlink_dir,
};
use crate::{Config, Flags};
@ -57,22 +57,6 @@ fn test_check_cfg_arg() {
);
}
#[test]
fn test_program_out_of_date() {
let config =
Config::parse(Flags::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]));
let tempfile = config.tempdir().join(".tmp-stamp-file");
File::create(&tempfile).unwrap().write_all(b"dummy value").unwrap();
assert!(tempfile.exists());
// up-to-date
assert!(!program_out_of_date(&tempfile, "dummy value"));
// out-of-date
assert!(program_out_of_date(&tempfile, ""));
remove_file(tempfile).unwrap();
}
#[test]
fn test_symlink_dir() {
let config =

View file

@ -2,6 +2,7 @@
//! support for a wide range of tasks and operations such as caching, tarballs, release
//! channels, job management, etc.
pub(crate) mod build_stamp;
pub(crate) mod cache;
pub(crate) mod cc_detect;
pub(crate) mod change_tracker;
@ -9,10 +10,12 @@ pub(crate) mod channel;
pub(crate) mod exec;
pub(crate) mod helpers;
pub(crate) mod job;
#[cfg(feature = "build-metrics")]
pub(crate) mod metrics;
pub(crate) mod render_tests;
pub(crate) mod shared_helpers;
pub(crate) mod tarball;
#[cfg(feature = "build-metrics")]
pub(crate) mod metrics;
#[cfg(test)]
mod tests;

View file

@ -129,8 +129,19 @@ pub fn get_closest_merge_commit(
git.current_dir(git_dir);
}
let channel = include_str!("../../ci/channel");
let merge_base = {
if CiEnv::is_ci() {
if CiEnv::is_ci() &&
// FIXME: When running on rust-lang managed CI and it's not a nightly build,
// `git_upstream_merge_base` fails with an error message similar to this:
// ```
// called `Result::unwrap()` on an `Err` value: "command did not execute successfully:
// cd \"/checkout\" && \"git\" \"merge-base\" \"origin/master\" \"HEAD\"\nexpected success, got: exit status: 1\n"
// ```
// Investigate and resolve this issue instead of skipping it like this.
(channel == "nightly" || !CiEnv::is_rust_lang_managed_ci_job())
{
git_upstream_merge_base(config, git_dir).unwrap()
} else {
// For non-CI environments, ignore rust-lang/rust upstream as it usually gets

View file

@ -1,29 +1,30 @@
# Docker images for CI
This folder contains a bunch of docker images used by the continuous integration
(CI) of Rust. An script is accompanied (`run.sh`) with these images to actually
execute them. To test out an image execute:
(CI) of Rust. A script is accompanied (`run.sh`) with these images to actually
execute them.
Note that a single Docker image can be used by multiple CI jobs, so the job name
is the important thing that you should know. You can examine the existing CI jobs in
the [`jobs.yml`](../github-actions/jobs.yml) file.
To run a specific CI job locally, you can use the following script:
```
./src/ci/docker/run.sh $image_name
python3 ./src/ci/github-actions/ci.py run-local <job-name>
```
for example:
For example, to run the `x86_64-gnu-llvm-18-1` job:
```
./src/ci/docker/run.sh x86_64-gnu
python3 ./src/ci/github-actions/ci.py run-local x86_64-gnu-llvm-18-1
```
Images will output artifacts in an `obj/$image_name` dir at the root of a repository. Note
that the script will overwrite the contents of this directory.
To match conditions in rusts CI, also set the environment variable `DEPLOY=1`, e.g.:
```
DEPLOY=1 ./src/ci/docker/run.sh x86_64-gnu
```
The job will output artifacts in an `obj/<image-name>` dir at the root of a repository. Note
that the script will overwrite the contents of this directory. `<image-name>` is set based on the
Docker image executed in the given CI job.
**NOTE**: In CI, the script outputs the artifacts to the `obj` directory,
while locally, to the `obj/$image_name` directory. This is primarily to prevent
while locally, to the `obj/<image-name>` directory. This is primarily to prevent
strange linker errors when using multiple Docker images.
For some Linux workflows (for example `x86_64-gnu-llvm-18-N`), the process is more involved. You will need to see which script is executed for the given workflow inside the [`jobs.yml`](../github-actions/jobs.yml) file and pass it through the `DOCKER_SCRIPT` environment variable. For example, to reproduce the `x86_64-gnu-llvm-18-3` workflow, you can run the following script:

View file

@ -0,0 +1,100 @@
# We document platform support for minimum glibc 2.17 and kernel 3.2.
# CentOS 7 has headers for kernel 3.10, but that's fine as long as we don't
# actually use newer APIs in rustc or std without a fallback. It's more
# important that we match glibc for ELF symbol versioning.
FROM centos:7
WORKDIR /build
# CentOS 7 EOL is June 30, 2024, but the repos remain in the vault.
RUN sed -i /etc/yum.repos.d/*.repo -e 's!^mirrorlist!#mirrorlist!' \
-e 's!^#baseurl=http://mirror.centos.org/!baseurl=https://vault.centos.org/!'
RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf
RUN yum upgrade -y && \
yum install -y \
automake \
bzip2 \
file \
gcc \
gcc-c++ \
git \
glibc-devel \
libedit-devel \
libstdc++-devel \
make \
ncurses-devel \
openssl-devel \
patch \
perl \
perl-core \
pkgconfig \
python3 \
unzip \
wget \
xz \
zlib-devel \
&& yum clean all
RUN mkdir -p /rustroot/bin
ENV PATH=/rustroot/bin:$PATH
ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib32:/rustroot/lib
ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig
WORKDIR /tmp
RUN mkdir /home/user
COPY scripts/shared.sh /tmp/
# Need at least GCC 5.1 to compile LLVM
COPY scripts/build-gcc.sh /tmp/
ENV GCC_VERSION=9.5.0
ENV GCC_BUILD_TARGET=aarch64-unknown-linux-gnu
RUN ./build-gcc.sh && yum remove -y gcc gcc-c++
ENV CC=gcc CXX=g++
# LLVM 17 needs cmake 3.20 or higher.
COPY scripts/cmake.sh /tmp/
RUN ./cmake.sh
# Build LLVM+Clang
COPY scripts/build-clang.sh /tmp/
ENV LLVM_BUILD_TARGETS=AArch64
RUN ./build-clang.sh
ENV CC=clang CXX=clang++
# Build zstd to enable `llvm.libzstd`.
COPY scripts/build-zstd.sh /tmp/
RUN ./build-zstd.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
ENV PGO_HOST=aarch64-unknown-linux-gnu
ENV HOSTS=aarch64-unknown-linux-gnu
ENV CPATH=/usr/include/aarch64-linux-gnu/:$CPATH
ENV RUST_CONFIGURE_ARGS \
--build=aarch64-unknown-linux-gnu \
--enable-full-tools \
--enable-profiler \
--enable-sanitizers \
--enable-compiler-docs \
--set target.aarch64-unknown-linux-gnu.linker=clang \
--set target.aarch64-unknown-linux-gnu.ar=/rustroot/bin/llvm-ar \
--set target.aarch64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib \
--set llvm.link-shared=true \
--set llvm.thin-lto=true \
--set llvm.libzstd=true \
--set llvm.ninja=false \
--set rust.debug-assertions=false \
--set rust.jemalloc \
--set rust.use-lld=true \
--set rust.codegen-units=1
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=clang
ENV LIBCURL_NO_PKG_CONFIG 1
ENV DIST_REQUIRE_ALL_TOOLS 1

View file

@ -1,32 +0,0 @@
FROM ubuntu:22.04
COPY scripts/cross-apt-packages.sh /scripts/
RUN sh /scripts/cross-apt-packages.sh
COPY scripts/crosstool-ng.sh /scripts/
RUN sh /scripts/crosstool-ng.sh
COPY scripts/rustbuild-setup.sh /scripts/
RUN sh /scripts/rustbuild-setup.sh
WORKDIR /tmp
COPY scripts/crosstool-ng-build.sh /scripts/
COPY host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig /tmp/crosstool.defconfig
RUN /scripts/crosstool-ng-build.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
ENV PATH=$PATH:/x-tools/aarch64-unknown-linux-gnu/bin
ENV CC_aarch64_unknown_linux_gnu=aarch64-unknown-linux-gnu-gcc \
AR_aarch64_unknown_linux_gnu=aarch64-unknown-linux-gnu-ar \
CXX_aarch64_unknown_linux_gnu=aarch64-unknown-linux-gnu-g++
ENV HOSTS=aarch64-unknown-linux-gnu
ENV RUST_CONFIGURE_ARGS \
--enable-full-tools \
--enable-profiler \
--enable-sanitizers
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS

View file

@ -1,10 +0,0 @@
CT_CONFIG_VERSION="4"
CT_PREFIX_DIR="/x-tools/${CT_TARGET}"
CT_USE_MIRROR=y
CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
CT_ARCH_ARM=y
CT_ARCH_64=y
CT_KERNEL_LINUX=y
CT_LINUX_V_4_1=y
CT_GLIBC_V_2_17=y
CT_CC_LANG_CXX=y

View file

@ -19,6 +19,7 @@ RUN yum upgrade -y && \
gcc \
gcc-c++ \
git \
binutils.i686 \
glibc-devel.i686 \
glibc-devel.x86_64 \
libedit-devel \
@ -46,11 +47,12 @@ ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib32:/rustroot/lib
ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig
WORKDIR /tmp
RUN mkdir /home/user
COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/
COPY scripts/shared.sh /tmp/
# Need at least GCC 5.1 to compile LLVM nowadays
COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/
COPY scripts/build-gcc.sh /tmp/
ENV GCC_VERSION=9.5.0
ENV GCC_BUILD_TARGET=i686-pc-linux-gnu
RUN ./build-gcc.sh && yum remove -y gcc gcc-c++
COPY scripts/cmake.sh /tmp/
@ -58,7 +60,8 @@ RUN ./cmake.sh
# Now build LLVM+Clang, afterwards configuring further compilations to use the
# clang/clang++ compilers.
COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/
COPY scripts/build-clang.sh /tmp/
ENV LLVM_BUILD_TARGETS=X86
RUN ./build-clang.sh
ENV CC=clang CXX=clang++

View file

@ -18,7 +18,7 @@ RUN /scripts/crosstool-ng-build.sh
WORKDIR /build
RUN apt-get install -y --no-install-recommends rpm2cpio cpio
COPY host-x86_64/dist-powerpc64le-linux/shared.sh host-x86_64/dist-powerpc64le-linux/build-powerpc64le-toolchain.sh /build/
COPY scripts/shared.sh host-x86_64/dist-powerpc64le-linux/build-powerpc64le-toolchain.sh /build/
RUN ./build-powerpc64le-toolchain.sh
COPY scripts/sccache.sh /scripts/

View file

@ -1,16 +0,0 @@
#!/bin/sh
hide_output() {
set +x
on_err="
echo ERROR: An error was encountered with the build.
cat /tmp/build.log
exit 1
"
trap "$on_err" ERR
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
PING_LOOP_PID=$!
"$@" &> /tmp/build.log
trap - ERR
kill $PING_LOOP_PID
set -x
}

View file

@ -10,7 +10,7 @@ https://sourceware.org/bugzilla/show_bug.cgi?id=28509
And this is the first version of the proposed binutils patch,
https://sourceware.org/pipermail/binutils/2021-November/118398.html
After applying the binutils patch, I get the the unexpected error when
After applying the binutils patch, I get the unexpected error when
building libgcc,
/scratch/nelsonc/riscv-gnu-toolchain/riscv-gcc/libgcc/config/riscv/div.S:42:

View file

@ -47,11 +47,12 @@ ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig
# Clang needs to access GCC headers to enable linker plugin LTO
WORKDIR /tmp
RUN mkdir /home/user
COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/
COPY scripts/shared.sh /tmp/
# Need at least GCC 5.1 to compile LLVM nowadays
COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/
COPY scripts/build-gcc.sh /tmp/
ENV GCC_VERSION=9.5.0
ENV GCC_BUILD_TARGET=x86_64-pc-linux-gnu
RUN ./build-gcc.sh && yum remove -y gcc gcc-c++
# LLVM 17 needs cmake 3.20 or higher.
@ -60,12 +61,13 @@ RUN ./cmake.sh
# Now build LLVM+Clang, afterwards configuring further compilations to use the
# clang/clang++ compilers.
COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/
COPY scripts/build-clang.sh /tmp/
ENV LLVM_BUILD_TARGETS=X86
RUN ./build-clang.sh
ENV CC=clang CXX=clang++
# Build zstd to enable `llvm.libzstd`.
COPY host-x86_64/dist-x86_64-linux/build-zstd.sh /tmp/
COPY scripts/build-zstd.sh /tmp/
RUN ./build-zstd.sh
COPY scripts/sccache.sh /scripts/

View file

@ -1,16 +0,0 @@
#!/bin/sh
hide_output() {
set +x
on_err="
echo ERROR: An error was encountered with the build.
cat /tmp/build.log
exit 1
"
trap "$on_err" ERR
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
PING_LOOP_PID=$!
"$@" &> /tmp/build.log
trap - ERR
kill $PING_LOOP_PID
set -x
}

View file

@ -54,8 +54,8 @@ ENV RUST_CONFIGURE_ARGS \
--set rust.randomize-layout=true \
--set rust.thin-lto-import-instr-limit=10
COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
COPY scripts/shared.sh /scripts/
COPY scripts/build-gccjit.sh /scripts/
RUN /scripts/build-gccjit.sh /scripts

View file

@ -54,8 +54,8 @@ ENV RUST_CONFIGURE_ARGS \
--set rust.randomize-layout=true \
--set rust.thin-lto-import-instr-limit=10
COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
COPY scripts/shared.sh /scripts/
COPY scripts/build-gccjit.sh /scripts/
RUN /scripts/build-gccjit.sh /scripts

View file

@ -89,8 +89,8 @@ ENV HOST_TARGET x86_64-unknown-linux-gnu
# assertions enabled! Therefore, we cannot force download CI rustc.
#ENV FORCE_CI_RUSTC 1
COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
COPY scripts/shared.sh /scripts/
COPY scripts/build-gccjit.sh /scripts/
RUN /scripts/build-gccjit.sh /scripts

View file

@ -21,6 +21,12 @@ cd clang-build
# include path, /rustroot/include, to clang's default include path.
INC="/rustroot/include:/usr/include"
GCC_PLUGIN_TARGET=$GCC_BUILD_TARGET
# We build gcc for the i686 job on x86_64 so the plugin will end up under an x86_64 path
if [[ $GCC_PLUGIN_TARGET == "i686-pc-linux-gnu" ]]; then
GCC_PLUGIN_TARGET=x86_64-pc-linux-gnu
fi
# We need compiler-rt for the profile runtime (used later to PGO the LLVM build)
# but sanitizers aren't currently building. Since we don't need those, just
# disable them. BOLT is used for optimizing LLVM.
@ -34,12 +40,12 @@ hide_output \
-DCOMPILER_RT_BUILD_XRAY=OFF \
-DCOMPILER_RT_BUILD_MEMPROF=OFF \
-DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
-DLLVM_TARGETS_TO_BUILD=X86 \
-DLLVM_TARGETS_TO_BUILD=$LLVM_BUILD_TARGETS \
-DLLVM_INCLUDE_BENCHMARKS=OFF \
-DLLVM_INCLUDE_TESTS=OFF \
-DLLVM_INCLUDE_EXAMPLES=OFF \
-DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt;bolt" \
-DLLVM_BINUTILS_INCDIR="/rustroot/lib/gcc/x86_64-pc-linux-gnu/$GCC_VERSION/plugin/include/" \
-DLLVM_BINUTILS_INCDIR="/rustroot/lib/gcc/$GCC_PLUGIN_TARGET/$GCC_VERSION/plugin/include/" \
-DC_INCLUDE_DIRS="$INC"
hide_output make -j$(nproc)

View file

@ -51,7 +51,9 @@ cd ..
rm -rf gcc-build
rm -rf gcc-$GCC
# FIXME: clang doesn't find 32-bit libraries in /rustroot/lib,
# but it does look all the way under /rustroot/lib/[...]/32,
# so we can link stuff there to help it out.
ln /rustroot/lib/*.{a,so} -rst /rustroot/lib/gcc/x86_64-pc-linux-gnu/$GCC/32/
if [[ $GCC_BUILD_TARGET == "i686-pc-linux-gnu" ]]; then
# FIXME: clang doesn't find 32-bit libraries in /rustroot/lib,
# but it does look all the way under /rustroot/lib/[...]/32,
# so we can link stuff there to help it out.
ln /rustroot/lib/*.{a,so} -rst /rustroot/lib/gcc/x86_64-pc-linux-gnu/$GCC/32/
fi

View file

@ -1,18 +1,20 @@
#!/usr/bin/env python3
"""
This script serves for generating a matrix of jobs that should
be executed on CI.
This script contains CI functionality.
It can be used to generate a matrix of jobs that should
be executed on CI, or run a specific CI job locally.
It reads job definitions from `src/ci/github-actions/jobs.yml`
and filters them based on the event that happened on CI.
It reads job definitions from `src/ci/github-actions/jobs.yml`.
"""
import argparse
import dataclasses
import json
import logging
import os
import re
import subprocess
import typing
from pathlib import Path
from typing import List, Dict, Any, Optional
@ -25,13 +27,19 @@ JOBS_YAML_PATH = Path(__file__).absolute().parent / "jobs.yml"
Job = Dict[str, Any]
def name_jobs(jobs: List[Dict], prefix: str) -> List[Job]:
def add_job_properties(jobs: List[Dict], prefix: str) -> List[Job]:
"""
Add a `name` attribute to each job, based on its image and the given `prefix`.
Modify the `name` attribute of each job, based on its base name and the given `prefix`.
Add an `image` attribute to each job, based on its image.
"""
modified_jobs = []
for job in jobs:
job["name"] = f"{prefix} - {job['image']}"
return jobs
# Create a copy of the `job` dictionary to avoid modifying `jobs`
new_job = dict(job)
new_job["image"] = get_job_image(new_job)
new_job["full_name"] = f"{prefix} - {new_job['name']}"
modified_jobs.append(new_job)
return modified_jobs
def add_base_env(jobs: List[Job], environment: Dict[str, str]) -> List[Job]:
@ -39,11 +47,15 @@ def add_base_env(jobs: List[Job], environment: Dict[str, str]) -> List[Job]:
Prepends `environment` to the `env` attribute of each job.
The `env` of each job has higher precedence than `environment`.
"""
modified_jobs = []
for job in jobs:
env = environment.copy()
env.update(job.get("env", {}))
job["env"] = env
return jobs
new_job = dict(job)
new_job["env"] = env
modified_jobs.append(new_job)
return modified_jobs
@dataclasses.dataclass
@ -116,7 +128,9 @@ def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]:
def calculate_jobs(run_type: WorkflowRunType, job_data: Dict[str, Any]) -> List[Job]:
if isinstance(run_type, PRRunType):
return add_base_env(name_jobs(job_data["pr"], "PR"), job_data["envs"]["pr"])
return add_base_env(
add_job_properties(job_data["pr"], "PR"), job_data["envs"]["pr"]
)
elif isinstance(run_type, TryRunType):
jobs = job_data["try"]
custom_jobs = run_type.custom_jobs
@ -130,7 +144,7 @@ def calculate_jobs(run_type: WorkflowRunType, job_data: Dict[str, Any]) -> List[
jobs = []
unknown_jobs = []
for custom_job in custom_jobs:
job = [j for j in job_data["auto"] if j["image"] == custom_job]
job = [j for j in job_data["auto"] if j["name"] == custom_job]
if not job:
unknown_jobs.append(custom_job)
continue
@ -140,10 +154,10 @@ def calculate_jobs(run_type: WorkflowRunType, job_data: Dict[str, Any]) -> List[
f"Custom job(s) `{unknown_jobs}` not found in auto jobs"
)
return add_base_env(name_jobs(jobs, "try"), job_data["envs"]["try"])
return add_base_env(add_job_properties(jobs, "try"), job_data["envs"]["try"])
elif isinstance(run_type, AutoRunType):
return add_base_env(
name_jobs(job_data["auto"], "auto"), job_data["envs"]["auto"]
add_job_properties(job_data["auto"], "auto"), job_data["envs"]["auto"]
)
return []
@ -181,12 +195,64 @@ def format_run_type(run_type: WorkflowRunType) -> str:
raise AssertionError()
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
def get_job_image(job: Job) -> str:
"""
By default, the Docker image of a job is based on its name.
However, it can be overridden by its IMAGE environment variable.
"""
env = job.get("env", {})
# Return the IMAGE environment variable if it exists, otherwise return the job name
return env.get("IMAGE", job["name"])
with open(JOBS_YAML_PATH) as f:
data = yaml.safe_load(f)
def is_linux_job(job: Job) -> bool:
return "ubuntu" in job["os"]
def find_linux_job(job_data: Dict[str, Any], job_name: str, pr_jobs: bool) -> Job:
candidates = job_data["pr"] if pr_jobs else job_data["auto"]
jobs = [job for job in candidates if job.get("name") == job_name]
if len(jobs) == 0:
available_jobs = "\n".join(
sorted(job["name"] for job in candidates if is_linux_job(job))
)
raise Exception(f"""Job `{job_name}` not found in {'pr' if pr_jobs else 'auto'} jobs.
The following jobs are available:
{available_jobs}""")
assert len(jobs) == 1
job = jobs[0]
if not is_linux_job(job):
raise Exception("Only Linux jobs can be executed locally")
return job
def run_workflow_locally(job_data: Dict[str, Any], job_name: str, pr_jobs: bool):
DOCKER_DIR = Path(__file__).absolute().parent.parent / "docker"
job = find_linux_job(job_data, job_name=job_name, pr_jobs=pr_jobs)
custom_env = {}
# Replicate src/ci/scripts/setup-environment.sh
# Adds custom environment variables to the job
if job_name.startswith("dist-"):
if job_name.endswith("-alt"):
custom_env["DEPLOY_ALT"] = "1"
else:
custom_env["DEPLOY"] = "1"
custom_env.update({k: str(v) for (k, v) in job.get("env", {}).items()})
args = [str(DOCKER_DIR / "run.sh"), get_job_image(job)]
env_formatted = [f"{k}={v}" for (k, v) in sorted(custom_env.items())]
print(f"Executing `{' '.join(env_formatted)} {' '.join(args)}`")
env = os.environ.copy()
env.update(custom_env)
subprocess.run(args, env=env)
def calculate_job_matrix(job_data: Dict[str, Any]):
github_ctx = get_github_ctx()
run_type = find_run_type(github_ctx)
@ -197,7 +263,7 @@ if __name__ == "__main__":
jobs = []
if run_type is not None:
jobs = calculate_jobs(run_type, data)
jobs = calculate_jobs(run_type, job_data)
jobs = skip_jobs(jobs, channel)
if not jobs:
@ -208,3 +274,45 @@ if __name__ == "__main__":
logging.info(f"Output:\n{yaml.dump(dict(jobs=jobs, run_type=run_type), indent=4)}")
print(f"jobs={json.dumps(jobs)}")
print(f"run_type={run_type}")
def create_cli_parser():
parser = argparse.ArgumentParser(
prog="ci.py", description="Generate or run CI workflows"
)
subparsers = parser.add_subparsers(
help="Command to execute", dest="command", required=True
)
subparsers.add_parser(
"calculate-job-matrix",
help="Generate a matrix of jobs that should be executed in CI",
)
run_parser = subparsers.add_parser(
"run-local", help="Run a CI jobs locally (on Linux)"
)
run_parser.add_argument(
"job_name",
help="CI job that should be executed. By default, a merge (auto) "
"job with the given name will be executed",
)
run_parser.add_argument(
"--pr", action="store_true", help="Run a PR job instead of an auto job"
)
return parser
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
with open(JOBS_YAML_PATH) as f:
data = yaml.safe_load(f)
parser = create_cli_parser()
args = parser.parse_args()
if args.command == "calculate-job-matrix":
calculate_job_matrix(data)
elif args.command == "run-local":
run_workflow_locally(data, args.job_name, args.pr)
else:
raise Exception(f"Unknown command {args.command}")

View file

@ -91,26 +91,26 @@ envs:
# These jobs automatically inherit envs.pr, to avoid repeating
# it in each job definition.
pr:
- image: mingw-check
- name: mingw-check
<<: *job-linux-4c
- image: mingw-check-tidy
- name: mingw-check-tidy
continue_on_error: true
<<: *job-linux-4c
- image: x86_64-gnu-llvm-18
- name: x86_64-gnu-llvm-18
env:
ENABLE_GCC_CODEGEN: "1"
# We are adding (temporarily) a dummy commit on the compiler
READ_ONLY_SRC: "0"
DOCKER_SCRIPT: x86_64-gnu-llvm.sh
<<: *job-linux-16c
- image: x86_64-gnu-tools
- name: x86_64-gnu-tools
<<: *job-linux-16c
# Jobs that run when you perform a try build (@bors try)
# These jobs automatically inherit envs.try, to avoid repeating
# it in each job definition.
try:
- image: dist-x86_64-linux
- name: dist-x86_64-linux
env:
CODEGEN_BACKENDS: llvm,cranelift
<<: *job-linux-16c
@ -123,106 +123,106 @@ auto:
# Linux/Docker builders #
#############################
- image: aarch64-gnu
- name: aarch64-gnu
<<: *job-aarch64-linux
- image: aarch64-gnu-debug
- name: aarch64-gnu-debug
<<: *job-aarch64-linux
- image: arm-android
- name: arm-android
<<: *job-linux-4c
- image: armhf-gnu
- name: armhf-gnu
<<: *job-linux-4c
- image: dist-aarch64-linux
- name: dist-aarch64-linux
env:
CODEGEN_BACKENDS: llvm,cranelift
<<: *job-aarch64-linux
- name: dist-android
<<: *job-linux-4c
- image: dist-android
<<: *job-linux-4c
- image: dist-arm-linux
- name: dist-arm-linux
<<: *job-linux-8c
- image: dist-armhf-linux
- name: dist-armhf-linux
<<: *job-linux-4c
- image: dist-armv7-linux
- name: dist-armv7-linux
<<: *job-linux-4c
- image: dist-i586-gnu-i586-i686-musl
- name: dist-i586-gnu-i586-i686-musl
<<: *job-linux-4c
- image: dist-i686-linux
- name: dist-i686-linux
<<: *job-linux-4c
- image: dist-loongarch64-linux
- name: dist-loongarch64-linux
<<: *job-linux-4c
- image: dist-loongarch64-musl
- name: dist-loongarch64-musl
<<: *job-linux-4c
- image: dist-ohos
- name: dist-ohos
<<: *job-linux-4c
- image: dist-powerpc-linux
- name: dist-powerpc-linux
<<: *job-linux-4c
- image: dist-powerpc64-linux
- name: dist-powerpc64-linux
<<: *job-linux-4c
- image: dist-powerpc64le-linux
- name: dist-powerpc64le-linux
<<: *job-linux-4c-largedisk
- image: dist-riscv64-linux
- name: dist-riscv64-linux
<<: *job-linux-4c
- image: dist-s390x-linux
- name: dist-s390x-linux
<<: *job-linux-4c
- image: dist-various-1
- name: dist-various-1
<<: *job-linux-4c
- image: dist-various-2
- name: dist-various-2
<<: *job-linux-4c
- image: dist-x86_64-freebsd
- name: dist-x86_64-freebsd
<<: *job-linux-4c
- image: dist-x86_64-illumos
- name: dist-x86_64-illumos
<<: *job-linux-4c
- image: dist-x86_64-linux
- name: dist-x86_64-linux
env:
CODEGEN_BACKENDS: llvm,cranelift
<<: *job-linux-16c
- image: dist-x86_64-linux-alt
- name: dist-x86_64-linux-alt
env:
IMAGE: dist-x86_64-linux
CODEGEN_BACKENDS: llvm,cranelift
<<: *job-linux-16c
- image: dist-x86_64-musl
- name: dist-x86_64-musl
env:
CODEGEN_BACKENDS: llvm,cranelift
<<: *job-linux-4c
- image: dist-x86_64-netbsd
- name: dist-x86_64-netbsd
<<: *job-linux-4c
# The i686-gnu job is split into multiple jobs to run tests in parallel.
# i686-gnu-1 skips tests that run in i686-gnu-2.
- image: i686-gnu-1
- name: i686-gnu-1
env:
IMAGE: i686-gnu
DOCKER_SCRIPT: stage_2_test_set1.sh
<<: *job-linux-4c
# Skip tests that run in i686-gnu-1
- image: i686-gnu-2
- name: i686-gnu-2
env:
IMAGE: i686-gnu
DOCKER_SCRIPT: stage_2_test_set2.sh
@ -230,14 +230,14 @@ auto:
# The i686-gnu-nopt job is split into multiple jobs to run tests in parallel.
# i686-gnu-nopt-1 skips tests that run in i686-gnu-nopt-2
- image: i686-gnu-nopt-1
- name: i686-gnu-nopt-1
env:
IMAGE: i686-gnu-nopt
DOCKER_SCRIPT: /scripts/stage_2_test_set1.sh
<<: *job-linux-4c
# Skip tests that run in i686-gnu-nopt-1
- image: i686-gnu-nopt-2
- name: i686-gnu-nopt-2
env:
IMAGE: i686-gnu-nopt
DOCKER_SCRIPT: >-
@ -245,13 +245,13 @@ auto:
/scripts/stage_2_test_set2.sh
<<: *job-linux-4c
- image: mingw-check
- name: mingw-check
<<: *job-linux-4c
- image: test-various
- name: test-various
<<: *job-linux-4c
- image: x86_64-fuchsia
- name: x86_64-fuchsia
# Only run this job on the nightly channel. Fuchsia requires
# nightly features to compile, and this job would fail if
# executed on beta and stable.
@ -260,10 +260,10 @@ auto:
# Tests integration with Rust for Linux.
# Builds stage 1 compiler and tries to compile a few RfL examples with it.
- image: x86_64-rust-for-linux
- name: x86_64-rust-for-linux
<<: *job-linux-4c
- image: x86_64-gnu
- name: x86_64-gnu
<<: *job-linux-4c
# This job ensures commits landing on nightly still pass the full
@ -271,7 +271,7 @@ auto:
# depend on the channel being built (for example if they include the
# channel name on the output), and this builder prevents landing
# changes that would result in broken builds after a promotion.
- image: x86_64-gnu-stable
- name: x86_64-gnu-stable
# Only run this job on the nightly channel. Running this on beta
# could cause failures when `dev: 1` in `stage0.txt`, and running
# this on stable is useless.
@ -281,20 +281,20 @@ auto:
RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
<<: *job-linux-4c
- image: x86_64-gnu-aux
- name: x86_64-gnu-aux
<<: *job-linux-4c
- image: x86_64-gnu-debug
- name: x86_64-gnu-debug
# This seems to be needed because a full stage 2 build + run-make tests
# overwhelms the storage capacity of the standard 4c runner.
<<: *job-linux-4c-largedisk
- image: x86_64-gnu-distcheck
- name: x86_64-gnu-distcheck
<<: *job-linux-8c
# The x86_64-gnu-llvm-19 job is split into multiple jobs to run tests in parallel.
# x86_64-gnu-llvm-19-1 skips tests that run in x86_64-gnu-llvm-19-{2,3}.
- image: x86_64-gnu-llvm-19-1
- name: x86_64-gnu-llvm-19-1
env:
RUST_BACKTRACE: 1
IMAGE: x86_64-gnu-llvm-19
@ -302,7 +302,7 @@ auto:
<<: *job-linux-4c
# Skip tests that run in x86_64-gnu-llvm-19-{1,3}
- image: x86_64-gnu-llvm-19-2
- name: x86_64-gnu-llvm-19-2
env:
RUST_BACKTRACE: 1
IMAGE: x86_64-gnu-llvm-19
@ -310,7 +310,7 @@ auto:
<<: *job-linux-4c
# Skip tests that run in x86_64-gnu-llvm-19-{1,2}
- image: x86_64-gnu-llvm-19-3
- name: x86_64-gnu-llvm-19-3
env:
RUST_BACKTRACE: 1
IMAGE: x86_64-gnu-llvm-19
@ -319,7 +319,7 @@ auto:
# The x86_64-gnu-llvm-18 job is split into multiple jobs to run tests in parallel.
# x86_64-gnu-llvm-18-1 skips tests that run in x86_64-gnu-llvm-18-{2,3}.
- image: x86_64-gnu-llvm-18-1
- name: x86_64-gnu-llvm-18-1
env:
RUST_BACKTRACE: 1
READ_ONLY_SRC: "0"
@ -328,7 +328,7 @@ auto:
<<: *job-linux-4c
# Skip tests that run in x86_64-gnu-llvm-18-{1,3}
- image: x86_64-gnu-llvm-18-2
- name: x86_64-gnu-llvm-18-2
env:
RUST_BACKTRACE: 1
READ_ONLY_SRC: "0"
@ -337,7 +337,7 @@ auto:
<<: *job-linux-4c
# Skip tests that run in x86_64-gnu-llvm-18-{1,2}
- image: x86_64-gnu-llvm-18-3
- name: x86_64-gnu-llvm-18-3
env:
RUST_BACKTRACE: 1
READ_ONLY_SRC: "0"
@ -345,10 +345,10 @@ auto:
DOCKER_SCRIPT: x86_64-gnu-llvm3.sh
<<: *job-linux-4c
- image: x86_64-gnu-nopt
- name: x86_64-gnu-nopt
<<: *job-linux-4c
- image: x86_64-gnu-tools
- name: x86_64-gnu-tools
env:
DEPLOY_TOOLSTATES_JSON: toolstates-linux.json
<<: *job-linux-4c
@ -357,7 +357,7 @@ auto:
# macOS Builders #
####################
- image: dist-x86_64-apple
- name: dist-x86_64-apple
env:
SCRIPT: ./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin
RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1
@ -371,7 +371,7 @@ auto:
CODEGEN_BACKENDS: llvm,cranelift
<<: *job-macos-xl
- image: dist-apple-various
- name: dist-apple-various
env:
SCRIPT: ./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim,aarch64-apple-ios-macabi,x86_64-apple-ios-macabi
# Mac Catalyst cannot currently compile the sanitizer:
@ -385,19 +385,19 @@ auto:
NO_OVERFLOW_CHECKS: 1
<<: *job-macos-xl
- image: x86_64-apple-1
- name: x86_64-apple-1
env:
<<: *env-x86_64-apple-tests
<<: *job-macos-xl
- image: x86_64-apple-2
- name: x86_64-apple-2
env:
SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc
<<: *env-x86_64-apple-tests
<<: *job-macos-xl
# This target only needs to support 11.0 and up as nothing else supports the hardware
- image: dist-aarch64-apple
- name: dist-aarch64-apple
env:
SCRIPT: ./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin
RUST_CONFIGURE_ARGS: >-
@ -421,7 +421,7 @@ auto:
<<: *job-macos-m1
# This target only needs to support 11.0 and up as nothing else supports the hardware
- image: aarch64-apple
- name: aarch64-apple
env:
SCRIPT: ./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin
RUST_CONFIGURE_ARGS: >-
@ -442,20 +442,20 @@ auto:
# Windows Builders #
######################
- image: x86_64-msvc
- name: x86_64-msvc
env:
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler
SCRIPT: make ci-msvc
<<: *job-windows-8c
- image: i686-msvc
- name: i686-msvc
env:
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
SCRIPT: make ci-msvc
<<: *job-windows-8c
# x86_64-msvc-ext is split into multiple jobs to run tests in parallel.
- image: x86_64-msvc-ext1
- name: x86_64-msvc-ext1
env:
SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld
@ -464,7 +464,7 @@ auto:
# Temporary builder to workaround CI issues
# See <https://github.com/rust-lang/rust/issues/127883>
#FIXME: Remove this, and re-enable the same tests in `checktools.sh`, once CI issues are fixed.
- image: x86_64-msvc-ext2
- name: x86_64-msvc-ext2
env:
SCRIPT: >
python x.py test --stage 2 src/tools/miri --target aarch64-apple-darwin --test-args pass &&
@ -476,7 +476,7 @@ auto:
<<: *job-windows
# Run `checktools.sh` and upload the toolstate file.
- image: x86_64-msvc-ext3
- name: x86_64-msvc-ext3
env:
SCRIPT: src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows
HOST_TARGET: x86_64-pc-windows-msvc
@ -500,7 +500,7 @@ auto:
# came from the mingw-w64 SourceForge download site. Unfortunately
# SourceForge is notoriously flaky, so we mirror it on our own infrastructure.
- image: i686-mingw
- name: i686-mingw
env:
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
SCRIPT: make ci-mingw
@ -510,7 +510,7 @@ auto:
<<: *job-windows-8c
# x86_64-mingw is split into two jobs to run tests in parallel.
- image: x86_64-mingw-1
- name: x86_64-mingw-1
env:
SCRIPT: make ci-mingw-x
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
@ -519,7 +519,7 @@ auto:
NO_DOWNLOAD_CI_LLVM: 1
<<: *job-windows
- image: x86_64-mingw-2
- name: x86_64-mingw-2
env:
SCRIPT: make ci-mingw-bootstrap
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
@ -528,7 +528,7 @@ auto:
NO_DOWNLOAD_CI_LLVM: 1
<<: *job-windows
- image: dist-x86_64-msvc
- name: dist-x86_64-msvc
env:
RUST_CONFIGURE_ARGS: >-
--build=x86_64-pc-windows-msvc
@ -542,7 +542,7 @@ auto:
CODEGEN_BACKENDS: llvm,cranelift
<<: *job-windows-8c
- image: dist-i686-msvc
- name: dist-i686-msvc
env:
RUST_CONFIGURE_ARGS: >-
--build=i686-pc-windows-msvc
@ -555,7 +555,7 @@ auto:
CODEGEN_BACKENDS: llvm,cranelift
<<: *job-windows
- image: dist-aarch64-msvc
- name: dist-aarch64-msvc
env:
RUST_CONFIGURE_ARGS: >-
--build=x86_64-pc-windows-msvc
@ -567,7 +567,7 @@ auto:
DIST_REQUIRE_ALL_TOOLS: 1
<<: *job-windows
- image: dist-i686-mingw
- name: dist-i686-mingw
env:
RUST_CONFIGURE_ARGS: >-
--build=i686-pc-windows-gnu
@ -580,7 +580,7 @@ auto:
CODEGEN_BACKENDS: llvm,cranelift
<<: *job-windows
- image: dist-x86_64-mingw
- name: dist-x86_64-mingw
env:
SCRIPT: python x.py dist bootstrap --include-default-paths
RUST_CONFIGURE_ARGS: >-
@ -593,7 +593,7 @@ auto:
CODEGEN_BACKENDS: llvm,cranelift
<<: *job-windows
- image: dist-x86_64-msvc-alt
- name: dist-x86_64-msvc-alt
env:
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
SCRIPT: python x.py dist bootstrap --include-default-paths

View file

@ -70,46 +70,21 @@ $ ENABLE_LINKCHECK=1 mdbook serve
We use `mdbook-toc` to auto-generate TOCs for long sections. You can invoke the preprocessor by
including the `<!-- toc -->` marker at the place where you want the TOC.
## How to fix toolstate failures
## Synchronizing josh subtree with rustc
> [!NOTE]
> Currently, we do not track the rustc-dev-guide toolstate due to
> [spurious failures](https://github.com/rust-lang/rust/pull/71731),
> but we leave these instructions for when we do it again in the future.
This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the following commands to synchronize the subtree in both directions.
1. You will get a ping from the toolstate commit. e.g. https://github.com/rust-lang-nursery/rust-toolstate/commit/8ffa0e4c30ac9ba8546b7046e5c4ccc2b96ebdd4
### Pull changes from `rust-lang/rust` into this repository
1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide`
2) Run the pull command
```
$ cargo run --manifest-path josh-sync/Cargo.toml rustc-pull
```
3) Push the branch to your fork and create a PR into `rustc-dev-guide`
2. The commit contains a link to the PR that caused the breakage. e.g. https://github.com/rust-lang/rust/pull/64321
3. If you go to that PR's thread, there is a post from bors with a link to the CI status: https://github.com/rust-lang/rust/pull/64321#issuecomment-529763807
4. Follow the check-actions link to get to the Actions page for that build
5. There will be approximately 1 billion different jobs for the build. They are for different configurations and platforms. The rustc-dev-guide build only runs on the Linux x86_64-gnu-tools job. So click on that job in the list, which is about 60% down in the list.
6. Click the Run build step in the job to get the console log for the step.
7. Click on the log and Ctrl-f to get a search box in the log
8. Search for rustc-dev-guide. This gets you to the place where the links are checked. It is usually ~11K lines into the log.
9. Look at the links in the log near that point in the log
10. Fix those links in the rustc-dev-guide (by making a PR in the rustc-dev-guide repo)
11. Make a PR on the rust-lang/rust repo to update the rustc-dev-guide git submodule in src/docs/rustc-dev-guide.
To make a PR, the following steps are useful.
```bash
# Assuming you already cloned the rust-lang/rust repo and you're in the correct directory
git submodule update --remote src/doc/rustc-dev-guide
git add -u
git commit -m "Update rustc-dev-guide"
# Note that you can use -i, which is short for --incremental, in the following command
./x test --incremental src/doc/rustc-dev-guide # This is optional and should succeed anyway
# Open a PR in rust-lang/rust
```
12. Wait for PR to merge
Voilà!
### Push changes from this repository into `rust-lang/rust`
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>
```
2) Create a PR from `<branch-name>` into `rust-lang/rust`

View file

@ -0,0 +1,430 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
dependencies = [
"anstyle",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "directories"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.48.0",
]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "josh-sync"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"directories",
"xshell",
]
[[package]]
name = "libc"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "proc-macro2"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_users"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[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.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[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.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[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.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "xshell"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e7290c623014758632efe00737145b6867b66292c42167f2ec381eb566a373d"
dependencies = [
"xshell-macros",
]
[[package]]
name = "xshell-macros"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32ac00cd3f8ec9c1d33fb3e7958a82df6989c42d747bd326c822b1d625283547"

View file

@ -0,0 +1,10 @@
[package]
name = "josh-sync"
version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.95"
clap = { version = "4.5.21", features = ["derive"] }
directories = "5"
xshell = "0.2.6"

View file

@ -0,0 +1,4 @@
# Git josh sync
This utility serves for syncing the josh git subtree to and from the rust-lang/rust repository.
See CLI help for usage.

View file

@ -0,0 +1,32 @@
use clap::Parser;
use crate::sync::GitSync;
mod sync;
#[derive(clap::Parser)]
enum Args {
/// Pull changes from the main `rustc` repository.
/// This creates new commits that should be then merged into `rustc-dev-guide`.
RustcPull,
/// 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
}
}
fn main() -> anyhow::Result<()> {
let args = Args::parse();
let sync = GitSync::from_current_dir()?;
match args {
Args::RustcPull => {
sync.rustc_pull(None)?;
}
Args::RustcPush { github_username, branch } => {
sync.rustc_push(github_username, branch)?;
}
}
Ok(())
}

View file

@ -0,0 +1,234 @@
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};
/// Used for rustc syncs.
const JOSH_FILTER: &str = ":/src/doc/rustc-dev-guide";
const JOSH_PORT: u16 = 42042;
const UPSTREAM_REPO: &str = "rust-lang/rust";
pub struct GitSync {
dir: PathBuf,
}
/// This code was adapted from the miri repository
/// (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()?
})
}
pub fn rustc_pull(&self, commit: Option<String>) -> anyhow::Result<()> {
let sh = Shell::new()?;
sh.change_dir(&self.dir);
let commit = commit.map(Ok).unwrap_or_else(|| {
let rust_repo_head =
cmd!(sh, "git ls-remote https://github.com/{UPSTREAM_REPO}/ HEAD").read()?;
rust_repo_head
.split_whitespace()
.next()
.map(|front| front.trim().to_owned())
.ok_or_else(|| anyhow!("Could not obtain Rust repo HEAD from remote."))
})?;
// Make sure the repo is clean.
if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() {
bail!("working directory must be clean before performing rustc pull");
}
// Make sure josh is running.
let josh = Self::start_josh()?;
let josh_url =
format!("http://localhost:{JOSH_PORT}/{UPSTREAM_REPO}.git@{commit}{JOSH_FILTER}.git");
// Update rust-version file. As a separate commit, since making it part of
// the merge has confused the heck out of josh in the past.
// We pass `--no-verify` to avoid running git hooks.
// We do this before the merge so that if there are merge conflicts, we have
// the right rust-version file while resolving them.
sh.write_file("rust-version", format!("{commit}\n"))?;
const PREPARING_COMMIT_MESSAGE: &str = "Preparing for merge from rustc";
cmd!(sh, "git commit rust-version --no-verify -m {PREPARING_COMMIT_MESSAGE}")
.run()
.context("FAILED to commit rust-version file, something went wrong")?;
// Fetch given rustc commit.
cmd!(sh, "git fetch {josh_url}")
.run()
.inspect_err(|_| {
// Try to un-do the previous `git commit`, to leave the repo in the state we found it.
cmd!(sh, "git reset --hard HEAD^")
.run()
.expect("FAILED to clean up again after failed `git fetch`, sorry for that");
})
.context("FAILED to fetch new commits, something went wrong (committing the rust-version file has been undone)")?;
// This should not add any new root commits. So count those before and after merging.
let num_roots = || -> anyhow::Result<u32> {
Ok(cmd!(sh, "git rev-list HEAD --max-parents=0 --count")
.read()
.context("failed to determine the number of root commits")?
.parse::<u32>()?)
};
let num_roots_before = num_roots()?;
// Merge the fetched commit.
const MERGE_COMMIT_MESSAGE: &str = "Merge from rustc";
cmd!(sh, "git merge FETCH_HEAD --no-verify --no-ff -m {MERGE_COMMIT_MESSAGE}")
.run()
.context("FAILED to merge new commits, something went wrong")?;
// Check that the number of roots did not increase.
if num_roots()? != num_roots_before {
bail!("Josh created a new root commit. This is probably not the history you want.");
}
drop(josh);
Ok(())
}
pub fn rustc_push(&self, github_user: String, branch: String) -> anyhow::Result<()> {
let sh = Shell::new()?;
sh.change_dir(&self.dir);
let base = sh.read_file("rust-version")?.trim().to_owned();
// Make sure the repo is clean.
if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() {
bail!("working directory must be clean before running `rustc-push`");
}
// Make sure josh is running.
let josh = Self::start_josh()?;
let josh_url =
format!("http://localhost:{JOSH_PORT}/{github_user}/rust.git{JOSH_FILTER}.git");
// Find a repo we can do our preparation in.
if let Ok(rustc_git) = env::var("RUSTC_GIT") {
// If rustc_git is `Some`, we'll use an existing fork for the branch updates.
sh.change_dir(rustc_git);
} else {
// Otherwise, do this in the local repo.
println!(
"This will pull a copy of the rust-lang/rust history into this checkout, growing it by about 1GB."
);
print!(
"To avoid that, abort now and set the `RUSTC_GIT` environment variable to an existing rustc checkout. Proceed? [y/N] "
);
std::io::stdout().flush()?;
let mut answer = String::new();
std::io::stdin().read_line(&mut answer)?;
if answer.trim().to_lowercase() != "y" {
std::process::exit(1);
}
};
// Prepare the branch. Pushing works much better if we use as base exactly
// the commit that we pulled from last time, so we use the `rust-version`
// file to find out which commit that would be.
println!("Preparing {github_user}/rust (base: {base})...");
if cmd!(sh, "git fetch https://github.com/{github_user}/rust {branch}")
.ignore_stderr()
.read()
.is_ok()
{
println!(
"The branch '{branch}' seems to already exist in 'https://github.com/{github_user}/rust'. Please delete it and try again."
);
std::process::exit(1);
}
cmd!(sh, "git fetch https://github.com/{UPSTREAM_REPO} {base}").run()?;
cmd!(sh, "git push https://github.com/{github_user}/rust {base}:refs/heads/{branch}")
.ignore_stdout()
.ignore_stderr() // silence the "create GitHub PR" message
.run()?;
println!();
// Do the actual push.
sh.change_dir(&self.dir);
println!("Pushing changes...");
cmd!(sh, "git push {josh_url} HEAD:{branch}").run()?;
println!();
// Do a round-trip check to make sure the push worked as expected.
cmd!(sh, "git fetch {josh_url} {branch}").ignore_stderr().read()?;
let head = cmd!(sh, "git rev-parse HEAD").read()?;
let fetch_head = cmd!(sh, "git rev-parse FETCH_HEAD").read()?;
if head != fetch_head {
bail!(
"Josh created a non-roundtrip push! Do NOT merge this into rustc!\n\
Expected {head}, got {fetch_head}."
);
}
println!(
"Confirmed that the push round-trips back to rustc-dev-guide properly. Please create a rustc PR:"
);
println!(
// Open PR with `subtree update` title to silence the `no-merges` triagebot check
" https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=Rustc+dev+guide+subtree+update&body=r?+@ghost"
);
drop(josh);
Ok(())
}
fn start_josh() -> anyhow::Result<impl Drop> {
// Determine cache directory.
let local_dir = {
let user_dirs =
directories::ProjectDirs::from("org", "rust-lang", "rustc-dev-guide-josh").unwrap();
user_dirs.cache_dir().to_owned()
};
// Start josh, silencing its output.
let mut cmd = process::Command::new("josh-proxy");
cmd.arg("--local").arg(local_dir);
cmd.arg("--remote").arg("https://github.com");
cmd.arg("--port").arg(JOSH_PORT.to_string());
cmd.arg("--no-background");
cmd.stdout(process::Stdio::null());
cmd.stderr(process::Stdio::null());
let josh = cmd.spawn().context("failed to start josh-proxy, make sure it is installed")?;
// Create a wrapper that stops it on drop.
struct Josh(process::Child);
impl Drop for Josh {
fn drop(&mut self) {
#[cfg(unix)]
{
// Try to gracefully shut it down.
process::Command::new("kill")
.args(["-s", "INT", &self.0.id().to_string()])
.output()
.expect("failed to SIGINT josh-proxy");
// Sadly there is no "wait with timeout"... so we just give it some time to finish.
std::thread::sleep(Duration::from_millis(100));
// Now hopefully it is gone.
if self.0.try_wait().expect("failed to wait for josh-proxy").is_some() {
return;
}
}
// If that didn't work (or we're not on Unix), kill it hard.
eprintln!(
"I have to kill josh-proxy the hard way, let's hope this does not break anything."
);
self.0.kill().expect("failed to SIGKILL josh-proxy");
}
}
// Wait until the port is open. We try every 10ms until 1s passed.
for _ in 0..100 {
// This will generally fail immediately when the port is still closed.
let josh_ready = net::TcpStream::connect_timeout(
&net::SocketAddr::from(([127, 0, 0, 1], JOSH_PORT)),
Duration::from_millis(1),
);
if josh_ready.is_ok() {
return Ok(Josh(josh));
}
// Not ready yet.
std::thread::sleep(Duration::from_millis(10));
}
bail!("Even after waiting for 1s, josh-proxy is still not available.")
}
}

View file

@ -0,0 +1 @@
dcfa38fe234de9304169afc6638e81d0dd222c06

View file

@ -134,14 +134,13 @@
- [Prologue](./part-4-intro.md)
- [Generic parameter definitions](./generic_parameters_summary.md)
- [Implementation nuances of early/late bound parameters](./early-late-bound-params/early-late-bound-implementation-nuances.md)
- [Interactions with turbofishing](./early-late-bound-params/turbofishing-and-early-late-bound.md)
- [`EarlyBinder` and instantiating parameters](./ty_module/early_binder.md)
- [Binders and Higher ranked regions](./ty_module/binders.md)
- [Instantiating binders](./ty_module/instantiating_binders.md)
- [Early vs Late bound parameters](./early_late_parameters.md)
- [The `ty` module: representing types](./ty.md)
- [ADTs and Generic Arguments](./ty_module/generic_arguments.md)
- [Parameter types/consts/regions](./ty_module/param_ty_const_regions.md)
- [`EarlyBinder` and instantiating parameters](./ty_module/early_binder.md)
- [`Binder` and Higher ranked regions](./ty_module/binders.md)
- [Instantiating binders](./ty_module/instantiating_binders.md)
- [`TypeFolder` and `TypeFoldable`](./ty-fold.md)
- [Parameter Environments](./param_env/param_env_summary.md)
- [What is it?](./param_env/param_env_what_is_it.md)

View file

@ -56,7 +56,7 @@ These tools include:
By default, the Rust build system does not check for changes to the LLVM source code or
its build configuration settings. So, if you need to rebuild the LLVM that is linked
into `rustc`, first delete the file `llvm-finished-building`, which should be located
into `rustc`, first delete the file `.llvm-stamp`, which should be located
in `build/<host-triple>/llvm/`.
The default rustc compilation pipeline has multiple codegen units, which is

View file

@ -126,4 +126,4 @@ Here is an example of how can `opt-dist` be used locally (outside of CI):
[`Environment`]: https://github.com/rust-lang/rust/blob/ee451f8faccf3050c76cdcd82543c917b40c7962/src/tools/opt-dist/src/environment.rs#L5
> Note: if you want to run the actual CI pipeline, instead of running `opt-dist` locally,
> you can execute `DEPLOY=1 src/ci/docker/run.sh dist-x86_64-linux`.
> you can execute `python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux`.

View file

@ -1,197 +0,0 @@
# Early and Late Bound Parameter Implementation Nuances
> Note: this chapter makes reference to information discussed later on in the [representing types][ch_representing_types] chapter. Specifically, it uses concise notation to represent some more complex kinds of types that have not yet been discussed, such as inference variables.
[ch_representing_types]: ../ty.md
Understanding this page likely requires a rudimentary understanding of higher ranked
trait bounds/`for<'a>`and also what types such as `dyn for<'a> Trait<'a>` and
`for<'a> fn(&'a u32)` mean. Reading [the nomincon chapter](https://doc.rust-lang.org/nomicon/hrtb.html)
on HRTB may be useful for understanding this syntax. The meaning of `for<'a> fn(&'a u32)`
is incredibly similar to the meaning of `T: for<'a> Trait<'a>`.
## What does it mean for parameters to be early or late bound
All function definitions conceptually have a ZST (this is represented by `TyKind::FnDef` in rustc).
The only generics on this ZST are the early bound parameters of the function definition. e.g.
```rust
fn foo<'a>(_: &'a u32) {}
fn main() {
let b = foo;
// ^ `b` has type `FnDef(foo, [])` (no args because `'a` is late bound)
assert!(std::mem::size_of_val(&b) == 0);
}
```
In order to call `b` the late bound parameters do need to be provided, these are inferred at the
call site instead of when we refer to `foo`.
```rust
fn main() {
let b = foo;
let a: &'static u32 = &10;
foo(a);
// the lifetime argument for `'a` on `foo` is inferred at the callsite
// the generic parameter `'a` on `foo` is inferred to `'static` here
}
```
Because late bound parameters are not part of the `FnDef`'s args this allows us to prove trait
bounds such as `F: for<'a> Fn(&'a u32)` where `F` is `foo`'s `FnDef`. e.g.
```rust
fn foo_early<'a, T: Trait<'a>>(_: &'a u32, _: T) {}
fn foo_late<'a, T>(_: &'a u32, _: T) {}
fn accepts_hr_func<F: for<'a> Fn(&'a u32, u32)>(_: F) {}
fn main() {
// doesn't work, the instantiated bound is `for<'a> FnDef<'?0>: Fn(&'a u32, u32)`
// `foo_early` only implements `for<'a> FnDef<'a>: Fn(&'a u32, u32)`- the lifetime
// of the borrow in the function argument must be the same as the lifetime
// on the `FnDef`.
accepts_hr_func(foo_early);
// works, the instantiated bound is `for<'a> FnDef: Fn(&'a u32, u32)`
accepts_hr_func(foo_late);
}
// the builtin `Fn` impls for `foo_early` and `foo_late` look something like:
// `foo_early`
impl<'a, T: Trait<'a>> Fn(&'a u32, T) for FooEarlyFnDef<'a, T> { ... }
// `foo_late`
impl<'a, T> Fn(&'a u32, T) for FooLateFnDef<T> { ... }
```
Early bound parameters are present on the `FnDef`. Late bound generic parameters are not present
on the `FnDef` but are instead constrained by the builtin `Fn*` impl.
The same distinction applies to closures. Instead of `FnDef` we are talking about the anonymous
closure type. Closures are [currently unsound](https://github.com/rust-lang/rust/issues/84366) in
ways that are closely related to the distinction between early/late bound
parameters (more on this later)
The early/late boundness of generic parameters is only relevant for the desugaring of
functions/closures into types with builtin `Fn*` impls. It does not make sense to talk about
in other contexts.
The `generics_of` query in rustc only contains early bound parameters. In this way it acts more
like `generics_of(my_func)` is the generics for the FnDef than the generics provided to the function
body although it's not clear to the author of this section if this was the actual justification for
making `generics_of` behave this way.
## What parameters are currently late bound
Below are the current requirements for determining if a generic parameter is late bound. It is worth
keeping in mind that these are not necessarily set in stone and it is almost certainly possible to
be more flexible.
### Must be a lifetime parameter
Rust can't support types such as `for<T> dyn Trait<T>` or `for<T> fn(T)`, this is a
fundamental limitation of the language as we are required to monomorphize type/const
parameters and cannot do so behind dynamic dispatch. (technically we could probably
support `for<T> dyn MarkerTrait<T>` as there is nothing to monomorphize)
Not being able to support `for<T> dyn Trait<T>` resulted in making all type and const
parameters early bound. Only lifetime parameters can be late bound.
### Must not appear in the where clauses
In order for a generic parameter to be late bound it must not appear in any where clauses.
This is currently an incredibly simplistic check that causes lifetimes to be early bound even
if the where clause they appear in are always true, or implied by well formedness of function
arguments. e.g.
```rust
fn foo1<'a: 'a>(_: &'a u32) {}
// ^^ early bound parameter because it's in a `'a: 'a` clause
// even though the bound obviously holds all the time
fn foo2<'a, T: Trait<'a>(a: T, b: &'a u32) {}
// ^^ early bound parameter because it's used in the `T: Trait<'a>` clause
fn foo3<'a, T: 'a>(_: &'a T) {}
// ^^ early bound parameter because it's used in the `T: 'a` clause
// even though that bound is implied by wellformedness of `&'a T`
fn foo4<'a, 'b: 'a>(_: Inv<&'a ()>, _: Inv<&'b ()>) {}
// ^^ ^^ ^^^ note:
// ^^ ^^ `Inv` stands for `Invariant` and is used to
// ^^ ^^ make the type parameter invariant. This
// ^^ ^^ is necessary for demonstration purposes as
// ^^ ^^ `for<'a, 'b> fn(&'a (), &'b ())` and
// ^^ ^^ `for<'a> fn(&'a u32, &'a u32)` are subtypes-
// ^^ ^^ of each other which makes the bound trivially
// ^^ ^^ satisfiable when making the fnptr. `Inv`
// ^^ ^^ disables this subtyping.
// ^^ ^^
// ^^^^^^ both early bound parameters because they are present in the
// `'b: 'a` clause
```
The reason for this requirement is that we cannot represent the `T: Trait<'a>` or `'a: 'b` clauses
on a function pointer. `for<'a, 'b> fn(Inv<&'a ()>, Inv<&'b ()>)` is not a valid function pointer to
represent`foo4` as it would allow calling the function without `'b: 'a` holding.
### Must be constrained by where clauses or function argument types
The builtin impls of the `Fn*` traits for closures and `FnDef`s cannot not have any unconstrained
parameters. For example the following impl is illegal:
```rust
impl<'a> Trait for u32 { type Assoc = &'a u32; }
```
We must not end up with a similar impl for the `Fn*` traits e.g.
```rust
impl<'a> Fn<()> for FnDef { type Assoc = &'a u32 }
```
Violating this rule can trivially lead to unsoundness as seen in [#84366](https://github.com/rust-lang/rust/issues/84366).
Additionally if we ever support late bound type params then an impl like:
```rust
impl<T> Fn<()> for FnDef { type Assoc = T; }
```
would break the compiler in various ways.
In order to ensure that everything functions correctly, we do not allow generic parameters to
be late bound if it would result in a builtin impl that does not constrain all of the generic
parameters on the builtin impl. Making a generic parameter be early bound trivially makes it be
constrained by the builtin impl as it ends up on the self type.
Because of the requirement that late bound parameters must not appear in where clauses, checking
this is simpler than the rules for checking impl headers constrain all the parameters on the impl.
We only have to ensure that all late bound parameters appear at least once in the function argument
types outside of an alias (e.g. an associated type).
The requirement that they not indirectly be in the args of an alias for it to count is the
same as why the follow code is forbidden:
```rust
impl<T: Trait> OtherTrait for <T as Trait>::Assoc { type Assoc = T }
```
There is no guarantee that `<T as Trait>::Assoc` will normalize to different types for every
instantiation of `T`. If we were to allow this impl we could get overlapping impls and the
same is true of the builtin `Fn*` impls.
## Making more generic parameters late bound
It is generally considered desirable for more parameters to be late bound as it makes
the builtin `Fn*` impls more flexible. Right now many of the requirements for making
a parameter late bound are overly restrictive as they are tied to what we can currently
(or can ever) do with fn ptrs.
It would be theoretically possible to support late bound params in `where`-clauses in the
language by introducing implication types which would allow us to express types such as:
`for<'a, 'b: 'a> fn(Inv<&'a u32>, Inv<&'b u32>)` which would ensure `'b: 'a` is upheld when
calling the function pointer.
It would also be theoretically possible to support it by making the coercion to a fn ptr
instantiate the parameter with an infer var while still allowing the FnDef to not have the
generic parameter present as trait impls are perfectly capable of representing the where clauses
on the function on the impl itself. This would also allow us to support late bound type/const
vars allowing bounds like `F: for<T> Fn(T)` to hold.
It is almost somewhat unclear if we can change the `Fn` traits to be structured differently
so that we never have to make a parameter early bound just to make the builtin impl have all
generics be constrained. Of all the possible causes of a generic parameter being early bound
this seems the most difficult to remove.
Whether these would be good ideas to implement is a separate question- they are only brought
up to illustrate that the current rules are not necessarily set in stone and a result of
"its the only way of doing this".

View file

@ -1,125 +0,0 @@
# Turbofishing's interactions with early/late bound parameters
> Note: this chapter makes reference to information discussed later on in the [representing types][ch_representing_types] chapter. Specifically, it uses concise notation to represent some more complex kinds of types that have not yet been discussed, such as inference variables.
[ch_representing_types]: ../ty.md
The early/late bound parameter distinction on functions introduces some complications
when providing generic arguments to functions. This document discusses what those are
and how they might interact with future changes to make more things late bound.
## Can't turbofish generic arguments on functions sometimes
When a function has any late bound lifetime parameters (be they explicitly defined or
implicitly introduced via lifetime elision) we disallow specifying any lifetime arguments
on the function. Sometimes this is a hard error other times it is a future compat lint
([`late_bound_lifetime_arguments`](https://github.com/rust-lang/rust/issues/42868)).
```rust
fn early<'a: 'a>(a: &'a ()) -> &'a () { a }
fn late<'a>(a: &'a ()) -> &'a () { a }
fn mixed<'a, 'b: 'b>(a: &'a (), b: &'b ()) -> &'a () { a }
struct Foo;
impl Foo {
fn late<'a>(self, a: &'a ()) -> &'a () { a }
}
fn main() {
// fine
let f = early::<'static>;
// some variation of hard errors and future compat lints
Foo.late::<'static>(&());
let f = late::<'static>;
let f = mixed::<'static, 'static>;
let f = mixed::<'static>;
late::<'static>(&());
}
```
The justification for this is that late bound parameters are not present on the
`FnDef` so the arguments to late bound parameters can't be present in the generic arguments
for the type. i.e. the `late` function in the above code snippet would not have
any generic parameters on the `FnDef` zst:
```rust
// example desugaring of the `late` function and its zst + builtin Fn impl
struct LateFnDef;
impl<'a> Fn<(&'a ())> for LateFnDef {
type Output = &'a ();
...
}
```
The cause for some situations giving future compat lints and others giving hard errors
is a little arbitrary but explainable:
- It's always a hard error for method calls
- It's only a hard error on paths to free functions if there is no unambiguous way to
create the generic arguments for the fndef from the lifetime arguments. (i.e. the amount of
lifetimes provided must be exactly equal to the amount of early bound lifetimes or
else it's a hard error)
## Back compat issues from turning early bound to late bound
Because of the previously mentioned restriction on turbofishing generic arguments, it
is a breaking change to upgrade a lifetime from early bound to late bound as it can cause
existing turbofishies to become hard errors/future compat lints.
Many t-types members have expressed interest in wanting more parameters to be late bound.
We cannot do so if making something late bound is going to break code that many would
expect to work (judging by the future compat lint issue many people do expect to be able
to turbofish late bound parameters).
## Interactions with late bound type/const parameters
If we were to make some type/const parameters late bound we would definitely not want
to disallow turbofishing them as it presumably(?) would break a Tonne of code.
While lifetimes do differ from type/consts in some ways I(BoxyUwU) do not believe there
is any justification for why it would make sense to allow turbofishing late bound
type/const parameters but not late bound lifetimes.
## Removing the hard error/fcw
From reasons above it seems reasonable that we may want to remove the hard error and fcw
(removing the errors/fcw is definitely a blocker for making more things late bound).
example behaviour:
```rust
fn late<'a>(a: &'a ()) -> &'a () { a }
fn accepts_fn(_: impl for<'a> Fn(&'a ()) -> &'a ()) {}
fn accepts_fn_2(_: impl Fn(&'static ()) -> &'static ()) {}
fn main() {
let f = late::<'static>;
accepts_fn(f); //~ error: `f` doesn't implement `for<'a> Fn(&'a ()) -> &'a ()`
accepts_fn_2(f) // works
accepts_fn(late) // works
}
````
one potential complication is that we would want a way to specify a generic argument
to a function without having to specify arguments for all previous parameters. i.e.
ideally you could write the following code somehow.
```rust
fn late<'a, 'b>(_: &'a (), _: &'b ()) {}
fn accepts_fn(_: impl for<'a> Fn(&'a (), &'static ())) {}
fn main() {
// a naive implementation would have an inference variable as
// the argument to the `'a` parameter no longer allowing the `FnDef`
// to satisfy the bound `for<'a> Fn(&'a ())`
let f = late::<'_, 'static>;
accepts_fn(f);
}
```
Maybe we can just special case HIR ty lowering for `_`/`'_` arguments for late bound
parameters somehow and have it not mean the same thing as `_` for early bound parameters.
Regardless I think we would need a solution that would allow writing the above code even
if it was done by some new syntax such as having to write `late::<k#no_argument, 'static>`
(naturally `k#no_argument` would only make sense as an argument to late bound parameters).

View file

@ -0,0 +1,424 @@
# Early vs Late bound parameters
<!-- toc -->
> **NOTE**: This chapter largely talks about early/late bound as being solely relevant when discussing function item types/function definitions. This is potentially not completely true, async blocks and closures should likely be discussed somewhat in this chapter.
## What does it mean to be "early" bound or "late" bound
Every function definition has a corresponding ZST that implements the `Fn*` traits known as a [function item type][function_item_type]. This part of the chapter will talk a little bit about the "desugaring" of function item types as it is useful context for explaining the difference between early bound and late bound generic parameters.
Let's start with a very trivial example involving no generic parameters:
```rust
fn foo(a: String) -> u8 {
# 1
/* snip */
}
```
If we explicitly wrote out the definitions for the function item type corresponding to `foo` and its associated `Fn` impl it would look something like this:
```rust,ignore
struct FooFnItem;
impl Fn<(String,)> for FooFnItem {
type Output = u8;
/* fn call(&self, ...) -> ... { ... } */
}
```
The builtin impls for the `FnMut`/`FnOnce` traits as well as the impls for `Copy` and `Clone` were omitted for brevity reasons (although these traits *are* implemented for function item types).
A slightly more complicated example would involve introducing generic parameters to the function:
```rust
fn foo<T: Sized>(a: T) -> T {
# a
/* snip */
}
```
Writing out the definitions would look something like this:
```rust,ignore
struct FooFnItem<T: Sized>(PhantomData<fn(T) -> T>);
impl<T: Sized> Fn<(T,)> for FooFnItem<T> {
type Output = T;
/* fn call(&self, ...) -> ... { ... } */
}
```
Note that the function item type `FooFnItem` is generic over some type parameter `T` as defined on the function `foo`. However, not all generic parameters defined on functions are also defined on the function item type as demonstrated here:
```rust
fn foo<'a, T: Sized>(a: &'a T) -> &'a T {
# a
/* snip */
}
```
With its "desugared" form looking like so:
```rust,ignore
struct FooFnItem<T: Sized>(PhantomData<for<'a> fn(&'a T) -> &'a T>);
impl<'a, T: Sized> Fn<(&'a T,)> for FooFnItem<T> {
type Output = &'a T;
/* fn call(&self, ...) -> ... { ... } */
}
```
The lifetime parameter `'a` from the function `foo` is not present on the function item type `FooFnItem` and is instead introduced on the builtin impl solely for use in representing the argument types.
Generic parameters not all being defined on the function item type means that there are two steps where generic arguments are provided when calling a function.
1. Naming the function (e.g. `let a = foo;`) the arguments for `FooFnItem` are provided.
2. Calling the function (e.g. `a(&10);`) any parameters defined on the builtin impl are provided.
This two-step system is where the early vs late naming scheme comes from, early bound parameters are provided in the *earliest* step (naming the function), whereas late bound parameters are provided in the *latest* step (calling the function).
Looking at the desugaring from the previous example we can tell that `T` is an early bound type parameter and `'a` is a late bound lifetime parameter as `T` is present on the function item type but `'a` is not. See this example of calling `foo` annotated with where each generic parameter has an argument provided:
```rust
fn foo<'a, T: Sized>(a: &'a T) -> &'a T {
# a
/* snip */
}
// Here we provide a type argument `String` to the
// type parameter `T` on the function item type
let my_func = foo::<String>;
// Here (implicitly) a lifetime argument is provided
// to the lifetime parameter `'a` on the builtin impl.
my_func(&String::new());
```
[function_item_type]: https://doc.rust-lang.org/reference/types/function-item.html
## Differences between early and late bound parameters
### Higher ranked function pointers and trait bounds
A generic parameter being late bound allows for more flexible usage of the function item. For example if we have some function `foo` with an early bound lifetime parameter and some function `bar` with a late bound lifetime parameter `'a` we would have the following builtin `Fn` impls:
```rust,ignore
impl<'a> Fn<(&'a String,)> for FooFnItem<'a> { /* ... */ }
impl<'a> Fn<(&'a String,)> for BarFnItem { /* ... */ }
```
The `bar` function has a strictly more flexible signature as the function item type can be called with a borrow with *any* lifetime, whereas the `foo` function item type would only be callable with a borrow with the same lifetime on the function item type. We can show this by simply trying to call `foo`'s function item type multiple times with different lifetimes:
```rust
// The `'a: 'a` bound forces this lifetime to be early bound.
fn foo<'a: 'a>(b: &'a String) -> &'a String { b }
fn bar<'a>(b: &'a String) -> &'a String { b }
// Early bound generic parameters are instantiated here when naming
// the function `foo`. As `'a` is early bound an argument is provided.
let f = foo::<'_>;
// Both function arguments are required to have the same lifetime as
// the lifetime parameter being early bound means that `f` is only
// callable for one specific lifetime.
//
// As we call this with borrows of different lifetimes, the borrow checker
// will error here.
f(&String::new());
f(&String::new());
```
In this example we call `foo`'s function item type twice, each time with a borrow of a temporary. These two borrows could not possible have lifetimes that overlap as the temporaries are only alive during the function call, not after. The lifetime parameter on `foo` being early bound requires all callers of `f` to provide a borrow with the same lifetime, as this is not possible the borrow checker errors.
If the lifetime parameter on `foo` was late bound this would be able to compile as each caller could provide a different lifetime argument for its borrow. See the following example which demonstrates this using the `bar` function defined above:
```rust
#fn foo<'a: 'a>(b: &'a String) -> &'a String { b }
#fn bar<'a>(b: &'a String) -> &'a String { b }
// Early bound parameters are instantiated here, however as `'a` is
// late bound it is not provided here.
let b = bar;
// Late bound parameters are instantiated separately at each call site
// allowing different lifetimes to be used by each caller.
b(&String::new());
b(&String::new());
```
This is reflected in the ability to coerce function item types to higher ranked function pointers and prove higher ranked `Fn` trait bounds. We can demonstrate this with the following example:
```rust
// The `'a: 'a` bound forces this lifetime to be early bound.
fn foo<'a: 'a>(b: &'a String) -> &'a String { b }
fn bar<'a>(b: &'a String) -> &'a String { b }
fn accepts_hr_fn(_: impl for<'a> Fn(&'a String) -> &'a String) {}
fn higher_ranked_trait_bound() {
let bar_fn_item = bar;
accepts_hr_fn(bar_fn_item);
let foo_fn_item = foo::<'_>;
// errors
accepts_hr_fn(foo_fn_item);
}
fn higher_ranked_fn_ptr() {
let bar_fn_item = bar;
let fn_ptr: for<'a> fn(&'a String) -> &'a String = bar_fn_item;
let foo_fn_item = foo::<'_>;
// errors
let fn_ptr: for<'a> fn(&'a String) -> &'a String = foo_fn_item;
}
```
In both of these cases the borrow checker errors as it does not consider `foo_fn_item` to be callable with a borrow of any lifetime. This is due to the fact that the lifetime parameter on `foo` is early bound, causing `foo_fn_item` to have a type of `FooFnItem<'_>` which (as demonstrated by the desugared `Fn` impl) is only callable with a borrow of the same lifetime `'_`.
### Turbofishing in the presence of late bound parameters
As mentioned previously, the distinction between early and late bound parameters means that there are two places where generic parameters are instantiated:
- When naming a function (early)
- When calling a function (late)
There currently is no syntax for explicitly specifying generic arguments for late bound parameters as part of the call step, only specifying generic arguments when naming a function. The syntax `foo::<'static>();`, despite being part of a function call, behaves as `(foo::<'static>)();` and instantiates the early bound generic parameters on the function item type.
See the following example:
```rust
fn foo<'a>(b: &'a u32) -> &'a u32 { b }
let f /* : FooFnItem<????> */ = foo::<'static>;
```
The above example errors as the lifetime parameter `'a` is late bound and so cannot be instantiated as part of the "naming a function" step. If we make the lifetime parameter early bound we will see this code start to compile:
```rust
fn foo<'a: 'a>(b: &'a u32) -> &'a u32 { b }
let f /* : FooFnItem<'static> */ = foo::<'static>;
```
What the current implementation of the compiler aims to do is error when specifying lifetime arguments to a function that has both early *and* late bound lifetime parameters. In practice, due to excessive breakage, some cases are actually only future compatibility warnings ([#42868](https://github.com/rust-lang/rust/issues/42868)):
- When the amount of lifetime arguments is the same as the number of early bound lifetime parameters a FCW is emitted instead of an error
- An error is always downgraded to a FCW when using method call syntax
To demonstrate this we can write out the different kinds of functions and give them both a late and early bound lifetime:
```rust,ignore
fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
struct Foo;
trait Trait: Sized {
fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ());
fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ());
}
impl Trait for Foo {
fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
}
impl Foo {
fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
}
```
Then, for the first case, we can call each function with a single lifetime argument (corresponding to the one early bound lifetime parameter) and note that it only results in a FCW rather than a hard error.
```rust
#![deny(late_bound_lifetime_arguments)]
#fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
#
#struct Foo;
#
#trait Trait: Sized {
# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ());
# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ());
#}
#
#impl Trait for Foo {
# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
#}
#
#impl Foo {
# fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
# fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
#}
#
// Specifying as many arguments as there are early
// bound parameters is always a future compat warning
Foo.trait_method::<'static>(&(), &());
Foo::trait_method::<'static>(Foo, &(), &());
Foo::trait_function::<'static>(&(), &());
Foo.inherent_method::<'static>(&(), &());
Foo::inherent_function::<'static>(&(), &());
free_function::<'static>(&(), &());
```
For the second case we call each function with more lifetime arguments than there are lifetime parameters (be it early or late bound) and note that method calls result in a FCW as opposed to the free/associated functions which result in a hard error:
```rust
#fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
#
#struct Foo;
#
#trait Trait: Sized {
# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ());
# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ());
#}
#
#impl Trait for Foo {
# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
#}
#
#impl Foo {
# fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {}
# fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {}
#}
#
// Specifying more arguments than there are early
// bound parameters is a future compat warning when
// using method call syntax.
Foo.trait_method::<'static, 'static, 'static>(&(), &());
Foo.inherent_method::<'static, 'static, 'static>(&(), &());
// However, it is a hard error when not using method call syntax.
Foo::trait_method::<'static, 'static, 'static>(Foo, &(), &());
Foo::trait_function::<'static, 'static, 'static>(&(), &());
Foo::inherent_function::<'static, 'static, 'static>(&(), &());
free_function::<'static, 'static, 'static>(&(), &());
```
Even when specifying enough lifetime arguments for both the late and early bound lifetime parameter, these arguments are not actually used to annotate the lifetime provided to late bound parameters. We can demonstrate this by turbofishing `'static` to a function while providing a non-static borrow:
```rust
struct Foo;
impl Foo {
fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b String ) {}
}
Foo.inherent_method::<'static, 'static>(&(), &String::new());
```
This compiles even though the `&String::new()` function argument does not have a `'static` lifetime, this is because "extra" lifetime arguments are discarded rather than taken into account for late bound parameters when actually calling the function.
### Liveness of types with late bound parameters
When checking type outlives bounds involving function item types we take into account early bound parameters. For example:
```rust
fn foo<T>(_: T) {}
fn requires_static<T: 'static>(_: T) {}
fn bar<T>() {
let f /* : FooFnItem<T> */ = foo::<T>;
requires_static(f);
}
```
As the type parameter `T` is early bound, the desugaring of the function item type for `foo` would look something like `struct FooFnItem<T>`. Then in order for `FooFnItem<T>: 'static` to hold we must also require `T: 'static` to hold as otherwise we would wind up with soundness bugs.
Unfortunately, due to bugs in the compiler, we do not take into account early bound *lifetimes*, which is the cause of the open soundness bug [#84366](https://github.com/rust-lang/rust/issues/84366). This means that it's impossible to demonstrate a "difference" between early/late bound parameters for liveness/type outlives bounds as the only kind of generic parameters that are able to be late bound are lifetimes which are handled incorrectly.
Regardless, in theory the code example below *should* demonstrate such a difference once [#84366](https://github.com/rust-lang/rust/issues/84366) is fixed:
```rust
fn early_bound<'a: 'a>(_: &'a String) {}
fn late_bound<'a>(_: &'a String) {}
fn requires_static<T: 'static>(_: T) {}
fn bar<'b>() {
let e = early_bound::<'b>;
// this *should* error but does not
requires_static(e);
let l = late_bound;
// this correctly does not error
requires_static(l);
}
```
## Requirements for a parameter to be late bound
### Must be a lifetime parameter
Type and Const parameters are not able to be late bound as we do not have a way to support types such as `dyn for<T> Fn(Box<T>)` or `for<T> fn(Box<T>)`. Calling such types requires being able to monomorphize the underlying function which is not possible with indirection through dynamic dispatch.
### Must not be used in a where clause
Currently when a generic parameter is used in a where clause it must be early bound. For example:
```rust
# trait Trait<'a> {}
fn foo<'a, T: Trait<'a>>(_: &'a String, _: T) {}
```
In this example the lifetime parameter `'a` is considered to be early bound as it appears in the where clause `T: Trait<'a>`. This is true even for "trivial" where clauses such as `'a: 'a` or those implied by wellformedness of function arguments, for example:
```rust
fn foo<'a: 'a>(_: &'a String) {}
fn bar<'a, T: 'a>(_: &'a T) {}
```
In both of these functions the lifetime parameter `'a` would be considered to be early bound even though the where clauses they are used in arguably do not actually impose any constraints on the caller.
The reason for this restriction is a combination of two things:
- We cannot prove bounds on late bound parameters until they have been instantiated
- Function pointers and trait objects do not have a way to represent yet to be proven where clauses from the underlying function
Take the following example:
```rust
trait Trait<'a> {}
fn foo<'a, T: Trait<'a>>(_: &'a T) {}
let f = foo::<String>;
let f = f as for<'a> fn(&'a String);
f(&String::new());
```
At *some point* during type checking an error should be emitted for this code as `String` does not implement `Trait` for any lifetime.
If the lifetime `'a` were late bound then this becomes difficult to check. When naming `foo` we do not know what lifetime should be used as part of the `T: Trait<'a>` trait bound as it has not yet been instantiated. When coercing the function item type to a function pointer we have no way of tracking the `String: Trait<'a>` trait bound that must be proven when calling the function.
If the lifetime `'a` is early bound (which it is in the current implementation in rustc), then the trait bound can be checked when naming the function `foo`. Requiring parameters used in where clauses to be early bound gives a natural place to check where clauses defined on the function.
Finally, we do not require lifetimes to be early bound if they are used in *implied bounds*, for example:
```rust
fn foo<'a, T>(_: &'a T) {}
let f = foo;
f(&String::new());
f(&String::new());
```
This code compiles, demonstrating that the lifetime parameter is late bound, even though `'a` is used in the type `&'a T` which implicitly requires `T: 'a` to hold. Implied bounds can be treated specially as any types introducing implied bounds are in the signature of the function pointer type, which means that when calling the function we know to prove `T: 'a`.
### Must be constrained by argument types
It is important that builtin impls on function item types do not wind up with unconstrained generic parameters as this can lead to unsoundness. This is the same kind of restriction as applies to user written impls, for example the following code results in an error:
```rust
trait Trait {
type Assoc;
}
impl<'a> Trait for u8 {
type Assoc = &'a String;
}
```
The analogous example for builtin impls on function items would be the following:
```rust,ignore
fn foo<'a>() -> &'a String { /* ... */ }
```
If the lifetime parameter `'a` were to be late bound we would wind up with a builtin impl with an unconstrained lifetime, we can manually write out the desugaring for the function item type and its impls with `'a` being late bound to demonstrate this:
```rust,ignore
// NOTE: this is just for demonstration, in practice `'a` is early bound
struct FooFnItem;
impl<'a> Fn<()> for FooFnItem {
type Output = &'a String;
/* fn call(...) -> ... { ... } */
}
```
In order to avoid such a situation we consider `'a` to be early bound which causes the lifetime on the impl to be constrained by the self type:
```rust,ignore
struct FooFnItem<'a>(PhantomData<fn() -> &'a String>);
impl<'a> Fn<()> for FooFnItem<'a> {
type Output = &'a String;
/* fn call(...) -> ... { ... } */
}
```

View file

@ -3,24 +3,24 @@
The `rust-lang/rust` git repository depends on several other repos in the `rust-lang` organization.
There are three main ways we use dependencies:
1. As a Cargo dependency through crates.io (e.g. `rustc-rayon`)
2. As a git subtree (e.g. `clippy`)
2. As a git (e.g. `clippy`) or a [josh] (e.g. `miri`) subtree
3. As a git submodule (e.g. `cargo`)
As a general rule, use crates.io for libraries that could be useful for others in the ecosystem; use
subtrees for tools that depend on compiler internals and need to be updated if there are breaking
changes; and use submodules for tools that are independent of the compiler.
As a general rule:
- Use crates.io for libraries that could be useful for others in the ecosystem
- Use subtrees for tools that depend on compiler internals and need to be updated if there are breaking
changes
- Use submodules for tools that are independent of the compiler
## External Dependencies (subtree)
## External Dependencies (subtrees)
As a developer to this repository, you don't have to treat the following external projects
differently from other crates that are directly in this repo:
The following external projects are managed using some form of a `subtree`:
* [Clippy](https://github.com/rust-lang/rust-clippy)
* [Miri]
* [clippy](https://github.com/rust-lang/rust-clippy)
* [miri](https://github.com/rust-lang/miri)
* [rustfmt](https://github.com/rust-lang/rustfmt)
* [rust-analyzer](https://github.com/rust-lang/rust-analyzer)
[Miri]: https://github.com/rust-lang/miri
* [rustc_codegen_cranelift](https://github.com/rust-lang/rustc_codegen_cranelift)
In contrast to `submodule` dependencies
(see below for those), the `subtree` dependencies are just regular files and directories which can
@ -29,6 +29,20 @@ to these tools should be filed against the tools directly in their respective
upstream repositories. The exception is that when rustc changes are required to
implement a new tool feature or test, that should happen in one collective rustc PR.
`subtree` dependencies are currently managed by two distinct approaches:
* Using `git subtree`
* `clippy` ([sync guide](https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html#performing-the-sync-from-rust-langrust-to-clippy))
* `rustfmt`
* `rustc_codegen_cranelift` ([sync script](https://github.com/rust-lang/rustc_codegen_cranelift/blob/113af154d459e41b3dc2c5d7d878e3d3a8f33c69/scripts/rustup.sh#L7))
* Using the [josh] tool
* `miri` ([sync guide](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#advanced-topic-syncing-with-the-rustc-repo))
* `rust-analyzer` ([sync script](https://github.com/rust-lang/rust-analyzer/blob/2e13684be123eca7181aa48e043e185d8044a84a/xtask/src/release.rs#L147))
The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh, you can check out the `miri` or `rust-analyzer` scripts linked above for inspiration. If you want to migrate a subtree from `git subtree` to josh, you can check out [this guide](https://hackmd.io/7pOuxnkdQDaL1Y1FQr65xg).
Below you can find a guide on how to perform push and pull synchronization with the main rustc repo using `git subtree`, although these instructions might differ repo from repo.
### Synchronizing a subtree
Periodically the changes made to subtree based dependencies need to be synchronized between this
@ -84,7 +98,6 @@ Now you're done, the `src/tools/clippy` directory behaves as if Clippy were
part of the rustc monorepo, so no one but you (or others that synchronize
subtrees) actually needs to use `git subtree`.
## External Dependencies (submodules)
Building Rust will also use external git repositories tracked using [git
@ -111,3 +124,4 @@ the week leading up to the beta cut.
[The Rust Reference]: https://github.com/rust-lang/reference/
[toolstate website]: https://rust-lang-nursery.github.io/rust-toolstate/
[Toolstate chapter]: https://forge.rust-lang.org/infra/toolstate.html
[josh]: https://josh-project.github.io/josh/intro.html

View file

@ -25,42 +25,4 @@ Interestingly, `ty::Generics` does not currently contain _every_ generic paramet
[ch_representing_types]: ./ty.md
[`ty::Generics`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Generics.html
[`GenericParamDef`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/generics/struct.GenericParamDef.html
# Early vs Late bound parameters
```rust
fn foo<'a, T>(b: &'a T) -> &'a T { b }
// ^^ ^early bound
// ^^
// ^^late bound
```
Generally when referring to an item with generic parameters you must specify a list of generic arguments corresponding to the item's generic parameters. In some cases it is permitted to elide these arguments but still, implicitly, a set of arguments are provided (e.g. `Vec::default()` desugars to `Vec::<_>::default()`).
For functions this is not necessarily the case, for example if we take the function `foo` from the example above and write the following code:
```rust
fn main() {
let f = foo::<_>;
let b = String::new();
let c = String::new();
f(&b);
drop(b);
f(&c);
}
```
This code compiles perfectly fine even though there is no single lifetime that could possibly be specified in `foo::<_>` that would allow for both
the `&b` and `&c` borrows to be used as arguments (note: the `drop(b)` line forces the `&b` borrow to be shorter than the `&c` borrow). This works because the `'a` lifetime is _late bound_.
A generic parameter being late bound means that when we write `foo::<_>` we do not actually provide an argument for that parameter, instead we wait until _calling_ the function to provide the generic argument. In the above example this means that we are doing something like `f::<'_>(&b);` and `f::<'_>(&c);` (although in practice we do not actually support turbofishing late bound parameters in this manner)
It may be helpful to think of "early bound parameter" or "late bound parameter" as meaning "early provided parameter" and "late provided parameter", i.e. we provide the argument to the parameter either early (when naming the function) or late (when calling it).
Late bound parameters on functions are tracked with a [`Binder`] when accessing the signature of the function, this can be done with the [`fn_sig`] query. For more information of binders see the [chapter on `Binder`s ][ch_binders].
[`Binder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/binder/struct.Binder.html
[`fn_sig`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.fn_sig
[ch_binders]: ./ty_module/binders.md
[ch_binders]: ./ty_module/binders.md

View file

@ -67,6 +67,7 @@ imported to use an inherent method, they are associated with the type
itself (note that inherent impls can only be defined in the same
crate as the type itself).
<!--
FIXME: Inherent candidates are not always derived from impls. If you
have a trait object, such as a value of type `Box<ToString>`, then the
trait methods (`to_string()`, in this case) are inherently associated
@ -76,7 +77,8 @@ to change: when DST's "impl Trait for Trait" is complete, trait object
dispatch could be subsumed into trait matching, and the type parameter
behavior should be reconsidered in light of where clauses.
TODO: Is this FIXME still accurate?
Is this still accurate?
-->
**Extension candidates** are derived from imported traits. If I have
the trait `ToString` imported, and I call `to_string()` as a method,

View file

@ -1,5 +1,7 @@
# Normalization in the new solver
> FIXME: Normalization has been changed significantly since this chapter was written.
With the new solver we've made some fairly significant changes to normalization when compared
to the existing implementation.
@ -52,12 +54,14 @@ before assigning the resulting rigid type to an inference variable. This is used
This has to be used whenever we match on the value of some type, both inside
and outside of the trait solver.
<!--
FIXME: structure, maybe we should have an "alias handling" chapter instead as
talking about normalization without explaining that doesn't make too much
sense.
FIXME: it is likely that this will subtly change again by mostly moving structural
normalization into `NormalizesTo`.
-->
[structural_norm]: https://github.com/rust-lang/rust/blob/2627e9f3012a97d3136b3e11bf6bd0853c38a534/compiler/rustc_trait_selection/src/solve/alias_relate.rs#L140-L175
[structural-relate]: https://github.com/rust-lang/rust/blob/a0569fa8f91b5271e92d2f73fd252de7d3d05b9c/compiler/rustc_trait_selection/src/solve/alias_relate.rs#L88-L107
@ -72,11 +76,13 @@ possible. However, this only works for aliases referencing bound variables if th
not ambiguous as we're unable to replace the alias with a corresponding inference
variable without leaking universes.
<!--
FIXME: we previously had to also be careful about instantiating the new inference
variable with another normalizeable alias. Due to our recent changes to generalization,
this should not be the case anymore. Equating an inference variable with an alias
now always uses `AliasRelate` to fully normalize the alias before instantiating the
inference variable: [source][generalize-no-alias]
-->
[generalize-no-alias]: https://github.com/rust-lang/rust/blob/a0569fa8f91b5271e92d2f73fd252de7d3d05b9c/compiler/rustc_infer/src/infer/relate/generalize.rs#L353-L358

View file

@ -60,6 +60,7 @@ Finally, we check whether the item bounds of the opaque hold for the expected ty
[eq-prev]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L51-L59
[insert-storage]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L68
[item-bounds-ck]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L69-L74
[^1]: FIXME: this should ideally only result in a unique candidate given that we require the args to be placeholders and regions are always inference vars
[^2]: FIXME: why do we check whether the expected type is rigid for this.
@ -101,6 +102,7 @@ The handling of member constraints does not change in the new solver. See the
FIXME: We need to continue to support calling methods on still unconstrained
opaque types in their defining scope. It's unclear how to best do this.
```rust
use std::future::Future;
use futures::FutureExt;

View file

@ -28,7 +28,7 @@ Our CI is primarily executed on [GitHub Actions], with a single workflow defined
in [`.github/workflows/ci.yml`], which contains a bunch of steps that are
unified for all CI jobs that we execute. When a commit is pushed to a
corresponding branch or a PR, the workflow executes the
[`calculate-job-matrix.py`] script, which dynamically generates the specific CI
[`ci.py`] script, which dynamically generates the specific CI
jobs that should be executed. This script uses the [`jobs.yml`] file as an
input, which contains a declarative configuration of all our CI jobs.
@ -299,8 +299,7 @@ platforms custom [Docker container]. This has a lot of advantages for us:
- We can avoid reinstalling tools (like QEMU or the Android emulator) every time
thanks to Docker image caching.
- Users can run the same tests in the same environment locally by just running
`src/ci/docker/run.sh image-name`, which is awesome to debug failures. Note
that there are only linux docker images available locally due to licensing and
`python3 src/ci/github-actions/ci.py run-local <job-name>`, which is awesome to debug failures. Note that there are only linux docker images available locally due to licensing and
other restrictions.
The docker images prefixed with `dist-` are used for building artifacts while
@ -413,7 +412,7 @@ To learn more about the dashboard, see the [Datadog CI docs].
[GitHub Actions]: https://github.com/rust-lang/rust/actions
[`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml
[`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml
[`calculate-job-matrix.py`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/calculate-job-matrix.py
[`ci.py`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/ci.py
[rust-lang-ci]: https://github.com/rust-lang-ci/rust/actions
[bors]: https://github.com/bors
[homu]: https://github.com/rust-lang/homu

View file

@ -441,6 +441,46 @@ $ COMPILETEST_FORCE_STAGE0=1 x test --stage 0 tests/run-make/<test-name>
Of course, some tests will not successfully *run* in this way.
#### Using rust-analyzer with `rmake.rs`
Like other test programs, the `rmake.rs` scripts used by run-make tests do not
have rust-analyzer integration by default.
To work around this when working on a particular test, temporarily create a
`Cargo.toml` file in the test's directory
(e.g. `tests/run-make/sysroot-crates-are-unstable/Cargo.toml`)
with these contents:
<div class="warning">
Be careful not to add this `Cargo.toml` or its `Cargo.lock` to your actual PR!
</div>
```toml
# Convince cargo that this isn't part of an enclosing workspace.
[workspace]
[package]
name = "rmake"
version = "0.1.0"
edition = "2021"
[dependencies]
run_make_support = { path = "../../../src/tools/run-make-support" }
[[bin]]
name = "rmake"
path = "rmake.rs"
```
Then add a corresponding entry to `"rust-analyzer.linkedProjects"`
(e.g. in `.vscode/settings.json`):
```json
"rust-analyzer.linkedProjects": [
"tests/run-make/sysroot-crates-are-unstable/Cargo.toml"
],
```
#### Using Makefiles (legacy)
<div class="warning">

View file

@ -2,7 +2,9 @@
<!-- toc -->
> **FIXME(jieyouxu)** completely revise this chapter.
<!--
FIXME(jieyouxu) completely revise this chapter.
-->
Directives are special comments that tell compiletest how to build and interpret
a test. They must appear before the Rust source in the test. They may also
@ -248,10 +250,11 @@ Consider writing the test as a proper incremental test instead.
|-------------|--------------------------------------------------------------|------------------------------------------|---------------------------|
| `doc-flags` | Flags passed to `rustdoc` when building the test or aux file | `rustdoc`, `js-doc-test`, `rustdoc-json` | Any valid `rustdoc` flags |
> **FIXME(rustdoc)**: what does `check-test-line-numbers-match` do?
>
> Asked in
> <https://rust-lang.zulipchat.com/#narrow/stream/266220-t-rustdoc/topic/What.20is.20the.20.60check-test-line-numbers-match.60.20directive.3F>.
<!--
**FIXME(rustdoc)**: what does `check-test-line-numbers-match` do?
Asked in
<https://rust-lang.zulipchat.com/#narrow/stream/266220-t-rustdoc/topic/What.20is.20the.20.60check-test-line-numbers-match.60.20directive.3F>.
-->
### Pretty printing

View file

@ -45,6 +45,15 @@ Some additional notes about using the Docker images:
containers. With the container name, run `docker exec -it <CONTAINER>
/bin/bash` where `<CONTAINER>` is the container name like `4ba195e95cef`.
The approach described above is a relatively low-level interface for running the Docker images
directly. If you want to run a full CI Linux job locally with Docker, in a way that is as close to CI as possible, you can use the following command:
```bash
python3 src/ci/github-actions/ci.py run-local <job-name>
# For example:
python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux-alt
```
[Docker]: https://www.docker.com/
[`src/ci/docker`]: https://github.com/rust-lang/rust/tree/master/src/ci/docker
[`src/ci/docker/run.sh`]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/run.sh

View file

@ -10,7 +10,7 @@ stream and say hello!
[Types team]: https://github.com/rust-lang/types-team
[`#t-types`]: https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types
The new-style trait solver is based on the work done in [chalk][chalk]. Chalk
The new-style trait solver is based on the work done in [chalk]. Chalk
recasts Rust's trait system explicitly in terms of logic programming. It does
this by "lowering" Rust code into a kind of logic program we can then execute
queries against.
@ -30,7 +30,7 @@ You can read more about chalk itself in the
## Ongoing work
The design of the new-style trait solving happens in two places:
**chalk**. The [chalk][chalk] repository is where we experiment with new ideas
**chalk**. The [chalk] repository is where we experiment with new ideas
and designs for the trait system.
**rustc**. Once we are happy with the logical rules, we proceed to

View file

@ -47,10 +47,10 @@ fn bar(foo: Foo<u32, f32>) {
In the compiler the `instantiate` call for this is done in [`FieldDef::ty`] ([src][field_def_ty_src]), at some point during type checking `bar` we will wind up calling `FieldDef::ty(x, &[u32, f32])` in order to obtain the type of `foo.x`.
**Note on indices:** It is possible for the indices in `Param` to not match with what the `EarlyBinder` binds. For
example, the index could be out of bounds or it could be the index of a lifetime when we were expecting a type.
These sorts of errors would be caught earlier in the compiler when translating from a `rustc_hir::Ty` to a `ty::Ty`.
If they occur later, that is a compiler bug.
**Note on indices:** It is a bug if the index of a `Param` does not match what the `EarlyBinder` binds. For
example, if the index is out of bounds or the index index of a lifetime corresponds to a type parameter.
These sorts of errors are caught earlier in the compiler during name resolution where we disallow references
to generics parameters introduced by items that should not be nameable by the inner item.
[`FieldDef::ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.FieldDef.html#method.ty
[field_def_ty_src]: https://github.com/rust-lang/rust/blob/44d679b9021f03a79133021b94e6d23e9b55b3ab/compiler/rustc_middle/src/ty/mod.rs#L1421-L1426

View file

@ -60,16 +60,18 @@
- [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md)
- [loongarch\*-unknown-none\*](platform-support/loongarch-none.md)
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
- [m68k-unknown-none-elf](platform-support/m68k-unknown-none-elf.md)
- [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
- [mipsel-sony-psx](platform-support/mipsel-sony-psx.md)
- [mips\*-mti-none-elf](platform-support/mips-mti-none-elf.md)
- [mipsisa\*r6\*-unknown-linux-gnu\*](platform-support/mips-release-6.md)
- [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md)
- [powerpc-unknown-openbsd](platform-support/powerpc-unknown-openbsd.md)
- [powerpc-unknown-linux-muslspe](platform-support/powerpc-unknown-linux-muslspe.md)
- [powerpc64-ibm-aix](platform-support/aix.md)
- [powerpc64le-unknown-linux-musl](platform-support/powerpc64le-unknown-linux-musl.md)
- [riscv32e*-unknown-none-elf](platform-support/riscv32e-unknown-none-elf.md)
- [riscv32i*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
- [riscv32e\*-unknown-none-elf](platform-support/riscv32e-unknown-none-elf.md)
- [riscv32i\*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
- [riscv32im-risc0-zkvm-elf](platform-support/riscv32im-risc0-zkvm-elf.md)
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
- [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md)
@ -78,14 +80,14 @@
- [s390x-unknown-linux-musl](platform-support/s390x-unknown-linux-musl.md)
- [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
- [sparcv9-sun-solaris](platform-support/solaris.md)
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
- [\*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)
- [*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md)
- [*-unknown-hermit](platform-support/hermit.md)
- [*-unknown-freebsd](platform-support/freebsd.md)
- [\*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md)
- [\*-unknown-hermit](platform-support/hermit.md)
- [\*-unknown-freebsd](platform-support/freebsd.md)
- [\*-unknown-netbsd\*](platform-support/netbsd.md)
- [*-unknown-openbsd](platform-support/openbsd.md)
- [*-unknown-redox](platform-support/redox.md)
- [\*-unknown-openbsd](platform-support/openbsd.md)
- [\*-unknown-redox](platform-support/redox.md)
- [\*-unknown-uefi](platform-support/unknown-uefi.md)
- [\*-uwp-windows-msvc](platform-support/uwp-windows-msvc.md)
- [\*-wrs-vxworks](platform-support/vxworks.md)
@ -96,13 +98,14 @@
- [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md)
- [wasm32v1-none](platform-support/wasm32v1-none.md)
- [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
- [\*-win7-windows-gnu](platform-support/win7-windows-gnu.md)
- [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md)
- [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md)
- [x86_64-pc-solaris](platform-support/solaris.md)
- [x86_64-unknown-linux-none.md](platform-support/x86_64-unknown-linux-none.md)
- [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
- [xtensa-\*-none-elf](platform-support/xtensa.md)
- [*-nuttx-\*](platform-support/nuttx.md)
- [\*-nuttx-\*](platform-support/nuttx.md)
- [Targets](targets/index.md)
- [Built-in Targets](targets/built-in.md)
- [Custom Targets](targets/custom.md)

View file

@ -134,7 +134,7 @@ As of `2025-01-02T`, the list of known names is as follows:
- `unix`
- `windows`
> Starting with CURRENT_RUSTC_VERSION, the `test` cfg is consider to be a "userspace" config
> Starting with 1.85.0, the `test` cfg is consider to be a "userspace" config
> despite being also set by `rustc` and should be managed by the build-system it-self.
Like with `values(any())`, well known names checking can be disabled by passing `cfg(any())`

View file

@ -313,10 +313,12 @@ target | std | host | notes
[`i686-unknown-redox`](platform-support/redox.md) | ✓ | | i686 Redox OS
`i686-uwp-windows-gnu` | ✓ | | [^x86_32-floats-return-ABI]
[`i686-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | | [^x86_32-floats-return-ABI]
[`i686-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI]
[`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI]
[`i686-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [^x86_32-floats-return-ABI]
[`loongarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | LoongArch64 OpenHarmony
[`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux
[`m68k-unknown-none-elf`](platform-support/m68k-unknown-none-elf.md) | | | Motorola 680x0
`mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23)
`mips-unknown-linux-musl` | ✓ | | MIPS Linux with musl 1.2.3
`mips-unknown-linux-uclibc` | ✓ | | MIPS Linux with uClibc
@ -332,6 +334,8 @@ target | std | host | notes
`mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc
[`mipsel-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | 32-bit MIPS (LE), requires mips32 cpu support
`mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat
[`mips-mti-none-elf`](platform-support/mips-mti-none-elf.md) | * | | Bare MIPS32r2 (BE) softfloat
[`mipsel-mti-none-elf`](platform-support/mips-mti-none-elf.md) | * | | Bare MIPS32r2 (LE) softfloat
[`mipsisa32r6-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Big Endian
[`mipsisa32r6el-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Little Endian
[`mipsisa64r6-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ? | | 64-bit MIPS Release 6 Big Endian
@ -407,6 +411,7 @@ target | std | host | notes
[`x86_64-unknown-trusty`](platform-support/trusty.md) | ? | |
`x86_64-uwp-windows-gnu` | ✓ | |
[`x86_64-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | |
[`x86_64-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 64-bit Windows 7 support
[`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 64-bit Windows 7 support
[`x86_64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | |
[`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell)

View file

@ -0,0 +1,108 @@
# m68k-unknown-none-elf
**Tier: 3**
Bare metal Motorola 680x0
## Designated Developers
* [@knickish](https://github.com/knickish)
## Requirements
This target requires an m68k build environment for cross-compilation which
is available on Debian, Debian-based systems, openSUSE, and other distributions.
On Debian-based systems, it should be sufficient to install a g++ cross-compiler for the m68k
architecture which will automatically pull in additional dependencies such as
the glibc cross development package:
```sh
apt install g++-m68k-linux-gnu
```
Binaries can be run using QEMU user emulation. On Debian-based systems, it should be
sufficient to install the package `qemu-user-static` to be able to run simple static
binaries:
```text
# apt install qemu-user-static
```
To run more complex programs, it will be necessary to set up a Debian/m68k chroot with
the help of the command `debootstrap`:
```text
# apt install debootstrap debian-ports-archive-keyring
# debootstrap --keyring=/usr/share/keyrings/debian-ports-archive-keyring.gpg --arch=m68k unstable debian-68k http://ftp.ports.debian.org/debian-ports
```
This chroot can then seamlessly entered using the normal `chroot` command thanks to
QEMU user emulation:
```text
# chroot /path/to/debian-68k
```
To get started with native builds, which are currently untested, a native Debian/m68k
system can be installed either on real hardware such as 68k-based Commodore Amiga or
Atari systems or emulated environments such as QEMU version 4.2 or newer or ARAnyM.
ISO images for installation are provided by the Debian Ports team and can be obtained
from the Debian CD image server available at:
[https://cdimage.debian.org/cdimage/ports/current](https://cdimage.debian.org/cdimage/ports/current/)
Documentation for Debian/m68k is available on the Debian Wiki at:
[https://wiki.debian.org/M68k](https://wiki.debian.org/M68k)
Support is available either through the `debian-68k` mailing list:
[https://lists.debian.org/debian-68k/](https://lists.debian.org/debian-68k/)
or the `#debian-68k` IRC channel on OFTC network.
## Building
At least llvm version `19.1.5` is required to build `core` and `alloc` for this target, and currently the gnu linker is required, as `lld` has no support for the `m68k` architecture
## Cross-compilation
This target can be cross-compiled from a standard Debian or Debian-based, openSUSE or any
other distribution which has a basic m68k cross-toolchain available.
## Testing
Currently there is no support to run the rustc test suite for this target.
## Building Rust programs
Recommended `.cargo/config.toml`:
```toml
[unstable]
build-std = ["panic_abort", "core", "alloc"]
[target.m68k-unknown-none-elf]
# as we're building for ELF, the m68k-linux linker should be adequate
linker = "m68k-linux-gnu-ld"
# the mold linker also supports m68k, remove the above line and uncomment the
# following ones to use that instead
# linker = "clang"
# rustflags = ["-C", "link-arg=-fuse-ld=/path/to/mold/binary"]
```
Rust programs can be built for this target using:
```sh
cargo build --target m68k-unknown-none-elf
```
Very simple programs can be run using the `qemu-m68k-static` program:
```sh
qemu-m68k-static your-code
```
For more complex applications, a chroot or native m68k system is required for testing.

View file

@ -0,0 +1,31 @@
# `mips*-mti-none-elf`
**Tier: 3**
MIPS32r2 baremetal softfloat, Big Endian or Little Endian.
- mips-mti-none-elf
- mipsel-mti-none-elf
## Target maintainers
- YunQiang Su, `syq@debian.org`, https://github.com/wzssyqa
## Background
These 2 targets, aka mips-mti-none-elf and mipsel-mti-none-elf, are for
baremetal development of MIPS32r2. The lld is used instead of Gnu-ld.
## Requirements
The target only supports cross compilation and no host tools. The target
supports `alloc` with a default allocator while only support `no-std` development.
The vendor name `mti` follows the naming of gcc to indicate MIPS32r2.
## Cross-compilation toolchains and C code
Compatible C code can be built for this target on any compiler that has a MIPS32r2
target. On clang and ld.lld linker, it can be generated using the
`-march=mips`/`-march=mipsel`, `-mabi=32` with llvm features flag
`features=+mips32r2,+soft-float,+noabicalls`.

View file

@ -0,0 +1,48 @@
# \*-win7-windows-gnu
**Tier: 3**
Windows targets continuing support of Windows 7.
Target triples:
- `i686-win7-windows-gnu`
- `x86_64-win7-windows-gnu`
## Target maintainers
- @tbu-
## Requirements
This target supports all of core, alloc, std and test. Host
tools may also work, though those are not currently tested.
Those targets follow Windows calling convention for extern "C".
Like any other Windows target, the created binaries are in PE format.
## Building the target
You can build Rust with support for the targets by adding it to the target list in config.toml:
```toml
[build]
build-stage = 1
target = ["x86_64-win7-windows-gnu"]
```
## Building Rust programs
Rust does not ship pre-compiled artifacts for this target. To compile for this
target, you will either need to build Rust with the target enabled (see
"Building the target" above), or build your own copy by using `build-std` or
similar.
## Testing
Created binaries work fine on Windows or Wine using native hardware. Remote
testing is possible using the `remote-test-server` described [here](https://rustc-dev-guide.rust-lang.org/tests/running.html#running-tests-on-a-remote-machine).
## Cross-compilation toolchains and C code
Compatible C code can be built with gcc's `{i686,x86_64}-w64-mingw32-gcc`.

View file

@ -1,8 +1,12 @@
# *-win7-windows-msvc
# \*-win7-windows-msvc
**Tier: 3**
Windows targets continuing support of windows7.
Windows targets continuing support of Windows 7.
Target triples:
- `i686-win7-windows-msvc`
- `x86_64-win7-windows-msvc`
## Target maintainers

View file

@ -0,0 +1,6 @@
# `emscripten-wasm-eh`
Use the WebAssembly exception handling ABI to unwind for the
`wasm32-unknown-emscripten`. If compiling with this setting, the `emcc` linker
should be invoked with `-fwasm-exceptions`. If linking with C/C++ files, the
C/C++ files should also be compiled with `-fwasm-exceptions`.

View file

@ -0,0 +1,24 @@
# `min-function-alignment`
The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/82232.
------------------------
The `-Zmin-function-alignment=<align>` flag specifies the minimum alignment of functions for which code is generated.
The `align` value must be a power of 2, other values are rejected.
Note that `-Zbuild-std` (or similar) is required to apply this minimum alignment to standard library functions.
By default, these functions come precompiled and their alignments won't respect the `min-function-alignment` flag.
This flag is equivalent to:
- `-fmin-function-alignment` for [GCC](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fmin-function-alignment_003dn)
- `-falign-functions` for [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang1-falign-functions)
The specified alignment is a minimum. A higher alignment can be specified for specific functions by using the [`repr(align(...))`](https://github.com/rust-lang/rust/issues/82232) feature and annotating the function with a `#[repr(align(<align>))]` attribute. The attribute's value is ignored when it is lower than the value passed to `min-function-alignment`.
There are two additional edge cases for this flag:
- targets have a minimum alignment for functions (e.g. on x86_64 the lowest that LLVM generates is 16 bytes).
A `min-function-alignment` value lower than the target's minimum has no effect.
- the maximum alignment supported by rust (and LLVM) is `2^29`. Trying to set a higher value results in an error.

View file

@ -0,0 +1,93 @@
# `default_field_values`
The tracking issue for this feature is: [#132162]
[#132162]: https://github.com/rust-lang/rust/issues/132162
The RFC for this feature is: [#3681]
[#3681]: https://github.com/rust-lang/rfcs/blob/master/text/3681-default-field-values.md
------------------------
The `default_field_values` feature allows users to specify a const value for
individual fields in struct definitions, allowing those to be omitted from
initializers.
## Examples
```rust
#![feature(default_field_values)]
#[derive(Default)]
struct Pet {
name: Option<String>, // impl Default for Pet will use Default::default() for name
age: i128 = 42, // impl Default for Pet will use the literal 42 for age
}
fn main() {
let a = Pet { name: Some(String::new()), .. }; // Pet { name: Some(""), age: 42 }
let b = Pet::default(); // Pet { name: None, age: 42 }
assert_eq!(a.age, b.age);
// The following would be a compilation error: `name` needs to be specified
// let _ = Pet { .. };
}
```
## `#[derive(Default)]`
When deriving Default, the provided values are then used. On enum variants,
the variant must still be marked with `#[default]` and have all its fields
with default values.
```rust
#![feature(default_field_values)]
#[derive(Default)]
enum A {
#[default]
B {
x: i32 = 0,
y: i32 = 0,
},
C,
}
```
## Enum variants
This feature also supports enum variants for both specifying default values
and `#[derive(Default)]`.
## Interaction with `#[non_exhaustive]`
A struct or enum variant marked with `#[non_exhaustive]` is not allowed to
have default field values.
## Lints
When manually implementing the `Default` trait for a type that has default
field values, if any of these are overriden in the impl the
`default_overrides_default_fields` lint will trigger. This lint is in place
to avoid surprising diverging behavior between `S { .. }` and
`S::default()`, where using the same type in both ways could result in
different values. The appropriate way to write a manual `Default`
implementation is to use the functional update syntax:
```rust
#![feature(default_field_values)]
struct Pet {
name: String,
age: i128 = 42, // impl Default for Pet will use the literal 42 for age
}
impl Default for Pet {
fn default() -> Pet {
Pet {
name: "no-name".to_string(),
..
}
}
}
```

View file

@ -172,11 +172,6 @@
<!-- tool-rust-docs-end -->
<Directory Id="Cargo" Name="." />
<Directory Id="Std" Name="." />
<Directory Id="RustFmt" Name="." />
<Directory Id="RustAnalyzer" Name="." />
<Directory Id="Miri" Name="." />
<Directory Id="Analysis" Name="." />
<Directory Id="Clippy" Name="." />
</Directory>
</Directory>
@ -284,41 +279,7 @@
<ComponentRef Id="PathEnvPerMachine" />
<ComponentRef Id="PathEnvPerUser" />
</Feature>
<Feature Id="RustFmt"
Title="Formatter for rust"
Display="7"
Level="1"
AllowAdvertise="no">
<ComponentGroupRef Id="RustFmtGroup" />
</Feature>
<Feature Id="Clippy"
Title="Formatter and checker for rust"
Display="8"
Level="1"
AllowAdvertise="no">
<ComponentGroupRef Id="ClippyGroup" />
</Feature>
<Feature Id="Miri"
Title="Soundness checker for rust"
Display="9"
Level="1"
AllowAdvertise="no">
<ComponentGroupRef Id="MiriGroup" />
</Feature>
<Feature Id="RustAnalyzer"
Title="Analyzer for rust"
Display="10"
Level="1"
AllowAdvertise="no">
<ComponentGroupRef Id="RustAnalyzerGroup" />
</Feature>
<Feature Id="Analysis"
Title="Analysis for rust"
Display="11"
Level="1"
AllowAdvertise="no">
<ComponentGroupRef Id="AnalysisGroup" />
</Feature>
<UIRef Id="RustUI" />
</Product>
</Wix>

View file

@ -314,12 +314,13 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
PatKind::Box(p) => return name_from_pat(p),
PatKind::Deref(p) => format!("deref!({})", name_from_pat(p)),
PatKind::Ref(p, _) => return name_from_pat(p),
PatKind::Lit(..) => {
PatKind::Expr(..) => {
warn!(
"tried to get argument name from PatKind::Lit, which is silly in function arguments"
"tried to get argument name from PatKind::Expr, which is silly in function arguments"
);
return Symbol::intern("()");
}
PatKind::Guard(p, _) => return name_from_pat(&*p),
PatKind::Range(..) => return kw::Underscore,
PatKind::Slice(begin, ref mid, end) => {
let begin = begin.iter().map(|p| name_from_pat(p).to_string());

View file

@ -1,5 +1,6 @@
use std::mem;
use rustc_attr_parsing::StabilityLevel;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet};
use rustc_middle::ty::{self, TyCtxt};
@ -306,7 +307,12 @@ impl DocFolder for CacheBuilder<'_, '_> {
| clean::ProcMacroItem(..)
| clean::VariantItem(..) => {
use rustc_data_structures::fx::IndexEntry as Entry;
if !self.cache.stripped_mod {
if !self.cache.stripped_mod
&& !matches!(
item.stability.map(|stab| stab.level),
Some(StabilityLevel::Stable { allowed_through_unstable_modules: true, .. })
)
{
// Re-exported items mean that the same id can show up twice
// in the rustdoc ast that we're looking at. We know,
// however, that a re-exported item doesn't show up in the

View file

@ -357,7 +357,7 @@ fn sidebar_type_alias<'a>(
deref_id_map: &'a DefIdMap<String>,
) {
if let Some(inner_type) = &t.inner_type {
items.push(LinkBlock::forced(Link::new("aliased-type", "Aliased type"), "type"));
items.push(LinkBlock::forced(Link::new("aliased-type", "Aliased Type"), "type"));
match inner_type {
clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive: _ } => {
let mut variants = variants

View file

@ -865,11 +865,11 @@ fn main_args(
}
let krate = rustc_interface::passes::parse(sess);
if sess.dcx().has_errors().is_some() {
sess.dcx().fatal("Compilation failed, aborting rustdoc");
}
rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| {
if sess.dcx().has_errors().is_some() {
sess.dcx().fatal("Compilation failed, aborting rustdoc");
}
let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || {
core::run_global_ctxt(tcx, show_coverage, render_options, output_format)
});

View file

@ -14,456 +14,468 @@ nightly_branch=master
# All changes below this comment will be overridden the next time the
# tool is executed.
compiler_date=2024-11-27
compiler_date=2025-01-08
compiler_version=beta
rustfmt_date=2024-11-27
rustfmt_date=2025-01-08
rustfmt_version=nightly
dist/2024-11-27/rustc-beta-aarch64-apple-darwin.tar.gz=58e2ba5f6a388a5bc9ecfa1c7ec4ba3efd9662e1875ea5fba484c75c5f930227
dist/2024-11-27/rustc-beta-aarch64-apple-darwin.tar.xz=95f3ed14a6e3093cdee83f80227c7966783fffcc0ff0be6ef095df0dc744b9f8
dist/2024-11-27/rustc-beta-aarch64-pc-windows-msvc.tar.gz=687b58e25baa685be9357048cc1e0c469c25dc6530db55e0179234615ff4d289
dist/2024-11-27/rustc-beta-aarch64-pc-windows-msvc.tar.xz=694e2405efb25c53575599ad6573d8c4646a168e5d4bde922ef5e7d43f3e530c
dist/2024-11-27/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=4b42d00e701f90c1fff9a692f1bc1da957fcadbd1813c3066dc1f1990bceadcc
dist/2024-11-27/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=4f83a8cced878c03aea2d6cec7e1d588c2b6590850664f28f3b49a3be3a8b827
dist/2024-11-27/rustc-beta-aarch64-unknown-linux-musl.tar.gz=bae97ca3778fbaa40f6db4da4f6da0b2bb870e9880165fc3126363f55a1fb23a
dist/2024-11-27/rustc-beta-aarch64-unknown-linux-musl.tar.xz=3e617e866a8c03fef243dede8c086d085a6564aeeb5570bada62db5a16e95f2a
dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=96d2f23814db8286de9ffce7bab033aa4dc656f83aa39418c8f877a5befbb100
dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=0433a866c4d8a434990746216232759345d3ef556b0b92358b231fc1e727962e
dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=6a776c6eb2b7b4992eed6a127d11b8845695cdc5d23938ced2267f88f8d97033
dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=2649e0f522755dcd511a6459258c3c3a24808fc49d3513f3d9098b17bd0f2c79
dist/2024-11-27/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=02a65e970ee930b46c2d10e1eb3d2e6f2420e08bbef039f10a8311baf57f274f
dist/2024-11-27/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=3843610c7ecf98948a5f78a364c223d520a084bc8c49ec0c3c8ec48bad6c0bf8
dist/2024-11-27/rustc-beta-i686-pc-windows-gnu.tar.gz=75288ca1e65157b8902195ec2fff31015017c90d3b8f51890f2f851529b200cb
dist/2024-11-27/rustc-beta-i686-pc-windows-gnu.tar.xz=5c694e50b41cd6f2c7b59b891eda3e728a1a2c56617b96c9da001b35885637b4
dist/2024-11-27/rustc-beta-i686-pc-windows-msvc.tar.gz=6d1a66c090322ccf272a425c779f9165398e6bd9e0c7e5d0a5f262086d43ed88
dist/2024-11-27/rustc-beta-i686-pc-windows-msvc.tar.xz=e826fe8be287f8969d11f620da9d01ea0d913eba145fb79ae86bc78674f1b919
dist/2024-11-27/rustc-beta-i686-unknown-linux-gnu.tar.gz=31e0d9a1ff97d92c391cc913fd865a0c8afd614279654350d469bdf881a1b1a3
dist/2024-11-27/rustc-beta-i686-unknown-linux-gnu.tar.xz=3b11a6be4863cb6ad420b66558b7745431834d1fac5dbda899a384dc30b526cf
dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=59d96cd092a56d12ea796b65225479803edadbdcb483effdfa36e191f73483f1
dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=0714a469cbd7d96118e9260f80fedf34b21234776904e9c8ec5b71c9493dd36a
dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=25113ca9719a036ae581f68df4dda74f1446b49ababe7bb194510fbd1b296e7a
dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=25bd910ea722fe2d4a1e66089352c92f97759ec7212af2b9a04431b469ed8e12
dist/2024-11-27/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=7a83c9f63d88849c4d691ad1d7fbe7ab5924b5a7d76378ddff5024269be95310
dist/2024-11-27/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=fbbb11b4c986186d94b0e00ebc70400d0071efc2ba3b802abdd877d86b8cacdd
dist/2024-11-27/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=6223dff24490e3e8506dfbe2b12620155d7c05fce92191cb01f3b28e269bf1be
dist/2024-11-27/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=6fb1edea73bcb76d9cb6061d1aba15ee4655a212c1bf96328a225c7c05df3462
dist/2024-11-27/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=0b7bc9ec0c40a6203fb62eb71fb6eeab43a4f64a2f7d0d51a1e0d041a216adb1
dist/2024-11-27/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=d77a49acbf26b8c9a2a5f79fdc640feb1c81b9fa38f442b81f69127f49c7cde7
dist/2024-11-27/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=bdf45a37fad10df4822690ea73840b38ee3e1048878982e625efbad3b2054f28
dist/2024-11-27/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=ad6a2f03b2e27711e1ec4eb75502782c4bc0200cfaca2b5246e0bd5b86bf29ad
dist/2024-11-27/rustc-beta-s390x-unknown-linux-gnu.tar.gz=b0cc3024a717d33775dbea63e83f317f8826e564ceb4ecb7a6cf23676f66ccdc
dist/2024-11-27/rustc-beta-s390x-unknown-linux-gnu.tar.xz=9d5b44a82803d5de5355ffced6ec1dcb9860950910bba6dc54878ad4da7ff444
dist/2024-11-27/rustc-beta-x86_64-apple-darwin.tar.gz=c7174c35b530453182f5f0b15c6684c030a2ff2770f4cc1a4a4ba75695e53b99
dist/2024-11-27/rustc-beta-x86_64-apple-darwin.tar.xz=c68c26159a3fb4d4380fb25488aa78223989893d7786b8ec947d82ce0cc905bc
dist/2024-11-27/rustc-beta-x86_64-pc-windows-gnu.tar.gz=c97caf7877097d78fe2191e715e3a45d827d28c27b4dabf0747f8ca522ee43f5
dist/2024-11-27/rustc-beta-x86_64-pc-windows-gnu.tar.xz=b7794ecabc42698cb77c1c90d66676a8b1b3632108ab95954ee496ee7d6e5708
dist/2024-11-27/rustc-beta-x86_64-pc-windows-msvc.tar.gz=28068a6e050abe21933920dba3ead2261f7d0c09687d5a86a5db51cca6e72ea9
dist/2024-11-27/rustc-beta-x86_64-pc-windows-msvc.tar.xz=3860d7ec8564019c79551727a3a54c66453a7d654fbb89b8feeae75d9021fa77
dist/2024-11-27/rustc-beta-x86_64-unknown-freebsd.tar.gz=6c2a918f8d40ba01e648565c98ea120d32562dd93820e8f2e33abb2aef08e1da
dist/2024-11-27/rustc-beta-x86_64-unknown-freebsd.tar.xz=5d1edcc6c4be49849c3c2d1c3c173d4a127db3cfb615093e5ee396e0d0c77366
dist/2024-11-27/rustc-beta-x86_64-unknown-illumos.tar.gz=a64c30d82dca58d09bfa38e72bbe1457b48b101157193a3ee33dd85922bbfe9d
dist/2024-11-27/rustc-beta-x86_64-unknown-illumos.tar.xz=87d14b146386fe1f9e24fedc25e1bf9682913bbd7537047b0baef0d74cad5473
dist/2024-11-27/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=3f186913535ac59446e249f4d3e35e3d93a3f8207b31ee31b3f70af8344856bc
dist/2024-11-27/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=0c17a60ebac74a9cdfc2ec69fd71a21e370ff178f4c83be6020642b55b6d78ab
dist/2024-11-27/rustc-beta-x86_64-unknown-linux-musl.tar.gz=327973698dd0ffe9b2d56b3b5929f82ec552f2002b4113fc9a738e27b0005ac0
dist/2024-11-27/rustc-beta-x86_64-unknown-linux-musl.tar.xz=d7e2f768922ae36a9eb302667398ee308c13f829c03235682529fce90253813d
dist/2024-11-27/rustc-beta-x86_64-unknown-netbsd.tar.gz=13f327974170a0423ea6e7241cd3a454ab8c39b657a707c08f2e306a7a657b45
dist/2024-11-27/rustc-beta-x86_64-unknown-netbsd.tar.xz=5c75388802c0ddcfa51336883f4039b6f7963e0efbe47c209bb455c12951990b
dist/2024-11-27/rust-std-beta-aarch64-apple-darwin.tar.gz=84c4c02fdecc669c5d26c49120fdece5899133c098f5ef791ea19aba33936dea
dist/2024-11-27/rust-std-beta-aarch64-apple-darwin.tar.xz=7ea047840073e6ad3123a61ca799bc56c951edbb71cb8495ecbc2029759a0190
dist/2024-11-27/rust-std-beta-aarch64-apple-ios.tar.gz=dfb8207b4b3bc13a9704fd1d212d92a22a0e7a57293f24f28bcaa846ad4c08b6
dist/2024-11-27/rust-std-beta-aarch64-apple-ios.tar.xz=96940a84d95b4cfdde84a501758c9dd83f5d6cb5afce9142917d5cb3dd75c040
dist/2024-11-27/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=4ed66daf59e9a8b61d66caef4b2248be72049282518d7526be771301bee2b905
dist/2024-11-27/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=013d59e32097917b269c45a837bff380a41c4f6401b0c145264cca5a1bbd91c3
dist/2024-11-27/rust-std-beta-aarch64-apple-ios-sim.tar.gz=270a0322dd3c2342745faa8797f4f64da8c0028b322385d209ff65cf04965a47
dist/2024-11-27/rust-std-beta-aarch64-apple-ios-sim.tar.xz=9d54f7f51c99f17ba9cfe7cbe005ddbfe598f8af6df1dfccc9ef37029cc08b41
dist/2024-11-27/rust-std-beta-aarch64-linux-android.tar.gz=9ae4c1d6044b2c3586791f127108e308e0a381e8e14ecc20b3830ae5258a03c2
dist/2024-11-27/rust-std-beta-aarch64-linux-android.tar.xz=689225ea098a88a88e8e2269ef53f964405a6c31b3ee2bda0fef98da4ed9178e
dist/2024-11-27/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=f1d9c996cbe468ca93b15c76b84c544930d7452f1eff2968a298c885203f14cb
dist/2024-11-27/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=f3f8c088d74c81b2457ddff57008cb908cc86e16d0fac60d10969e45210d88d6
dist/2024-11-27/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=fb4e5d66911a47bd63429686885cd5c7f0a6310b25622f36bb43a754300526be
dist/2024-11-27/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=ab6c7d346bfd72f06fbbc198743bda35fcb7fd1e131c05c54935b6ceff282f17
dist/2024-11-27/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=32b2e0d5161f7d8354d846c91e5cb25530e78351dfcff4ebf0a6fba669e2c483
dist/2024-11-27/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=656fc4a8af570b28b3f83cd59d4e5226f15d11b5d8c26b58ca2c1b2a4e18c4df
dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=13c98efcde78c1e187f728509f2950a0a407ba32e730877cb9ca4cbb4ba01469
dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=6372891715046375fd0a04e80c95bf79080db2d136e187b02ea96647e9281407
dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=db156e0d5db6f04621e625e92323a04091c049a8b5e2b4f7e0fb2e50b81ab2ec
dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=b610214bb59b8f58be96b84b0f13e5f50473e21039f6e827fa16c446d0e9ccba
dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=99f96b0bda31bf21853c96b3618408587f275f46ea9bd7d1fc741e58343a5625
dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=dfa1f209f546b457aa6ef742a645f00f55c70fde86522c737f7a560494170157
dist/2024-11-27/rust-std-beta-aarch64-unknown-none.tar.gz=4735b29991a2337a7e2016c5a827635e17ac149372efafc0442a86b0dc0759fb
dist/2024-11-27/rust-std-beta-aarch64-unknown-none.tar.xz=fead0635c572aa4f5e5564e497f1b7e892217ebe52fea54aedacbefb32f6343d
dist/2024-11-27/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=bbb9b6fedb874a61d99d22b4cdb2d20d8b9e6c69924922312692aa526851b960
dist/2024-11-27/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=9e0d48236676dc9947565daf0c2605316c5b4abc06bdb1c343559c46b9c4e304
dist/2024-11-27/rust-std-beta-aarch64-unknown-uefi.tar.gz=e230ffa3d46dbe5330416cdf8b7235b8dc2cf119ef8990b422eeebd017ebd17f
dist/2024-11-27/rust-std-beta-aarch64-unknown-uefi.tar.xz=38a5560575740f92cb8664d204924cf7a2972e0f2f396852d8a22befd2cdd848
dist/2024-11-27/rust-std-beta-arm-linux-androideabi.tar.gz=0b0a9f95d10484207c52fcd8ab1bd56903b53f18ce46fe263d5b7bb085044246
dist/2024-11-27/rust-std-beta-arm-linux-androideabi.tar.xz=91f7655ab2bce397a0821edc0f523dbf2bac0af39a50ead106eb1de637ec5c44
dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=e8210f03bc18661954f147dedd0b4af721d005866c0c4fea1e91594cd6c9bc2b
dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=56a623817e6a600e802727d59d4cd653e84cb628695e39ecb23ae99065113115
dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=310a408bde58335d8011af480d4f8c38745865772d71631596cef1a79f9f4fc2
dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=fd6766ea9e828adc2e43ff1654a459785eed05ad00c7f6804c742ff8ae8f6b8a
dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=e663e30526d85d89f41456a3d5bcd411397cb69e7cb9508aa1472b015963fd18
dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=0361504ada464a7d21e7ac66fdf9e1e820695f3a8ca4854695e78a748c5c7a18
dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=c375be97e626900d809390c61bf6f2d689c9fca8e58c85e4e02b694bed4c5ce0
dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=c33e3b4f9098860f75fcc9a8f86c7e7173692ad4c19cbb2c0de068961f87c192
dist/2024-11-27/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=3f50d9afd9df4db85958e4575429dd4c80b6702a8d91c3f1d9327345aaadefe0
dist/2024-11-27/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=0016d3a6ec8351ee9fac2eeae358a0854a3c2b360822bb3ba670255e8f27f57e
dist/2024-11-27/rust-std-beta-armebv7r-none-eabi.tar.gz=f23117b972ccd21c0a6f4db4b544401045c9f157595a297fb56d7e864cf190fe
dist/2024-11-27/rust-std-beta-armebv7r-none-eabi.tar.xz=ab9be4bb25b1575af276cbec7fb1a1f8c683741b0f137bca7b4b61ab13575645
dist/2024-11-27/rust-std-beta-armebv7r-none-eabihf.tar.gz=673561456e26bc992cb6a888c34c0b6b13e1bd0d3e0764360a785a6c3369f0d0
dist/2024-11-27/rust-std-beta-armebv7r-none-eabihf.tar.xz=29c6f01c636bcd901b88e92c60874c454369efd41f690d74b1fa2adf3450166a
dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=c214d4439676a19c057324dc736d63aa0328ac74c0eb9ced8d782d8bc89757ae
dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=4baf85ac632750c35d007bcae8f23720208c5197f4a1d49b0a85b2b0e137f603
dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=a7e81c0e80f2508c81ba9d8e658dabeb19af2de6f7365f6e377d39e99d8449e7
dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=3f37f746aaa03107573a3a2b201c15bf86777ec405dc03640e7d3f24f718f67f
dist/2024-11-27/rust-std-beta-armv7-linux-androideabi.tar.gz=fe7c7ecb8a8e612caf0e7ecf04d18ccaed31d8b93911ded6b3cba0c78fcbbddc
dist/2024-11-27/rust-std-beta-armv7-linux-androideabi.tar.xz=d571b714821de4b7d2accad221b5e043e7f9aead8dbc06586f4f7ff3f3f3e38e
dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=663396f0e4c45bfc041b1a502b64627620f499ca6343664633761c3fb1c2229e
dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=4d8c47d74958e3b1058ab721e9c6635774afad0252f251b0c9fe4f0895d0c81e
dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=3cba82809bc1204b6e8f62877c5e9f9a08f111da7d439032cc30d55be0e88fd7
dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=d525a4dde496e72fd18c6f2a525756d652ced436007f513267e9201d8b1c0a40
dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=ec0311a0722f205b117160817b2137e9a73f0f4e540930d61c831ceba1265f0d
dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=c63c4a28225dfca26baab129f06d8537fae5710083046f203a2fb73c50b48671
dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=52eae1bdf37366bf406cff95e5e7979d0651979ae5ad4c036e8badddc8ec8b82
dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=542791fb5cd80fe5515ab0812c9fd8671f083151d4262fc76d26f7723ba961e1
dist/2024-11-27/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=91697f75c762bdb51f19348953768a45bc37c389c2e904a56f4f092604ed2d1c
dist/2024-11-27/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=a79a7a5974b365f70598c413da3db8262d14414e3b4d48dde45f529bca4c6ef8
dist/2024-11-27/rust-std-beta-armv7a-none-eabi.tar.gz=6eec497ec2aaf6c5beb8e6dfbeaf32190b6f7206aebffb7499b5fdd7e5e7643a
dist/2024-11-27/rust-std-beta-armv7a-none-eabi.tar.xz=234924a6746fed2efa112b0b805d0ca56252b6cde82e6422774871e9c009fed6
dist/2024-11-27/rust-std-beta-armv7r-none-eabi.tar.gz=1b0cd107412fae22266267bd8eccd2b39a36afa8936da3888d0bd0d2f4cfdb1c
dist/2024-11-27/rust-std-beta-armv7r-none-eabi.tar.xz=0d0d1ee48f9032df88ea7b3f73f06300686f4d5b9fc16f1d4554caf8356cfd74
dist/2024-11-27/rust-std-beta-armv7r-none-eabihf.tar.gz=72f0549de44925bd08286e092261164dac47826124123e3fe707411a3dfa756c
dist/2024-11-27/rust-std-beta-armv7r-none-eabihf.tar.xz=eb45acd55dd70be3670de83c8cbef5b6ef05827b3f97b7c71679a19c88f8f3e6
dist/2024-11-27/rust-std-beta-i586-pc-windows-msvc.tar.gz=edd8dadbba618f2a786dfcc68e4a5c7f2b7cf1528d1c16ca6ddbc52622df95c6
dist/2024-11-27/rust-std-beta-i586-pc-windows-msvc.tar.xz=ae59c5d77b31aeac30c22104abc0abda6b7f725419e9f86db6cae634ededf262
dist/2024-11-27/rust-std-beta-i586-unknown-linux-gnu.tar.gz=8996c94269e4c60270d253ea75bddb9482facc441ee2314a387888924bea1d92
dist/2024-11-27/rust-std-beta-i586-unknown-linux-gnu.tar.xz=f6b59e3d6e7f0e458c048ad4aad9a2da23f3b54aeac20a905d2e00379da1bd6a
dist/2024-11-27/rust-std-beta-i586-unknown-linux-musl.tar.gz=85f22b148be72691214dee620eac582405dc3b8937d2ef7c480c9070b963af3a
dist/2024-11-27/rust-std-beta-i586-unknown-linux-musl.tar.xz=4b48538541dd20fad8569cb3f0994d5ce6aceaacdd8b319d00b0234cefc5c267
dist/2024-11-27/rust-std-beta-i686-linux-android.tar.gz=6e5ce19fc4cd8cf4dbaca8b31f4032b08ee413ce20f354186e4945efd4e8b6af
dist/2024-11-27/rust-std-beta-i686-linux-android.tar.xz=5e78b98abdf2b7348381863052c109beec025a5f68285ce72e6f6e9245c22ce3
dist/2024-11-27/rust-std-beta-i686-pc-windows-gnu.tar.gz=50057f990d1127e7d693b1c5b9539b19262a478130bed51dbc2837d61d2db6da
dist/2024-11-27/rust-std-beta-i686-pc-windows-gnu.tar.xz=ea524b276e42a1cb918625df12b8d3397ada5ecd43bb9ad5c676747e1f916c8b
dist/2024-11-27/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=c7c9093e277187590b86ea02fcd940071c8bce93a894396d73953276ec58eb1d
dist/2024-11-27/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=a67879ff0dcc591d30a155fd972149953eaac3b139bec9aca3a383dc277ddbc6
dist/2024-11-27/rust-std-beta-i686-pc-windows-msvc.tar.gz=a086c8272f9c7c0db3d5de37b027478dfc22fc577c613254a821700c645df3c9
dist/2024-11-27/rust-std-beta-i686-pc-windows-msvc.tar.xz=8ac4b938e0b643e47d6d0ba6e5283887fcc73cb1a825fc065c35879b085d9c28
dist/2024-11-27/rust-std-beta-i686-unknown-freebsd.tar.gz=3614b95b54ca24c598e3ed6e14aaa86f7048c2a5be2b3e9f97d9ca00f3d890ce
dist/2024-11-27/rust-std-beta-i686-unknown-freebsd.tar.xz=6d36127f5c113b01300fa0d54062bc1137b51d2514346c8d84bafb9f2c56a972
dist/2024-11-27/rust-std-beta-i686-unknown-linux-gnu.tar.gz=a6d33a96eeb667f3f4649ea6ccdd6212a183bce85f095ff7db5036c3a50d35a6
dist/2024-11-27/rust-std-beta-i686-unknown-linux-gnu.tar.xz=bab1dada484d61bb96e2834da5fc6ed5d4d788e6636849e9802f9fb6bff45d55
dist/2024-11-27/rust-std-beta-i686-unknown-linux-musl.tar.gz=0ac331a1c9e384430a5f316809bffdf01bae3ae9cc1f807f07142ffde7388602
dist/2024-11-27/rust-std-beta-i686-unknown-linux-musl.tar.xz=136341bbf4c820dfc98e96cee41fa0e9fcbc7d81d2772407efaf1d4be6d10f7f
dist/2024-11-27/rust-std-beta-i686-unknown-uefi.tar.gz=32f06ca3b2752a8687e2f282a59823671fcec672bffc0775a9fb27da50b6bb11
dist/2024-11-27/rust-std-beta-i686-unknown-uefi.tar.xz=b2f376089b39a34f3308833ce9bf65200f9665e5c55bbda3e5b7e9c5096b7e67
dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=a2ca950893c93be71c7db707230b98674a29c013546e27d95bdf8c3c6eebf9a7
dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=c70b58f4583578347e9f0fa20d17bd5fc51d88717095e05d73091209f2a363be
dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=ed284c40b6253c022e39718dc2af2e4100ca7e805d35d86aca04937586f26ece
dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=3efcabf46e0d02505ebf0926c6c14e0c70838f9b510f2328ccd98dd0fa977794
dist/2024-11-27/rust-std-beta-loongarch64-unknown-none.tar.gz=9b9f8418fdf64fef652f15b28a1a1f2f8c63c18da8b323994f10f921010721ab
dist/2024-11-27/rust-std-beta-loongarch64-unknown-none.tar.xz=fdc673e4b250424c6dafc18a165ffb592aecd7b897e483af8ca54aa145a0e6a9
dist/2024-11-27/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=802d22c1c364a58402f9313c6ba2f58b79f3cf3163842a608b78680fa2b3d476
dist/2024-11-27/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=dc4932d91d8a2887d309dbd6317d6c41afd083043f44742138ca7c97f60b931c
dist/2024-11-27/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=636b19ca036fc7ddcf358062c98f6bcf31e8c2cd035cbb9dc0a6b96c81217f7c
dist/2024-11-27/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=31f80fc50be95bf665d21fe52b714532ff34ebfcdc0c975bb68f7d2f2cebd0e0
dist/2024-11-27/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=f2c83275df652bc5b387525e77a1aa30bac31fb301b304ddd7e6bf402e140c34
dist/2024-11-27/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=41358bdb20fe3a97a95fd7b656b1ed03d5b8012354d8cfad2437bc9ef6c7aeb6
dist/2024-11-27/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=49b8f286b4abb3b34bd38c92ea3e15efbd1f623d5efa7bcff10711b595363579
dist/2024-11-27/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=283f065701c77fa47a2d5413d20fa40989fbbcc75bc938889de6c4f9b6b9e53e
dist/2024-11-27/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=d0ee5ba5dd6f94dc6ca981be0d55f2e3f51c2af25877131a7a74e0ab9848dc3d
dist/2024-11-27/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=79c78bb31022ec8e7a3fad9823c5d22ac553d389104844110473d1877d8c8302
dist/2024-11-27/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=b953686e3034f2b51033a2630328c8eb5f59fdf8ef4e26189bddb8efb4c482cf
dist/2024-11-27/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=fb25ac2e68594d379f915f0555b3ded2b1a7b5a67144e12eb62949f540b0d957
dist/2024-11-27/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=fbf5a16a57de3a7e846389aebe18bc7871f43e67eff39fc9b4744b5a445b2639
dist/2024-11-27/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=55a92aa5770924a21b706724c15f58d66ef2ca5b630f7025f6ba1416152ef350
dist/2024-11-27/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=b880b7209ea604761ad2a46832925d32fc547737b879645fd3cf99ec235e7b39
dist/2024-11-27/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=c48cc6a6fda06fab014c0b8fef49006dd32fb71f8e981ba44a0c25d47fbfe034
dist/2024-11-27/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=7d133b6c8d0e8b8ec8b65a74ed8d64a22e2fa5e4f6d4a1e36f9e0ebb8826f40e
dist/2024-11-27/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=1c507e003c38115bfffe8701df1ff7aed6ad16ef5ac4b383f84bd2d6aa0216bd
dist/2024-11-27/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=111a909b3d1a04b328ca1c1f247ee4eaaa84349eeaa8df77f7901bbc0efc94c1
dist/2024-11-27/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=d29f92ed071c60259feaa8005eb5392da549f8e2069fecb1b77e112f89cf1bbc
dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=241b1ec9ef6a89277944c9d8021f521284dc28822c5f80513b6cd94d2bdd1d64
dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=9f5b02be846fa2084becc5616f024094d47beca102442ac7a0e3588e0f12ee7e
dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=7272eae1625415c0f57bf541dd62c14e02b9946ca1de04615827a1f5218c2181
dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=d4bcd0068d3c9e7351565fec57ca68d36c9ddbfe59249a6bd2c56930ebad2257
dist/2024-11-27/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=758ccc47004398add2e3cfef52e4839e14dc4d132a215658e576e590401a28ca
dist/2024-11-27/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=6902fee1027b0136f8dc5179e69e24ed9e34366e9409129b9ba223043ddadea1
dist/2024-11-27/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=3024570f3e382a57fce0e832c52d080a83d42206d8412b724361bd1f0087ec4d
dist/2024-11-27/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=20eaa72b6fa32b9884b43030a0bee554bafa9de3f3b51c5768ba0ff47ec492c1
dist/2024-11-27/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=a3eae70be3fa5b0a56cc88cc6433cdb7c42b3b974caf0d879d21a5219f4f826e
dist/2024-11-27/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=1da88d1882d4dd1f15ca97e016f392a01b56951882ae75929023e83fa557d796
dist/2024-11-27/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=387cc8ccaeed6f9c6a8c9d21004e45ac97a9739643a63448eb893e13ed4df22d
dist/2024-11-27/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=1b9afe3631fb7847b2a8a8f483fc00ca203ccc18ae298339801dab1c7b06b3b3
dist/2024-11-27/rust-std-beta-sparcv9-sun-solaris.tar.gz=f9a4d2115d6fce06e0da7a9f579b197d383034c218573e145b3c7dae0aad21d4
dist/2024-11-27/rust-std-beta-sparcv9-sun-solaris.tar.xz=c352bc631e538d4e68eaaccdfb9dca1c9dc8ff0ef4a75d8ee91016aada39d717
dist/2024-11-27/rust-std-beta-thumbv6m-none-eabi.tar.gz=d97851ca9193d98192a55aeaf695973ac706e6ba3e198643c200cf410817b424
dist/2024-11-27/rust-std-beta-thumbv6m-none-eabi.tar.xz=89a6524a3743e5a769a583b4a6bf8a76ef5b45c67b7e39da7ae24b687bed4943
dist/2024-11-27/rust-std-beta-thumbv7em-none-eabi.tar.gz=6fe614db166618a8f2ccb5807e02884daa8bd8dfded2164f88d79fc688047020
dist/2024-11-27/rust-std-beta-thumbv7em-none-eabi.tar.xz=91c5e4f4575ab004119797988679077e5057881ad9a7f6790b673dd062a8b7ee
dist/2024-11-27/rust-std-beta-thumbv7em-none-eabihf.tar.gz=d0e05467fb1562ed7d6687a50b7fafa14ba0c2aad328f0e7c19eaca1ee366475
dist/2024-11-27/rust-std-beta-thumbv7em-none-eabihf.tar.xz=0473372df5fece49e58efcd3b2a702bb93e47ec149b38fd5244ad667804e7c63
dist/2024-11-27/rust-std-beta-thumbv7m-none-eabi.tar.gz=e6b6130a1a571325cc1bda8ddba6b2672104c2feeed5c93c6022bfcc8ba4b247
dist/2024-11-27/rust-std-beta-thumbv7m-none-eabi.tar.xz=d4c739c42104e04aba55b96a3ad434e11b013ba44649dd3a648cfbb15de83eb9
dist/2024-11-27/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=e427d5d6a53abfb53b436df96457d58eedc648198fce6b1d976b50de18cbc31a
dist/2024-11-27/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=11142018c11849c21adaa7096abf50d0c923f3b8f07d67eb96d6860d428e9b27
dist/2024-11-27/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=46596d8f2271dd5a6f0f84387ac19d0e81976adfc6050b6aab6cc554102fe469
dist/2024-11-27/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=f3d0c9db1c50a018540278433fed2e0ae4bc798aa0dac87cf0f55ad1808618a1
dist/2024-11-27/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=c46fc4bf174fc54f5565fa04e80efff4e853642e3e5f0bf5b696a2bd6e7ae817
dist/2024-11-27/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=706c10ef22cc16b3d4cab8fc09d8783384313b9f774229470b8ae1dd292850b2
dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=b9cec80ed374f7b5f22f1446e3f2e0dacfaa0e2d4d6c631ad66cc42a23e156f7
dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=41c67ee95e72a3d10bdf739c4841bd937c4e0b19c33451724c1f603b4bd2a318
dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=5ad8603f98cff0d5d015c72f3a55730d75d59680a867c067928bf4586c00d805
dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=61a75701f7e000f86f318a04dc6746f029fb933e0ea94944d76c7eefca1f24b2
dist/2024-11-27/rust-std-beta-wasm32-unknown-emscripten.tar.gz=89bfbfea23974ed75a53ff134386992e9c257d3e51a55eb49847aec9c5ba6b13
dist/2024-11-27/rust-std-beta-wasm32-unknown-emscripten.tar.xz=e34d1586bc6767b4b244f98754badda706645fdec7168ddc0a409b9f95f2b18d
dist/2024-11-27/rust-std-beta-wasm32-unknown-unknown.tar.gz=8a88bb923e138d0015c8f46bc1c3d5f2f5f75f40dddfca72a49eed42c080d1db
dist/2024-11-27/rust-std-beta-wasm32-unknown-unknown.tar.xz=79a980f2b999c3e3b04d7e327bd2b548007039b45da705847c6da2bfec3ffc04
dist/2024-11-27/rust-std-beta-wasm32-wasip1.tar.gz=454e2c4b46b4684e591c6e4c0f1ce8e3c44623a29d561be3a481ae008072dbd5
dist/2024-11-27/rust-std-beta-wasm32-wasip1.tar.xz=4dcf652ab51fe03c4691de46365218dc483cf1f7c2f5a552a38509685a0ca873
dist/2024-11-27/rust-std-beta-wasm32-wasip1-threads.tar.gz=c2c34d9b3998633cfa145dc2a5568a99d1fe26b91c5be55a08870a1d27db4af7
dist/2024-11-27/rust-std-beta-wasm32-wasip1-threads.tar.xz=4d5b25e4b5fb71d879f15f320f7513eec1ad078d3ca6f525ebf56b9620bdb5ad
dist/2024-11-27/rust-std-beta-wasm32-wasip2.tar.gz=e1385a340d3d9a4003cc456156bfbb1435a5255b2bdae3a40b6d7339768bdc81
dist/2024-11-27/rust-std-beta-wasm32-wasip2.tar.xz=245e7914174d213ddbb550b09fff200f419bcd632de98548a470013891666410
dist/2024-11-27/rust-std-beta-wasm32v1-none.tar.gz=d5d924ea001f914bf87df8765b013db6e838a930a4865e95f8d35bfaa86bc81e
dist/2024-11-27/rust-std-beta-wasm32v1-none.tar.xz=bb98d0d55f38f2308bf99d4e5f11842683452571075eefa5b4e1f18f2bd553bf
dist/2024-11-27/rust-std-beta-x86_64-apple-darwin.tar.gz=edd5e7ea230a13be750dd74c5f7a7dee20db8683f7978aeb352307a0ce110b9d
dist/2024-11-27/rust-std-beta-x86_64-apple-darwin.tar.xz=c6cec9a501d9873e3c7abdefd5b9418f7250c8cb915be8b816cb48dedf1f201e
dist/2024-11-27/rust-std-beta-x86_64-apple-ios.tar.gz=e970c2a4ebfb69219dc66e4c7541cf22c52da5f94983c7c914df1f93beda3d31
dist/2024-11-27/rust-std-beta-x86_64-apple-ios.tar.xz=594ae9bf5f1501322d986dc91249a48a61c22371513b872fd63e134097ac55ca
dist/2024-11-27/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=d57bf579b4629417dbe1c02506db4a4ba4428871a2684141d21303e6c99551f5
dist/2024-11-27/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=714db83e7563a5f286fb37bc629b64834a9ed981bb9a05931122072f95e39bf8
dist/2024-11-27/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=feafcba9c46ba3e5fa0bd9b5bedc05ef3423c9962dc4d25a7b2367e3e1caa679
dist/2024-11-27/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=78fbc8f45df64dca21da7223b5d081111922f2268fcc4f1f83595d159d310bce
dist/2024-11-27/rust-std-beta-x86_64-linux-android.tar.gz=74fb57da7f2907afbaa2a7a73847273ef81e2d6902a326f1ae87767677a864d3
dist/2024-11-27/rust-std-beta-x86_64-linux-android.tar.xz=3216eb73d9c9effcd2a2de7f63d78055c3d7e50fb8141e2910a45a36ce744ffb
dist/2024-11-27/rust-std-beta-x86_64-pc-solaris.tar.gz=3df431c8941ac28906c3a6568d3debe478d9349d868ea8bd3ad79e65792c20e8
dist/2024-11-27/rust-std-beta-x86_64-pc-solaris.tar.xz=548c2a6104148bf0da21bf5e009b80522fd15539077a62021a64f16282815a5e
dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=235228431d67feb4c8e6aad44e20bf68574f335e8f948808b597ae98d827171d
dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=5a2d4ed70aed26f902cf45e1dcabc5f25884cf6e9aaff775405ba9c1f0a5cacd
dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=818131158e8be6af4b762750f7927c4a799346c94059a6073230da79b4408720
dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=fc08b39833e2c9319dcb55cef5c6d1f0110aea794c9a6f163ca39749a22a94b9
dist/2024-11-27/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=6164c3ade38c03113193301b815c52df0ee84a4ca1c8ef21e1a56d386e28df00
dist/2024-11-27/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=0846126e6c4cf2b5184979b6025fbb7bddb5c22905bc7ba31fff69f6b1459280
dist/2024-11-27/rust-std-beta-x86_64-unknown-freebsd.tar.gz=ae308e29be13a176b26c142347a81facf8c11ef1a28e67d5898f4f2a0d3344ca
dist/2024-11-27/rust-std-beta-x86_64-unknown-freebsd.tar.xz=e80bcba8b011a4dd3f7b2a2cea69b5a95ae2cde9b2d9078ac8fdd492ac162139
dist/2024-11-27/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=b25f0d605b7f4a2a93adb746e32f59bfc26af569a4169e9fb203cb33751d1575
dist/2024-11-27/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=010f35236062a651b1b54d7c928068efca8dc486856b84b04e98f4f97583bf32
dist/2024-11-27/rust-std-beta-x86_64-unknown-illumos.tar.gz=db3d258c2caea73b469feb9c11fbd3bcc29d22c3969c406321d11f05c24974ed
dist/2024-11-27/rust-std-beta-x86_64-unknown-illumos.tar.xz=a952b0c2bbed9085525c041c957f00b6b1020e031149dba70c09a1a0d40db3ad
dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=817d3d3a931eba2255bd5721435cba7604fe37a72c18a179c1fd5f06dc3b97a1
dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=170a54aa50f161576d4b0d103f2ab6dcbbb81ee57a5a47f7fbd181128f6c17ff
dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=ea991dce55415ed7462abbeb1ac1c70795cb628b0460e14230e8cecd41117fca
dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=a8f620c3a641f8f4c29d88e4cc54d7637aeb18cf8eaed8571ce558835f742601
dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=875e2e3309b1deccc1a4476e4847a2849df32e0e2a394e4ddf3b4abd1feca534
dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=23f21ac664b3341771109ac69d094518a512391b86219ffec50725dc68a08504
dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=680f5b2c63f58643bd34f9921e2c1699a549410ab06bfd04ce991907e8fd7d8f
dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=dd10f6f3ce39489b6e3f3f638573e850c36518e3b2e8ffad0c50c3143e3a8124
dist/2024-11-27/rust-std-beta-x86_64-unknown-netbsd.tar.gz=fd31ba490f0bfc53530e34e6e5ab35a52eebee616efc8ed18d473065ea885230
dist/2024-11-27/rust-std-beta-x86_64-unknown-netbsd.tar.xz=daffc01050f5cf0b5ece91717d7a4c42cd4a148c4c11f641b494d9c375df5177
dist/2024-11-27/rust-std-beta-x86_64-unknown-none.tar.gz=376d571641a9f1f75fadf951da91bb73ba94a5495d7d33389f5f914ccbec57bb
dist/2024-11-27/rust-std-beta-x86_64-unknown-none.tar.xz=ffd9e826537dc94c6d8e767ef5a61d1fcf0385b8ccbe508ff9177de0fe772939
dist/2024-11-27/rust-std-beta-x86_64-unknown-redox.tar.gz=447e434b5e40f7882d7adb6d0346629e0e3e92d0f339c7781e5a437898a84b4a
dist/2024-11-27/rust-std-beta-x86_64-unknown-redox.tar.xz=bc21caabcb492ca648e19a8f3b9dc1a1bf7792135a202831deb554ec3ea11077
dist/2024-11-27/rust-std-beta-x86_64-unknown-uefi.tar.gz=40ca7d9ebcf6610c26f2921c0560729e708f5661bf6167266e9d8cb3987ad0b3
dist/2024-11-27/rust-std-beta-x86_64-unknown-uefi.tar.xz=06966d5901f5d9accadb47c4d1e561f3f95bd050f3f8e78f30000389f39e9b6c
dist/2024-11-27/cargo-beta-aarch64-apple-darwin.tar.gz=e1a24f081ddd93b483c0f1c196bae676163db50fef0a994bc47c2a7c98c9dfa7
dist/2024-11-27/cargo-beta-aarch64-apple-darwin.tar.xz=d51a5f0669906eceeee4e09b079828e2ebf3404aaedf1fb20745339205270ee0
dist/2024-11-27/cargo-beta-aarch64-pc-windows-msvc.tar.gz=e135a5f0f83432b58d9e093c6d560b021a133707e39e1ded90a28a9967105e0f
dist/2024-11-27/cargo-beta-aarch64-pc-windows-msvc.tar.xz=1fbe65015cb8c7ab0b863ffc6f7aa72d3bf52f7830957ede8915c61a22e5b993
dist/2024-11-27/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=9d4e830e9ba582302865fcefe31883cef4a471e77d46e70838e549ca11a0fbce
dist/2024-11-27/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=233f6347a36e806dcf27ecad4906c90bb3353051f440a819989efcf091cb78b8
dist/2024-11-27/cargo-beta-aarch64-unknown-linux-musl.tar.gz=6cd719a7255a0eb1f11592b9a92d0aa4986363f624ee0d6077fcc253acab66a8
dist/2024-11-27/cargo-beta-aarch64-unknown-linux-musl.tar.xz=b874ca8285ad1936adc70a9323cf80f06322b1e6d5925f54b58500129830f0ca
dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=ec7200319224ccabe814cb051e51d147f1ae8c763413002fd03c9263a02c2320
dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=86e96c80a91862e59123272c80f1cfabdca56bfddcd66af4a5e840af7421c4e1
dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=3f7cfdcb28fe8c3f0dde58c24a0c424652b40d00a24fc50891351fa5bff5c15e
dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=2d5a184b0103ac943ec4f6756fbc7126773e739e0d120acea7b3244c7cd19b1b
dist/2024-11-27/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=9a77540943f28584d90b4bcae4e234cc9d833eb732f65d7fbd680a0f4e915da4
dist/2024-11-27/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=7696a065951b7d7179b30ff2fd16a05675b6bd4250f293666b98ec05299113a5
dist/2024-11-27/cargo-beta-i686-pc-windows-gnu.tar.gz=eaff75076ad71a4291af5465dedf0fb0998dc171e35ab8f707ac63b43e89c38a
dist/2024-11-27/cargo-beta-i686-pc-windows-gnu.tar.xz=205d3d19726a1a87a1533d94f77b73ed9de8181906acb48088dca22835aa7a83
dist/2024-11-27/cargo-beta-i686-pc-windows-msvc.tar.gz=58da319889533ff7be5c9142c2abdd1ade79de10eb83d7ef82ebd93b75607f8b
dist/2024-11-27/cargo-beta-i686-pc-windows-msvc.tar.xz=5ae699d0f6b9e210a988af5b8f2f0c4d62fb1695ed6fa55718fdf05298039b9c
dist/2024-11-27/cargo-beta-i686-unknown-linux-gnu.tar.gz=362f6338ea929ceb632307031e049dee1b3ed998f5cf160654c327c5e0e7ed39
dist/2024-11-27/cargo-beta-i686-unknown-linux-gnu.tar.xz=88f14ca7b5c8af006f3c54749b61747485f7e93fde4c65b5969e73503d12c5c2
dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=9ee8f29e3e715cd7c85e679fd01ca724a27503a50edb0e6f8912f289630bc7a5
dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=4c643f0d18ba101c2b248e1df32ec3ddba82efc0d5f9b47945d484fd3d462794
dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=f70952c63e2eebd05acc326cfa667595535fc36db34bc0262fda4ba100ff2145
dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=0546a908cc12884801c35b461f98db01e87a7f92d276ca6cb6b89eb76c596e2c
dist/2024-11-27/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=3534e839b34603e4e2b32fb8ecc76163ea3b9cd9907c1a22fde4165860d1fb56
dist/2024-11-27/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=b402a2e73debd81dc5cbc866f00c2ca82f676e2f923193674969af0ab34ad311
dist/2024-11-27/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=fa69011557fdde5af1f78f33f9ba75a1d6f4488b9d8edd2958582593dba347fe
dist/2024-11-27/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=679be0bf62c7371b92f1824c8718662672ac3ef2d79e8af5c752fe34effbe333
dist/2024-11-27/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=ecc2ba0da5c1057136eb105ec0727e55396e414d75efe0c2b96bef0477961574
dist/2024-11-27/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=a89ad44842df861c69c6633ba79bf4ecefc38419d5669b6f22a265dd7be836f2
dist/2024-11-27/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=051437ff7d177bdeb7a5a0eb947d27b8cf352c8e809b9311a1cc21b785a5a8b5
dist/2024-11-27/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=1a4f50972104a95c404e778279a4acd42176cae45f58d316d601e7f38dc7bbc0
dist/2024-11-27/cargo-beta-s390x-unknown-linux-gnu.tar.gz=bbe9812fe890b900e71aa4714dabd2f3e67bdc610fe0bbd5aea645ee807dd0ff
dist/2024-11-27/cargo-beta-s390x-unknown-linux-gnu.tar.xz=eebac7e8555f44ea9094750b61bd11d758197a72d4d436e1713e4bca42fa8080
dist/2024-11-27/cargo-beta-x86_64-apple-darwin.tar.gz=6773b94f012a3d3589e2bca28f35dd23208fb245f107e4a17b8b3e7f893c038a
dist/2024-11-27/cargo-beta-x86_64-apple-darwin.tar.xz=d3a20dbd60545b0162dc06499317e342bea077cff369e053eb89e85e2b640188
dist/2024-11-27/cargo-beta-x86_64-pc-windows-gnu.tar.gz=39e16c97c0b22533dfa674d6e8f5bf5df256e2b426d02dca5ed33e246f18d05b
dist/2024-11-27/cargo-beta-x86_64-pc-windows-gnu.tar.xz=ffd939f901c64a17c3f24fc69744cd2af1c176a45d8e5fa8209067ada403db7d
dist/2024-11-27/cargo-beta-x86_64-pc-windows-msvc.tar.gz=8addc12e74a983f3166b89d1d53ce87c92f38c7c3a62ec7c66580aa424d20516
dist/2024-11-27/cargo-beta-x86_64-pc-windows-msvc.tar.xz=8e5622917395ff50e53b237e7322f1faf2b64f0446c41ccaa0096e57a3e7de69
dist/2024-11-27/cargo-beta-x86_64-unknown-freebsd.tar.gz=2734d099aa1ada79346213aec8cc7ebe40312df1dfb40a32d09ccd3b6622e025
dist/2024-11-27/cargo-beta-x86_64-unknown-freebsd.tar.xz=642edcaf16dd74c0935d28ce9b37cf1c5ecb9c03bec30f6ff0e7476760ae7ca2
dist/2024-11-27/cargo-beta-x86_64-unknown-illumos.tar.gz=4f28de38005de48db7126dcb698b748063341de41dc71175605301837a3f7336
dist/2024-11-27/cargo-beta-x86_64-unknown-illumos.tar.xz=ce18692f99780ec09d01816277ee4e71785bdfbd7abb4375ba8d87c1b6905ffa
dist/2024-11-27/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=f1d692c3a1c280f34de167ef26af3c13a6d0a3b5ae4fb86b0a9f2178c3287a94
dist/2024-11-27/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=21f477af2b49ec8809bf8bc7b4c4919c7d2ac57782b829f5a0d9ef1967c5d71a
dist/2024-11-27/cargo-beta-x86_64-unknown-linux-musl.tar.gz=4bed61be221c1347b1649f54222b27e2a3577b84816ce1099c9f0f461c6e9e5a
dist/2024-11-27/cargo-beta-x86_64-unknown-linux-musl.tar.xz=33f463209d50ca6b04a8953c87d2177a84d1729d635de9a7c9b1a711ccb5d751
dist/2024-11-27/cargo-beta-x86_64-unknown-netbsd.tar.gz=ce46b5b2d767cc0d790d8fd21052ecfb787dffb4218a238a339fe5f1afd26d6f
dist/2024-11-27/cargo-beta-x86_64-unknown-netbsd.tar.xz=0afd0489cb4231edc5bc1ef24a43c3f1918f681f08c1207d184fefdb46416509
dist/2024-11-27/clippy-beta-aarch64-apple-darwin.tar.gz=6e5f1a85dad2b899567369aceac0102943ab807dad7e218c273b7b4d6393dba7
dist/2024-11-27/clippy-beta-aarch64-apple-darwin.tar.xz=f784ac4a6ab180675396adf8256ac2bf2d1e823bef106d1c6c59911a8360692c
dist/2024-11-27/clippy-beta-aarch64-pc-windows-msvc.tar.gz=22f1e9299a24aebaf9a32471ddc6cdbf856b455d059ca077170aecf5989f8772
dist/2024-11-27/clippy-beta-aarch64-pc-windows-msvc.tar.xz=7f3fd047ed5aa85ea6ca2b0d6103f7530d7d070c93b0f212c9d1a6491f160cbc
dist/2024-11-27/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=f383ecb5cd654268f00be1f577572993c38e7386a1e1d18b864338e87c7b2b42
dist/2024-11-27/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=b2043facf587f98a8f10a92ae129b7f608297709f4ac61d683b7c813cc65e41e
dist/2024-11-27/clippy-beta-aarch64-unknown-linux-musl.tar.gz=6678d45195bd2a7b27ed2d4bad3790e6b63e376da71d112b9333760ea375c40f
dist/2024-11-27/clippy-beta-aarch64-unknown-linux-musl.tar.xz=f6c77e80c9ea4e312fc2715a9f66ea9a2e6344e3f04ab96cc572e4c0e8c915db
dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=be8c0dfde3f09bf476d6600b530aa498b01415015665429bebed8814c7568b73
dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=4315f7623dcf0a278cccb6c8b397a29f83f70ecb9b03588f61e383e5ebaa697d
dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=c31ff694c68f28e0f462133e783a5d732cf9c539737fc8dbbfd01a53e9a456c3
dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=2553ae5596b8273d8a61ec66d2e20d0c9733c9f791ca5c56217c60884f0ccf9a
dist/2024-11-27/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=1842cf2c26ab474df47e74720c56997e270b37609f840ac50ab0b05064cb38fb
dist/2024-11-27/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=e882b1cc2814e3c97c33991fa0a80de62556ce8f4f88307f6338a90be32b045b
dist/2024-11-27/clippy-beta-i686-pc-windows-gnu.tar.gz=7c6e08b841f21e3b8953e51a6a9fd9df0c719e8defd7b1ab0660d8920fe72185
dist/2024-11-27/clippy-beta-i686-pc-windows-gnu.tar.xz=137aec194877446fec994a233427db419bb4f2910151c456c3ec80d9329628e7
dist/2024-11-27/clippy-beta-i686-pc-windows-msvc.tar.gz=52ba38277ac3f80d124fdc8dd1709b8c1115cecfc53fae4731da8615a63f78cb
dist/2024-11-27/clippy-beta-i686-pc-windows-msvc.tar.xz=548d3eb599334ab98791b8ba27decff8b0de98dfcffadc994ad38aad6255cff5
dist/2024-11-27/clippy-beta-i686-unknown-linux-gnu.tar.gz=448071394d5e647e8da8f64cfbf85e8305d85ff9357dd24737523c95eb339ab3
dist/2024-11-27/clippy-beta-i686-unknown-linux-gnu.tar.xz=e25daa6264cf5e0a7cbcfd827e27a8e276c29c88c86cc15977c1a1650d0303f9
dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=9f080cc937e7209ad83fdb8bf4b2cd7b080af83dbd9061229f154785e273bfec
dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=7d537f66195c581ff51ce8f53c4687a762daf225c7f0ce76393953ab04b804e1
dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=2bd38261a9ef33ad687b3edcd33f283c32a493a80b56dbefc822c1116edb1f2f
dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=7e63dff1d8abe517aefeb4b1976932d23a9a7ed5e4db2398d8ba2659301f639c
dist/2024-11-27/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=1495b2a49cfce014da72beb691e6c477d189ef34080acb1761b588d11b75d27a
dist/2024-11-27/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=75da94f1ade2ef48674b77ded595c69ee715f62f9d9dd96e72039e27807b7314
dist/2024-11-27/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=2d6b826fb4d3d9b61ecd3aaffdd1334f766dd5a5fb0d8279e0de26d381c5cbdc
dist/2024-11-27/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=f5ceaca2651d6002f232f71809458ad912bb5f00030790e907ff7b0e12c9e0c1
dist/2024-11-27/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=1a62f307197c6fd08fbeabef89f58842cfd59c6d62f530850592fe55852d61f7
dist/2024-11-27/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=4c65fd6a5d74527391fbc7c242a2313e5290209f5a15763d74eeaa6cba0a0ed0
dist/2024-11-27/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=8ab9f735a98de1949e65d51c3050b29ceba3ddc28167ba0180353253dc726392
dist/2024-11-27/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=0367eb23a9349ebd829d59fe0a2638557c8e57205e48f66a701b238461385bf2
dist/2024-11-27/clippy-beta-s390x-unknown-linux-gnu.tar.gz=ffe9100ec6b81b081d5f9d840bdf01c658790d7e6bc0674e5ebb6b28f79c2f7f
dist/2024-11-27/clippy-beta-s390x-unknown-linux-gnu.tar.xz=b19b1b28bb7ddf8cf977f102acb623f65d5117c44ab8b62cf197f2d3d33c15de
dist/2024-11-27/clippy-beta-x86_64-apple-darwin.tar.gz=d986de5c01bde3469693dea7cb4248155ee9791550aa179d601066d27e45afb1
dist/2024-11-27/clippy-beta-x86_64-apple-darwin.tar.xz=8000e46ccc2598fdb770c69c68aeb18d94db9b2847d0509f7a9c51ef28714ba7
dist/2024-11-27/clippy-beta-x86_64-pc-windows-gnu.tar.gz=c701581f28d885889ae5c845a7b34beebb04a4631c2740e9333b69390cfaf499
dist/2024-11-27/clippy-beta-x86_64-pc-windows-gnu.tar.xz=fc285792e6f626e133edede613a9a9a90ee12191765e2f0beac642a3b3c9ca12
dist/2024-11-27/clippy-beta-x86_64-pc-windows-msvc.tar.gz=91afdb71bdd54e5c04fc7c933dac06d5e769627e886e20eb712524e852a01966
dist/2024-11-27/clippy-beta-x86_64-pc-windows-msvc.tar.xz=2ef7018c7319e3a299c5eddf36748d9d293ae43eaf54662d9855fd211eb4658c
dist/2024-11-27/clippy-beta-x86_64-unknown-freebsd.tar.gz=02234d4c47478112e01d51bc7dd48cd467293e1eeba55bd383d08bc7376c471d
dist/2024-11-27/clippy-beta-x86_64-unknown-freebsd.tar.xz=a3e6a0c7f31278866d97816c5ed434b1987e0bc5a89b24283e836402803c1388
dist/2024-11-27/clippy-beta-x86_64-unknown-illumos.tar.gz=b238ab536ac963929884da4dc9bab43679e6fa9aba4251c73ab7e5cbe5d8eeb9
dist/2024-11-27/clippy-beta-x86_64-unknown-illumos.tar.xz=797ea7a7643a8302e45347f21c4dc6bdee617c2a9d9ccef74ed525c7d2e9dd91
dist/2024-11-27/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=d630a6b25a08af85d3d426e73d3231e018e0ab7176a5934572786147fbbf3823
dist/2024-11-27/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=d0259a0112f452ee49b8c9bebd760ab8945e5bc3a0d57b1cdc2b8e24accd35c7
dist/2024-11-27/clippy-beta-x86_64-unknown-linux-musl.tar.gz=5febe478e5040f0f74a14c23e78eed21b080900d875d6b447354945c07677a6f
dist/2024-11-27/clippy-beta-x86_64-unknown-linux-musl.tar.xz=552c35bbe76a83439e66cf9ccd522d97e43a8fe4f6aadbabd1f02c4b2c1814dd
dist/2024-11-27/clippy-beta-x86_64-unknown-netbsd.tar.gz=ff6db2d7b84e1b01c81e494de15ccd07f60fef6dc60fa46d47e128ebaba4022c
dist/2024-11-27/clippy-beta-x86_64-unknown-netbsd.tar.xz=b27f89b175bee3769dab1c2d0c54f17ff3efba2038f3b600f4077435c7fd21d3
dist/2024-11-27/rustfmt-nightly-aarch64-apple-darwin.tar.gz=5b5015483d0a98e9dc715c3cc8c23598c02fc14ea6e5878790ae68f2f1c8ef46
dist/2024-11-27/rustfmt-nightly-aarch64-apple-darwin.tar.xz=ce5706f0397a1b2fd9e17dbf34ccfbc3e8c87cc81c92b54b81fd33accc2b7c06
dist/2024-11-27/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=3f5077c8743b5c4f233da7d0aa0aa13fc488ef0fa9da24b002bfa413d52dc845
dist/2024-11-27/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=087eb30f24ba7d8ee42e28bce2a6cd75e5fb7ef5dca8a738ef23fac82ad59566
dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=28a716ef9c5318543559ab4c0c2d062b0deeab1ecec80d5d83ad5effb574f209
dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=99cf9ec4b7bea4281f64a613784350a8ac34e9b0387fed7eb26d6f8c21c83735
dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=a23c3de89603bd4d1035a267e6ee456c6de12efa4029d76ded3edf7c69285a15
dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=462dfd28b631b5a6d8277920cfa8037d8583cbf6a2e5c9159c492161013e820a
dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=44af5b13726cab40865580df8bc05182a2359eae64e41a92f84790ef55ca6bdb
dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=0a7c0b207e745d01194d96f0fbe2402273d630d4f1aa05001a5f5371c9585a2c
dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=66e2fc688b8f746d15c0dce042f2a94e06c5b652d5e0b6534d9e992eec186784
dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=15a2e087f7b482fa8c027fe6e6fbaf846d784c8e917fed375048a297d5e13c45
dist/2024-11-27/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=71788ea2544f8349ec548a2f150dca2afe80a49deb91c00c46484a5e3039742d
dist/2024-11-27/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d9fa7b780b9d8b93549abf0a3f0e6f31cc8e1e991ddf682adf3b616fe2a1f0c8
dist/2024-11-27/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=30924bad51ffa62f762d4c000f86ea3457b590f6397d65755c711ff7f77ac129
dist/2024-11-27/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=14fff13942e6a65927776c49013249b2e75aa3a630667ecf49c9ba721e47bcb4
dist/2024-11-27/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=02d82688bdf3bd3c261a4a6d4acfb07835e29ce262cdc3165ba849a6a8490bcc
dist/2024-11-27/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=2a19b55bb609542ec49dea87e3b67532e5d18df8be43d0ad775bb34f4f9f96a0
dist/2024-11-27/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=d07ca0ddfb0dd89a9cc935b2b9662379bcc9503cb28a28d68c5165f787a7d762
dist/2024-11-27/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=de8106801b1e49dfd8a4fffbfc2a4f949218eaa011ca2085953ebf2a5ea9b141
dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=309024f86e80a4568721b5bb61aa936e027accc251fa97acd5043b513b325576
dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=55bf234aa2ec7fd4c6a7179f779d790e7f62969967519bacfeae84db5cd29abe
dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=4bf9571182e7ef40e76c7e5905fab8ac35269ace390f5007480b4951f80cfa3b
dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=2a2cde80fcbf68768ba7a99cb059a0cdc9313ad0c934383dde9598d6147ef756
dist/2024-11-27/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=b747fb16b15cff3f9368ce1a1f5cad0d2930bde5a609547a3afa2679d7ab8a1a
dist/2024-11-27/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=b861f8361ee806d83f38afbbbf312e0e5e4d8851e7048444c409de1a83484446
dist/2024-11-27/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=ebe56700ad0948e4dcd9930730f7df8e01a5eefca1d1157fe12160d782e2a5c0
dist/2024-11-27/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=5081c9b8677314464d8a3a50220809def18badb2269d2cd8b7106f3547b0e25a
dist/2024-11-27/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=2ed9094b538b6450371311b742f2d309a1f40b2b4c84deb9867059336b76d1b0
dist/2024-11-27/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=d9d52d9b9f4da7a457d05dd4645885d092f170bd2f751a49b4ab3b88395a5248
dist/2024-11-27/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=a2e51d381645c6bf18502ca72fe9f10ffd309281dae87ec16c5627f232f77e50
dist/2024-11-27/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=c526efc054c33a08626b882eebadf887a9aaf8fd60a4adf6a146659a7c1ec8d7
dist/2024-11-27/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=04e5b7c97b57ff7d967abb4f98374f0833108c04f6edf482b8b3fefbde340956
dist/2024-11-27/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=1829afdebce1c3fe249f81958de68c765db18b431927e54fc42be37ea4ab8226
dist/2024-11-27/rustfmt-nightly-x86_64-apple-darwin.tar.gz=d6cf138d02e50168f8ee4a89abb2a4a39e19458d060d7b46cf227bba1fd4c0d8
dist/2024-11-27/rustfmt-nightly-x86_64-apple-darwin.tar.xz=e8185262c82c064c4bb9ae6f1d3072819410de9cfca943b77605012a546c254e
dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=64d78f9f05a978b95b9e22a63bbb31dcf98152df5638f498a361a96d9d2b0c04
dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=c07041ab84364ace58a357c18b5c4dca037852e1159edabb02f4579ac6853b4a
dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=7ef0122ccd3a0c77c917bd75e93358eb95d7e87d78a165c724e3f0cd90f8209c
dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=d0d0566a0a50e1e9e7f4251cf207bde82d96c27016f0a0acc364754561ab4881
dist/2024-11-27/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=e4854528c31316894339bfa97b07ec607e8956877c285778e555885ce9c8a068
dist/2024-11-27/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=d79c9b352ed7b2f132f06dcdf360527502b2153beb09cca968a5ced521edcd39
dist/2024-11-27/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=df76cbeae0a61506a29db22e8743d16fcd97ef2da216ea15bf4d6cd709814017
dist/2024-11-27/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=103cbb30bbe92da6666d84fab53dd7fe8105c2ebe62eeab5f6609488e62a481b
dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=5f3c61663a319d6162240192f387e10ab87e2a972062198082158a243b667d7f
dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=221b45c3928b1c45fedbeea987ad80750d3f55fbc564cf3ccf910a68447ad725
dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=18eb24fd665ce1cc4ce66b37b19c22397bff9369963b127137780870c179228d
dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=bcd09587a21ea10953a14521e9e0ba7b5100e8e15b6a10cc4e7bd359200d5279
dist/2024-11-27/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=db712c5e1d21231770e12dc95f6bcbe2f1d04b9cde61bc7adf8b529b41773adf
dist/2024-11-27/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=43303e426752dcd15964416822cdce0e5f3012366a9b77f3d68e6011c7bacd0f
dist/2024-11-27/rustc-nightly-aarch64-apple-darwin.tar.gz=95d543a835b11cb5ccbf0578df1ce4e1846e4915622d23a36cc6e18e44e17f29
dist/2024-11-27/rustc-nightly-aarch64-apple-darwin.tar.xz=db9e0c51c35c81c2ec8be0838f3231f7374917215792ffee159e3d7ffed855d8
dist/2024-11-27/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=bf9b83d6418bf97caf2df70a8e8298cd8fecb7b950cdaaa2cecbec243ed57c74
dist/2024-11-27/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=bb520da5b522fffb5a20eed4390990c2ab9d22eb4f77196535a84ae7a434c9f5
dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=4072d9ca2d617d09d394139c0b8608bb8b2b8b2b4fa450f13c41975a16a791c7
dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=3d75a8a534e86bb55b63f5b5b2df66ae47862cb7f3ecd1591a829435031d7279
dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=3cf05e90bc1f95e92cca4769f74055245234037009cf464df3062238c88bc2b6
dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=245ebb7886cfba64d667630ca8bd672520cfece0ccec3b916e3de0f26aeada52
dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=dadff4abd2f169f9aa1910d4ea247b7d1f767fca74238ad31485b73399ab6dda
dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=ff97e1201e9a305673e8a9b740b7696cc4cb5e86bfaa3e137cd8e3e28cffd7a6
dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=0c411e0824140323f51600d387d52bd01f601f5539d6457815e950224a6d29a4
dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=dc5731a70c393f69555433d522cde8a52893bfb88beec519c1bbb03b2a0e060c
dist/2024-11-27/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=01ef2f07f1222fbf3e0cfc5b957c287fb886fd0bd08cbf18f90dc37fb0b63541
dist/2024-11-27/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d45042b3ea0c0ce6befea7bfdd731e890dbd1f47d1992fe8718a1363f9f18779
dist/2024-11-27/rustc-nightly-i686-pc-windows-gnu.tar.gz=5437da4c0b73d203789829512d856a66c1697d95afb1ffeaa6347ad0f7c04672
dist/2024-11-27/rustc-nightly-i686-pc-windows-gnu.tar.xz=a7cb4cb627d75de1ade9211d8ea489ada9ac76ed38909751861ef0cb729dcbcd
dist/2024-11-27/rustc-nightly-i686-pc-windows-msvc.tar.gz=fd6ee6fc171459092e5e8a012d9cfb7491313e021d1c38965605836b5b101b0a
dist/2024-11-27/rustc-nightly-i686-pc-windows-msvc.tar.xz=314c7cd558a3654db85d75b3ed71da7cfec3614e4a5f2c449dbc6663b64c7e3d
dist/2024-11-27/rustc-nightly-i686-unknown-linux-gnu.tar.gz=7a1118011b11befb7df2df57e4450c7611bb3503b3b3cfece9c9c7d4a304391d
dist/2024-11-27/rustc-nightly-i686-unknown-linux-gnu.tar.xz=2cb95208e77546bcce56d8d5646c3fb5e49ed711894926cb50903ba10431a36e
dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=4a76c4493e5ba19aaf14947a6c2e28ebfc7f2da530f1441a9fdfa328e15ea4cf
dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=9b361904c691e17fbf44d80c7f7789511db1d8f251d65ba9cf6fda7f06fd495f
dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=e89dc76ab061ae23081aee1619fcbf4a94e3acefef6b9b149231f3e1c22f9ec1
dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=11266d557e6d1d9155e6f04f65e4815cfbfd9f8e1aaa47221030e3ff11b22f78
dist/2024-11-27/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=30f2eae1b8694607a04c836f750b4b7c204e1e14e52ec37885b9a821c2c9646e
dist/2024-11-27/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=495316e70b26140c66b074e9d7f714ab949f422c2635cab784a5e133538e4bb9
dist/2024-11-27/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=ca560c4fe28051573d54f512652ac9740a2d1111aeb8e36b004a6ff9c325925c
dist/2024-11-27/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=1191f15bb6da98b01b43f0e9d7f51c5c45d38e3c5be2b4ae5f7c0c8fd25e9a90
dist/2024-11-27/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=5f85829aaab919fa4b2fa5ac843b87358e8da4797adbb6eeaed5be02666ce964
dist/2024-11-27/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=7c671d366fec561f0b568bfb4b6a08a6071303077a60f76da1307453e51ebc36
dist/2024-11-27/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=300307ab6cf88afc4312edaa510769e901598492deec4834176c6fc9f3eef6cb
dist/2024-11-27/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=6fcf91c8679f4963f7d510cc8afbc24a1070b25ea6d20d5d31ad78ea659da194
dist/2024-11-27/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=ab905f6f3119648c83a2f37ebe1a55b7899a5ac6d10070e4dbbfb89762a369af
dist/2024-11-27/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=13688b6857c8b10f7fb497f07c969d406cb6b76869957b5138f4b20fcc5d7c5a
dist/2024-11-27/rustc-nightly-x86_64-apple-darwin.tar.gz=e6bb782014e34fafdc5dcf3aeb407eb636d822d346c5a8c6227cc45bc645561a
dist/2024-11-27/rustc-nightly-x86_64-apple-darwin.tar.xz=6016ae620deddc42d1d6b6134b0164dab45a204089754b73db41ec837aa88a84
dist/2024-11-27/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=ed3a381858612e25cacfd89c08496e9d06378d593ccedea4217ad4fa1ab326d4
dist/2024-11-27/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=4819bb9c25aa743de7ab7e93b10b30336a87f1f75e5122d578df2c83fbc59850
dist/2024-11-27/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=404aac87c77871c80f83cd7c59390af9af704ee468f40eba68d224d23e2c84e9
dist/2024-11-27/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=0e1e0d2454ad24fe1da2cce2dce425bc1167bbca68832da2476c7996c00ba612
dist/2024-11-27/rustc-nightly-x86_64-unknown-freebsd.tar.gz=946d5bcc3ac0b83fd0b53b60290a6361b179f16ba2aa6a2467789ad520278792
dist/2024-11-27/rustc-nightly-x86_64-unknown-freebsd.tar.xz=f3bd1a053399ec89dccaa7456da41d54a8e91deb5c628e4c502fdcf34c5fe780
dist/2024-11-27/rustc-nightly-x86_64-unknown-illumos.tar.gz=c353588a38705b7ae050d4b9868b6c4d3527295edbfb25c115b22cda4912be1f
dist/2024-11-27/rustc-nightly-x86_64-unknown-illumos.tar.xz=a71d8b2b42f6cd522da237f99492ed59cd34ea8c86fc1e73c8854c8234e1c980
dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=5116b949572fd6c7b11a079d9453b15a4c48562bce22b26d82b7050da772789b
dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=3635df40363273d44c6f8182f5f6a3a099ed55897bb764cab2565363cd31c1f4
dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=5233af0b907fb7b176d2b5fee07c486e92dcbbbab1d54a60d814a827befaa984
dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=c908cad6d28657f1fdcbe9d84ecb86f247c75134803dd5273ca24c6c68a58f37
dist/2024-11-27/rustc-nightly-x86_64-unknown-netbsd.tar.gz=c799165c319218a2fb4cdc0ac8db87fc9e2992a8e402d984ea27938a5ad1c5af
dist/2024-11-27/rustc-nightly-x86_64-unknown-netbsd.tar.xz=ec12763fa5d4cc150f663361cd245c30835e05e3b1928898b1b7300de559468c
dist/2025-01-08/rustc-beta-aarch64-apple-darwin.tar.gz=8869795c998e9d39a7093bf53917291b066e35964059298cb1cc2ee2f1088b2e
dist/2025-01-08/rustc-beta-aarch64-apple-darwin.tar.xz=1397b1ee764dd51d8a082a063b6b13a2d5609b1e1a6e1dbbc0368f24e7830e85
dist/2025-01-08/rustc-beta-aarch64-pc-windows-msvc.tar.gz=68719c1f92c6aa4251c27910c9f788472166444a9295cfa0af6450bc6b5e6555
dist/2025-01-08/rustc-beta-aarch64-pc-windows-msvc.tar.xz=56fca9013ab1646263f043898346dfe206f4b264c37d1cf39fc61807e47c072d
dist/2025-01-08/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=7acc2b71f759f098c542f0ff4f3705e73112dfb3b8e85bb9158d1ce10d858efe
dist/2025-01-08/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=0d21e19b284d2053879ee55353f0d601e3b359530cfb9c747f6cc4ad9b67ade9
dist/2025-01-08/rustc-beta-aarch64-unknown-linux-musl.tar.gz=25a5b2cf16fb51056c208e5899c9843bc3a902ae2f4148ac53f0b9043727e321
dist/2025-01-08/rustc-beta-aarch64-unknown-linux-musl.tar.xz=31b1dead28d88897fcb2ccdaf72021faba9febe50d797e70ff5c29ae82179618
dist/2025-01-08/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=fa8d3c93890425c9a0d130a652d3a4ecd018cb3098efe243a3ce8422539cb9ce
dist/2025-01-08/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=15344286d365042d9bd8cced1268eed508aaa6152d5e3e289fbd5ebc87788e75
dist/2025-01-08/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=c5ed0dd8c2a3b609d9fdd88b027a1d628517107af8b5488a74bce9a3a4dbebcb
dist/2025-01-08/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=ff5eb5bc42dcfedaae86bf31af37c6c2bdb6210e98cbdd780c4e1a63ba37eaeb
dist/2025-01-08/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=6108711c53f07920a9afd0e749ff4228396220ec2eeacab2310e5b32af7a5e91
dist/2025-01-08/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=7bd41663ab83aa4bef55f3c44e4e4cd3c4291c967573cf8b2ba3d60eda9d06f7
dist/2025-01-08/rustc-beta-i686-pc-windows-gnu.tar.gz=12ba512d2dece4f9be9ac08f3270bfa6663aa28a3443f1cbd7f852ab052f12ab
dist/2025-01-08/rustc-beta-i686-pc-windows-gnu.tar.xz=834cd8f4962401dc522a5a0ac866561a62c646614a6ce4b99e91619098538861
dist/2025-01-08/rustc-beta-i686-pc-windows-msvc.tar.gz=9915fde0d52fcc41eb5f5eb19c06be447187aaf3e5b4f438f7c20d92b364527e
dist/2025-01-08/rustc-beta-i686-pc-windows-msvc.tar.xz=e4e79679d6f90b5de5c64a534ff150416e48aed276d7426a1d4b1fc2e517cefe
dist/2025-01-08/rustc-beta-i686-unknown-linux-gnu.tar.gz=e394e8f0361f0f8a8a9653cab3ade57de10622651675e27c137cef2b06114a6d
dist/2025-01-08/rustc-beta-i686-unknown-linux-gnu.tar.xz=756965d724f5389a3cb63374b4287ea48e18d38827ac3af61a127fc6561ab865
dist/2025-01-08/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=4e3483a31356c4c7c0a7041d318b36e02bcd25ac25c396e4dd139ff4ecad5af5
dist/2025-01-08/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=9fcc0531f285832f5333762317ff64dd2506bc263e447f1931d361b15430d0f8
dist/2025-01-08/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=780ab392bd8d879efc593ec9f87c1ff927e750fea4fdaae23d327fc363f8078f
dist/2025-01-08/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=bfad2585877df4fc99fe708187336631140a8170d21159a6deb7cd8f8ed20248
dist/2025-01-08/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=30659e0526394f50ada52ce228cbe342e7ad9f6db2f0e1dfe6c8c63eb7ec3dd4
dist/2025-01-08/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=e59cbdad42098b5f402f612c957113e7f7b8f4b4f37292079187f44d1753360e
dist/2025-01-08/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=adc19d38f3927cd2c09e2b4bc5e31b1b2473d45027b839abab1837ef22b6cb31
dist/2025-01-08/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=35b15e40ea3b382d67e98dabbb93916abecb7d18977652760e081c1a112300d5
dist/2025-01-08/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=31477a7164f8b3658bdf192bcb1383bb77f93e684887fc7b06e55bb469e7e25a
dist/2025-01-08/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=67f4e6f541e16eafa55e803e2c41fef1c892e7408f61228bdaabfb3a4cb41ade
dist/2025-01-08/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=2f4b8b12fc8bd7bd5783cc77e9b798de3ecd4a17f5a09d6fd4f3a528e1a243a5
dist/2025-01-08/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=474f1a2b2f3a2379da02ba24c59a160a7ab0a2bdb4290b0b277d8aea8e441a53
dist/2025-01-08/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=6be8f141e0a3f00abade77cde91405ac107d729f24b946c89831baa674c210d9
dist/2025-01-08/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=897be1e29a2b67a9dc2d69195ec1f41439903dd3ad8a7b57eb339344ca6ec5da
dist/2025-01-08/rustc-beta-s390x-unknown-linux-gnu.tar.gz=b58ebbaeb5474f577329f4d48991222621d4f30f6411a00973951917586e2cf6
dist/2025-01-08/rustc-beta-s390x-unknown-linux-gnu.tar.xz=215384ed943e173fcb4e10baa69d6929c99e8eeb4790365f1067bf20d5417b32
dist/2025-01-08/rustc-beta-x86_64-apple-darwin.tar.gz=40a3d42489eb77cc7912af5580632f8f6f27373b0f691d24b7d249ca9bc84a41
dist/2025-01-08/rustc-beta-x86_64-apple-darwin.tar.xz=6f8c83b96ba2d9bdb623af0f09b6227532d8c0c0f6ac19fb4b0c5f5145d2ee9c
dist/2025-01-08/rustc-beta-x86_64-pc-windows-gnu.tar.gz=1f76fb03cca2d0fe466c995467f209c28a68d8ad69e7b2fce521f4ace94106f8
dist/2025-01-08/rustc-beta-x86_64-pc-windows-gnu.tar.xz=5bed9303cb18b7c5d78875b11463b945c9c9583c5b377efb69462bda0f92b190
dist/2025-01-08/rustc-beta-x86_64-pc-windows-msvc.tar.gz=a64fedbd98a9d2e8ca6d21018abf627367e2c81a028d38fb850253a6c94ef45b
dist/2025-01-08/rustc-beta-x86_64-pc-windows-msvc.tar.xz=471c040fe9f119e3ddf74fb8887d03cecc415109577a85c14917c00ab3348d0c
dist/2025-01-08/rustc-beta-x86_64-unknown-freebsd.tar.gz=468f89e4f6b7e72cfeeb19eeb723e723673487f3d1cf333d860623bf454e4ff9
dist/2025-01-08/rustc-beta-x86_64-unknown-freebsd.tar.xz=c9e699c5fdbf0af0434354caf8745796db42a931669e733b3a7432baabf81974
dist/2025-01-08/rustc-beta-x86_64-unknown-illumos.tar.gz=e0dbd7d05f74a1d444efb849700f98bbe6b00f870036e5cf6f065fc2d0b982b7
dist/2025-01-08/rustc-beta-x86_64-unknown-illumos.tar.xz=1936046fd441ed9bf8331f77ac9ba930640523ded0674831912d28f9f7ae90c1
dist/2025-01-08/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=c6dbeb9017e7f9694ddb05c4658250945e1d6c2b6de656306a3686d499653029
dist/2025-01-08/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=adec507e847d746ef1bdb0464b23ef7fd840d17e7bff787a198fae239b69a77d
dist/2025-01-08/rustc-beta-x86_64-unknown-linux-musl.tar.gz=32714ed814213cc64fb1721c919c43a877286f625289bf5d526e247de0941e05
dist/2025-01-08/rustc-beta-x86_64-unknown-linux-musl.tar.xz=fdebe84ac7370ca3cfa66cff6974c00e506aab6fb3ecb6b70e8e2c3ef92025f3
dist/2025-01-08/rustc-beta-x86_64-unknown-netbsd.tar.gz=6443e8f6c2cd4d5f4a0b7f38e1c741061f42c454d006afc06ab87968425a8f44
dist/2025-01-08/rustc-beta-x86_64-unknown-netbsd.tar.xz=c12851a0437c7ba6edf08d9ec89f2ccd22f05a5de661664142bf4f15d2a658a2
dist/2025-01-08/rust-std-beta-aarch64-apple-darwin.tar.gz=e88734bd578a36ca396032144b25717e18ff51c519ff9490b193117516b299be
dist/2025-01-08/rust-std-beta-aarch64-apple-darwin.tar.xz=60f5672d8759ccf632e072cce922dd9d079a8e2325098b278afc4fa829943a2f
dist/2025-01-08/rust-std-beta-aarch64-apple-ios.tar.gz=bfd63a92d85035bdd4b4d445427c68483a34b41f647b09390de2ac9342ad6b54
dist/2025-01-08/rust-std-beta-aarch64-apple-ios.tar.xz=9e9b941612bb29e317e4dd10ced4cdaec502526fa964b3aa29cd4fc2af070451
dist/2025-01-08/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=2dc9ed6bbb9fd1d576bc78321a78f7997928a6a94625d90a613286e1a5bec758
dist/2025-01-08/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=ecb686e8f201952f1e3475a88de73eb264a11c74961967bd1ba7eee87a248bfb
dist/2025-01-08/rust-std-beta-aarch64-apple-ios-sim.tar.gz=b481a6f88b8696b86160541083e608ef811f1ec0d9b1455325fd48efdaca6f01
dist/2025-01-08/rust-std-beta-aarch64-apple-ios-sim.tar.xz=584d7a1cd7be4af3c747269de3466a312e541dfa17b1614ad355b32b74ea1ad8
dist/2025-01-08/rust-std-beta-aarch64-linux-android.tar.gz=c91990c99c5687216320bb82e9e2f8f7b2242fafd534cbb0ae88a287880c2dab
dist/2025-01-08/rust-std-beta-aarch64-linux-android.tar.xz=c3a4a168393d0a8222b8ebdb6b5495a8896788156af4c454e35d349d1ab63109
dist/2025-01-08/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=5a7c5b256b41a9ee01387da8ffaa49a3914737c827113beba081f34671568e84
dist/2025-01-08/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=d0343608f884db1579847539eb6346ad3cb7b85072bf698598db61dee720793d
dist/2025-01-08/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=6cf78705518f865a7c6d3c9c4566b0dca6197338d5d88dc0037c721261e5dc3c
dist/2025-01-08/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=c8c81ffc20538dea3050a7b7ba89cab620423e66a10931befba354e2c4572ea1
dist/2025-01-08/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=966f512ab3d23e303f7162d03bc619aff54b0af25bab86bedc0c96e130c89545
dist/2025-01-08/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=fba9f964d8fb51753435c300319870a3b4530e385887a16d31975597cfde3ca7
dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=997d422eedd7b6adfd175ef6a13b5ae7a83530d633f834e7ca0d94851ed29ed6
dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=5ff49e69e9b549494542c9306c1fc82f6221b8d9e9fe25ec5021fe46f7c8cb28
dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=2181081deaa27438f420df53847b8108f96ad215369cae81947f0688b1906cc2
dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=f8b28aeeae9973c1dddbea684eec9a6a136fda3f850b4ffaa10e53914e1037e0
dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=a49eeccef00269063a10b1e623a54b0b500afbc2dd8e1db4ff8ae4a6844de943
dist/2025-01-08/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=32fa668c9d3d703adbf6910ef358dbcab344d37fd3ce4e81ba43a820d8a8792e
dist/2025-01-08/rust-std-beta-aarch64-unknown-none.tar.gz=95c6a6a65ede296e8b4183a1271dd6cb1c61299f3966a8e2a6180867752a2988
dist/2025-01-08/rust-std-beta-aarch64-unknown-none.tar.xz=a44fa8ccbc73899c013526ca32866f63e1165e7f3b14455b91b37e3865c9e1c0
dist/2025-01-08/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=31448ceb30ff86b5d8b4e7fa8fe5871665115d561e6377f73e164d8f11652b6e
dist/2025-01-08/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=bd71a90489b9ed6134d0fd05fd22c58b20c271422628a552d04bbc2bfd1bd29e
dist/2025-01-08/rust-std-beta-aarch64-unknown-uefi.tar.gz=0cc22881954c661d2ae01058ca04db10912289812e9cfdbca3c066227e38566a
dist/2025-01-08/rust-std-beta-aarch64-unknown-uefi.tar.xz=439e6cda62ca17f124ed788ed8c3882c2999362067214ed911aa362b8d4d22b8
dist/2025-01-08/rust-std-beta-arm-linux-androideabi.tar.gz=c62e75f3754b04b3594189de953ca6a8703679b29e8da3935ee5a7370ee0e03c
dist/2025-01-08/rust-std-beta-arm-linux-androideabi.tar.xz=dd23a5df6353aa01271f0d1206f927dc0f532203fbf66258b2771155e543b86f
dist/2025-01-08/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=2cf5fee1c6cc0e2ee099c8687126b11861e12b098dd4ac99397a2ad026596350
dist/2025-01-08/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=d3a946d098ca9991b4dbdc4ba3b53e37535e62815f76f81bdf7e4562f3534943
dist/2025-01-08/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=2eed53b995d0ac0c2856c39815ea08f40c074165c3814336af591adcd9f8b571
dist/2025-01-08/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=3848bae0dfc660d40486ee56589fd0d6ee558f051a14b5efd9d55cd03d10f709
dist/2025-01-08/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=b40192daf614574f7ef2f7785f6b66d99c0876f3f3cdc30990f8545d41ba0fba
dist/2025-01-08/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=9e23ebe3062f38791cd23cfa58d9fbd796553bceff7a5a041d3cb78278915c99
dist/2025-01-08/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=1b47d8f88a4496a8c7604aa2b6b0a2a810266825c385df5e29d313d5635eab6f
dist/2025-01-08/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=613dba102c8e8aed939ce3f1c43382d3d5d74a1baf911b7f68867ce0abaddbf6
dist/2025-01-08/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=6afea3865efe25d2675c6e988c09c1fdfc052b27d996f893d9e5fe8a5aee10c3
dist/2025-01-08/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=285ce1584fca2d0701baffb3228801c88212c20df1a6ee76bcc6e8a392de8739
dist/2025-01-08/rust-std-beta-armebv7r-none-eabi.tar.gz=8bee2bdb49b1b8781b016b0b1032663e20d135d23b7d9de898e7dee0732a8ce2
dist/2025-01-08/rust-std-beta-armebv7r-none-eabi.tar.xz=d0e2b1d1a095bb02866048e6286fcf762cffb69f437031ba3e7f330ec1ddaf07
dist/2025-01-08/rust-std-beta-armebv7r-none-eabihf.tar.gz=c9a13d7fe85291c560786835a0531a407459f07cbfe4b652d9497a581e4bff09
dist/2025-01-08/rust-std-beta-armebv7r-none-eabihf.tar.xz=be5e9534e88732ca700315d8a4517de3701201d74a0344e962faa9e9c64cf035
dist/2025-01-08/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=9a48d8e2247f3f70c85e8a5fd39c9f1302d56aa94fbac6b431bff5a4c74f64ad
dist/2025-01-08/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=5e210bb961e6f73869671298ae1172a3a6f61b1b4ab08baad81e0e32e0a25245
dist/2025-01-08/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=fc842d5db2778c0f3fff7602e8056795a0c33880a29ba0d29941fec2d2174d8f
dist/2025-01-08/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=cf473390797976ca153701dcd3ee41a4c2ba314cb180a06ee51e242f5f93047f
dist/2025-01-08/rust-std-beta-armv7-linux-androideabi.tar.gz=2cf80485cb303b44d48f6555ca33ea25fde6daa7f5fc9e6a2acdc23697c810a2
dist/2025-01-08/rust-std-beta-armv7-linux-androideabi.tar.xz=625e57d27f5b4bc198598df7b2ae6ac8416951060eda7dd08ef9d319e97b2b9c
dist/2025-01-08/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=170d6999f1f9185d48df161023e527826ad72019c37ee11a4e3ad25fa1667e81
dist/2025-01-08/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=724bf705fdfd23aa4065ec9128d6d34beaa8285b02f36c2a68d83b1f537c5186
dist/2025-01-08/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=21a6727b7bee42a9ed22167600a5c9e8346db3e10133c88a07acca89a3513140
dist/2025-01-08/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=f6234d0030296bb13cd8b075a6b2637b5f8c1c9454ff764a168755686fff4b5c
dist/2025-01-08/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=09479a598b1fe96eead29bc72f007a130b374b53d06be22282ad94ef7b4e4bce
dist/2025-01-08/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=7e67daa06adad6878ea5d3cd9626baf370188fde3e14b2459347665118173c5f
dist/2025-01-08/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=92d63ffb8ef0c274ff6138032e0df849b7d10668035ec3a20304ab31bafad495
dist/2025-01-08/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=1c2e84999fb5282b6ed7bb31bac0f4c979483696453f3c797dce2e52b7bb848f
dist/2025-01-08/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=3a5e0748561fb981acdcfdc2037b12cdfb51d4fd3336172f6be74a78eeaca6b3
dist/2025-01-08/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=9bd198313fe8e4d0d3b4f999841ad6310884f6a0ba9f1582e072108e38fbda0c
dist/2025-01-08/rust-std-beta-armv7a-none-eabi.tar.gz=45cdec4bacb8c1cb67e73c26499fa789fffebc981a33472f6b84d8752554e7c9
dist/2025-01-08/rust-std-beta-armv7a-none-eabi.tar.xz=5222471cb625865c8a2594e88a3adbf529a866164e98f77a315953d5e3494c54
dist/2025-01-08/rust-std-beta-armv7r-none-eabi.tar.gz=32159e59a8c11c032ab900f77ab7b25827409be390c62bfee8e28d9cd733c13d
dist/2025-01-08/rust-std-beta-armv7r-none-eabi.tar.xz=45c7ba589c6f092ada1a0acc0a107efb09b3baf0549846919ac3f853b574026e
dist/2025-01-08/rust-std-beta-armv7r-none-eabihf.tar.gz=4263a0a290f88e9b5c09c6140aaa02fcc7bc455439070f6d4b4d9a38f8424c3f
dist/2025-01-08/rust-std-beta-armv7r-none-eabihf.tar.xz=a3ff2f3691f7f62f9bb57259eb4e6c2976276fabc46e9ac6a7796ce2fd6ece5c
dist/2025-01-08/rust-std-beta-i586-pc-windows-msvc.tar.gz=d073f07548e5a2d92e094c69b6a7b59cf91309ebb42e06393c410c95fa90b681
dist/2025-01-08/rust-std-beta-i586-pc-windows-msvc.tar.xz=e8708e2a341358c14c3259a8c4c05db6eb7baf09050cdab383b44f0b70dea7b7
dist/2025-01-08/rust-std-beta-i586-unknown-linux-gnu.tar.gz=9072d9bf10db42db4e150b73fddf1085495979a18f59cabd43d73c0f1336e112
dist/2025-01-08/rust-std-beta-i586-unknown-linux-gnu.tar.xz=e43a369c7954f4645243990291c88dae3b6694e4d2efe7ed4f81b7b8b7c723c8
dist/2025-01-08/rust-std-beta-i586-unknown-linux-musl.tar.gz=e7de687f826c37e20b64b5e091fc3ea514770d38c45bb39eb6ab5a9730be6d11
dist/2025-01-08/rust-std-beta-i586-unknown-linux-musl.tar.xz=5ab4c606c30f534fa75351160af4c4dda660955658a0d6864d28d927b9ca07cd
dist/2025-01-08/rust-std-beta-i686-linux-android.tar.gz=5936848fc7f45feeb797c6a78889762d0b36fe48dd82eb437049be6e8d17ee04
dist/2025-01-08/rust-std-beta-i686-linux-android.tar.xz=d66a746f476ad27525c9f22136b664c0a98a811450caa083ff8c9def80dd886f
dist/2025-01-08/rust-std-beta-i686-pc-windows-gnu.tar.gz=d6326c139001357e964fcad7e26b195fb707e8158791fdfbcd16910258438910
dist/2025-01-08/rust-std-beta-i686-pc-windows-gnu.tar.xz=f455268ea0f33118607adb1a7ebe484a38904e1c698899f4857492633fad219f
dist/2025-01-08/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=714846d27f13247f37edc266b66eb1792fa1c35d2dd13215800db55ed89cf8c3
dist/2025-01-08/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=cede0b7977ee57ed24d792749dbfb42240f95a235d93b2e1a7ad4aa03d588da3
dist/2025-01-08/rust-std-beta-i686-pc-windows-msvc.tar.gz=70fbea3fa87e1aa93668f2462ddf73b05c55883ae9d2bbdd0a3acc9ab51eb961
dist/2025-01-08/rust-std-beta-i686-pc-windows-msvc.tar.xz=bc13da70c924372a2247d125bdfc850b9551e32ef990ca8dd0c24d282f9c7025
dist/2025-01-08/rust-std-beta-i686-unknown-freebsd.tar.gz=c4583d916fdf07e7e274b59c32fe661b0c1780b925c4d84d01fccb1262cee70a
dist/2025-01-08/rust-std-beta-i686-unknown-freebsd.tar.xz=77612c690f5ecbadb1f2d9128f79676bc3b199478cdb619321eb521e4f8777ca
dist/2025-01-08/rust-std-beta-i686-unknown-linux-gnu.tar.gz=c487e6e164f31a9274a24a1668170db22e64def6412a38a38b6e0c4741523786
dist/2025-01-08/rust-std-beta-i686-unknown-linux-gnu.tar.xz=cfd25efcec9004d223fb7257a34c0530ff755eb3337fe80468949df185e1adec
dist/2025-01-08/rust-std-beta-i686-unknown-linux-musl.tar.gz=5e208e822d9d2db30bfa4ca363d29d923c5560ac7d220dfd32898524022aa2c7
dist/2025-01-08/rust-std-beta-i686-unknown-linux-musl.tar.xz=742f8c4dde07be899de43502af87ea1457a4706078ea7f353914fd31d9b91537
dist/2025-01-08/rust-std-beta-i686-unknown-uefi.tar.gz=3567303608260def6590e9f0c29ce776ce933f0a9cf4c568faa8713935ee9efc
dist/2025-01-08/rust-std-beta-i686-unknown-uefi.tar.xz=dbea586494aeec9d2d29c80eb259cb6d66608c93b26f560f2276b490d6946a25
dist/2025-01-08/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=ecbacd29dc59c59ac513958325ce3a2a2323156562dbf966f529f267fc52ce17
dist/2025-01-08/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=69c2429bc0bdcb3e4ab9b05af37f65c60b936df6598d375843e63b8141371fe3
dist/2025-01-08/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=f4f33e673f883a9ac3b0113281c890839498d70d72e5ba51094c851bd6f0d323
dist/2025-01-08/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=c82917544801fe373b007aae871b4833db428a37d544e09644601d3fde682018
dist/2025-01-08/rust-std-beta-loongarch64-unknown-none.tar.gz=d3fb635af8745de8a5019bb9bbc3b20b109ed85f7ced6e939836bc0a124a0fbd
dist/2025-01-08/rust-std-beta-loongarch64-unknown-none.tar.xz=6e7e2d66e1c99507b1b515178d6a200532e1ae7600dc125d26b8ccf52d011399
dist/2025-01-08/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=0fb8285f64d616d741a32ae07f69dfa96e0d231cb835a839dc42ea76fdf0ea83
dist/2025-01-08/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=c1c92ca9c3153ea5f42aeec0c3ee7f1042e3e01d6a91784e6baaf201c9621608
dist/2025-01-08/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=1749eb869811470620cf5e432b5f5dc128c6b8e9f3b9586fc20336c677b863da
dist/2025-01-08/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=72c7a3c88afab27d0e4b09c313af336e6aff45046fae2becb17235affc1746f6
dist/2025-01-08/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=36bd0cb97b921cdb915337ec1c7a23609c94c2485f932a1c27fd71804def533d
dist/2025-01-08/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=45a6098b27a0de50e3c26d540ab4afeac30178bdd389c0a4d829b015cc5726ec
dist/2025-01-08/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=00352c0a8fba406add478aa1bbf6b6ca99e7c5db302901616bd2cc740a9867b8
dist/2025-01-08/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=69d7ca4226590875ae59a45b45e7726780dcf4091c9c44c3759931e2b05a42af
dist/2025-01-08/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=6243b4efcf2435cf586248ebc9b99379e8b86ce5575d8845821a11c21f8946fd
dist/2025-01-08/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=78898b9d99a25075a8c47e7b78e35b64b891179a8f54d41983370814f33b6eca
dist/2025-01-08/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=ab293f2e7e3288a4c4842ee510307f18c9df6618702695add978bd1d56be21b1
dist/2025-01-08/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=57b7c326e4167d01385f9f89d89e81b5b660a7e63e1c17b14b70e8c8e50774dd
dist/2025-01-08/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=167fca173e6e2974a35be4c8fc5cc9043a3b34d74efba13a86df75d2600576d5
dist/2025-01-08/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=4197393d32094f65fc781bf39ba95fb36988508f9ab6b41300ebe2ebad838640
dist/2025-01-08/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=d3d0569bffb348bc580f3e382557939a4a87452a05dcfe1fbca8c8a9888c457d
dist/2025-01-08/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=c0ad9def2f73a60b674b35b8f53483a0c017ad4e4db3b268b3c10bdbedc13625
dist/2025-01-08/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=7f41fade9abdf4ee47e96ffcf345fc37231d60a645ce814b19738689018b77cd
dist/2025-01-08/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=d6f21bf60530c691a6d40d0ba1ebe0ee041bf8a333f489671b1f1fea61950ffc
dist/2025-01-08/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=0ddc2427ea4e448789b8053f111f7310f6da95d6cff8f644ce1f3ccffeb16f42
dist/2025-01-08/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=77a2f8531ec6a87ef95ed5690c31d5e1e3cf65a633e0ff885cb0b2cc55a2fab4
dist/2025-01-08/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=c72a5c97347dbf43c328170cd1ded9363f1f3659732d9497d73bc2a9e3b32de7
dist/2025-01-08/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=584e99c8fdfd6e186509ad41f67d02ad92cd9d887c2b6159ad8a36334eba7aae
dist/2025-01-08/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=536f1135a697180ed7674b8d9ac15232eac4d7735cbcc836cc099cd6136c39b2
dist/2025-01-08/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=dad89574543674fd72dd2a6be4b2753b4e2211238d6208b201903c0645024fa5
dist/2025-01-08/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=1fb747dc33e3016ec5f0d8161dadef20f0798f7a65967c316f0315826bf7e8d0
dist/2025-01-08/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=05c57bfecf04cfb5279a3132138c9bf0c6773ea5fa01315bdcc83f0ad06165c5
dist/2025-01-08/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=83e04e9c3ca61c2aa39a0c37b92d11a8571792244e6c5ebc795c1c3274a9a926
dist/2025-01-08/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=4c1537651b695764db9ae3c536a605a7a9a1fdf51689350f7fff9638454844d3
dist/2025-01-08/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=1c3164278134db89dc7cc5d2169402f28757e55c99438cb86a90cbf06f07ef7b
dist/2025-01-08/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=ddb7ffbad2e308d80b901986f6e00f38ecc59359a9f7d28223c089b01ae86f91
dist/2025-01-08/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=935d864e0e212ed9f70027fa7f6afe18757e561347c4d8b97221db2936a5afe7
dist/2025-01-08/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=18cc0e5b000474a60938521e23c5ef057e184616ddb1e2b031db0f8b5d87931b
dist/2025-01-08/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=e824c24bb3933941658a3a6c981e469c153aefc5bdb153216d90cbe8dc26adf8
dist/2025-01-08/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=d40178695aff134127268c21a91ae8b4aaedf2d78122a00c844e0c4efe246815
dist/2025-01-08/rust-std-beta-sparcv9-sun-solaris.tar.gz=c37a91e3c6685a11bc96acb1f7db48c30a45ed19c9a7f303ad4b60bb24228975
dist/2025-01-08/rust-std-beta-sparcv9-sun-solaris.tar.xz=cf190f95859df6eb65ca3cc07aee95d4f3f8c0770c480ecd8373168cf0bce323
dist/2025-01-08/rust-std-beta-thumbv6m-none-eabi.tar.gz=b598d8aba2ac570320ae7a1c8b9103f04cd0b81df37500ed838b88874eb7317c
dist/2025-01-08/rust-std-beta-thumbv6m-none-eabi.tar.xz=ebd4c1ca68d4ca5944a3f0837a8a1018e18dcb31ef8436a4d02c347b251ff0be
dist/2025-01-08/rust-std-beta-thumbv7em-none-eabi.tar.gz=3d0385fdb184a66a1af91e3db28ea0829b1a498f2431a896aeccf2c900cb9624
dist/2025-01-08/rust-std-beta-thumbv7em-none-eabi.tar.xz=f778bfbb7033a53c61c3af187ee35e9e7713e9e98a6994f11ed9b589f3459391
dist/2025-01-08/rust-std-beta-thumbv7em-none-eabihf.tar.gz=0a1669fc57856b2e475a9b8edd7575ad7ab07ad0b95a0ba9fb92e7fb26f81a0b
dist/2025-01-08/rust-std-beta-thumbv7em-none-eabihf.tar.xz=bb6b245b183061f65e3a5d9e9c1bafc76c3f968ed7d0cbd0e33ff878f5e30804
dist/2025-01-08/rust-std-beta-thumbv7m-none-eabi.tar.gz=3f459b3a6dbe99fa6bcce86e853096902f23e7e49a1b8c300ef4515796619b28
dist/2025-01-08/rust-std-beta-thumbv7m-none-eabi.tar.xz=b9ce85bf7cfcb13526c2cbf56aba726919b818168c6f99fb855cf00ef8d0c76c
dist/2025-01-08/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=366797feb0b31dccd500310903b494682b654800938a79c46e47313accaf622a
dist/2025-01-08/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=33c50d91b1f23770031a3e1c9b3a78f901b30831bbed8c7f463c29ebb86d5a91
dist/2025-01-08/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=43acc164b41da62e1aeb7f252f6d81f1f3b79281362348817134760185648071
dist/2025-01-08/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=c93bc0681027e879719417049e61ddf7f4092d72d103d14994520bccaf6ede19
dist/2025-01-08/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=0b36bef54f41302c871bfb92f45f248c34bd2450b159c68801eb13373d464e69
dist/2025-01-08/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=7f9300e17e4786747ca434c1f1a0451aa7c7f933f7952b5010a0e4bf4d9e4198
dist/2025-01-08/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=ca421607c9f67d0648dc7550781bf90983dca6f17e81153ebcc4ae2f69fe88a5
dist/2025-01-08/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=0b20c32941914bacc1b0a16b334cd32feed1ff56e6a2551aa0ae6b22c41f4c46
dist/2025-01-08/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=e792938012865b5c1fcec63bc25a9b72e28889515472cfd83d7d57fd8f84d7c5
dist/2025-01-08/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=15338fd8f01e0fb422336ba055a4ccf4be3ff8ccdb123ace84e9dc9f1a64e3cc
dist/2025-01-08/rust-std-beta-wasm32-unknown-emscripten.tar.gz=c57a71f14db1b122dec0ff70a04faf1b8a7a3af948e3ed81b15563b19c376334
dist/2025-01-08/rust-std-beta-wasm32-unknown-emscripten.tar.xz=dbbd2251d206de84de81abd5b29e4ed1b08c00155141e08a7b6fa35559ac4e65
dist/2025-01-08/rust-std-beta-wasm32-unknown-unknown.tar.gz=852381932ef65b7ce75f943164ac747bcce3b1d3f6e2c1cd434934c1030f789a
dist/2025-01-08/rust-std-beta-wasm32-unknown-unknown.tar.xz=cbdf58a9afb016aee98416924578d0a8ece8a6d5a17734606928bedf37719129
dist/2025-01-08/rust-std-beta-wasm32-wasip1.tar.gz=6dd459e217ea3b4f7f85811eca500c774a36dd849addd9874e4e54e972fc7c7c
dist/2025-01-08/rust-std-beta-wasm32-wasip1.tar.xz=beca27838a50a2da0341d1bee58faaab18d67a41cd1724d39b30b4f8daf18359
dist/2025-01-08/rust-std-beta-wasm32-wasip1-threads.tar.gz=8a264acc2656f35e61d4ebf8773dd3b29c0e7748ccaf326898089838128c609d
dist/2025-01-08/rust-std-beta-wasm32-wasip1-threads.tar.xz=eac3340c629af165b67982326cbff6cd63a2721e41972b70826a9911af902e02
dist/2025-01-08/rust-std-beta-wasm32-wasip2.tar.gz=ddef01fac3d8b1116b0f2b5f7b4a65a54070e06ccff8fc0429ed8e668d57d4fe
dist/2025-01-08/rust-std-beta-wasm32-wasip2.tar.xz=6de7754db16d34a556264c6d37ed66480e832aacf2aefe34a7e82636ccd38653
dist/2025-01-08/rust-std-beta-wasm32v1-none.tar.gz=8f8eef02573a4911630ceb59534bb91a084ecc9d8ba1ccfa6e59370f69af028f
dist/2025-01-08/rust-std-beta-wasm32v1-none.tar.xz=86bb30d39659171af2120a86668f1803f3c1ca7b2a0f8662fc98a499734f9e17
dist/2025-01-08/rust-std-beta-x86_64-apple-darwin.tar.gz=b4e018a5dec5b232867770a8d8ce43d670265a51b389c7a1f0f1652a9e2b685e
dist/2025-01-08/rust-std-beta-x86_64-apple-darwin.tar.xz=b81c60d6b6c5f5fb1eba3037c545452bf7f070eae7b6c23ab3011f50de1f01ce
dist/2025-01-08/rust-std-beta-x86_64-apple-ios.tar.gz=61a88f5fd29b413ae351db90a43773ad2cc846ef3a03b5747e98bcab7865b988
dist/2025-01-08/rust-std-beta-x86_64-apple-ios.tar.xz=977ad619301f051e241f898c302bc230ed37dcd6041d925378cba6811a15f41a
dist/2025-01-08/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=184c6fb1f051685f23a04ee2a57d15b8f1f3d5696b9cee0f8d48b230f108f408
dist/2025-01-08/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=90715fa792f08da57964abae2b8366337c3372ecb92624783448ee6fc921792e
dist/2025-01-08/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=13343f16a12d12bf5dea13e240a88e50855a3eaa16d87842e33356611ef6a0dc
dist/2025-01-08/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=f273923ea18276e3440003bfe6f00479df907dffd18fb80b447c41baae396cb7
dist/2025-01-08/rust-std-beta-x86_64-linux-android.tar.gz=3c86701e32a065bd9b0529360379b86180724497b5167f776253abba208db741
dist/2025-01-08/rust-std-beta-x86_64-linux-android.tar.xz=daf93cde1b13402a2e7ef7faa2aa1644cacb2fafb211a28d4e1c7cb96e738372
dist/2025-01-08/rust-std-beta-x86_64-pc-solaris.tar.gz=5cf8d53338a4c504dfb96dcbef5b2862921624c2c93edc7597478f97ef3f1a24
dist/2025-01-08/rust-std-beta-x86_64-pc-solaris.tar.xz=a8a4105596906d4b1ac1588c1b301c1843c4ea695219fa6a979205a6b5fb336f
dist/2025-01-08/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=f9c03150ce779c7a31ccf5fa4e12953af8d182bd7c0415300ea0ddee191a0e47
dist/2025-01-08/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=fb81f14fc43c8c9e86da1f10dbff6474447029781b716c9ad67068f793f07ba5
dist/2025-01-08/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=de329a0e32d0f66d50da01875c85ac807b826d2d2efbf971a7b46f89710dd2f7
dist/2025-01-08/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=ea5ad2523161e086b0b898c8c989fc1b20a26b460f4403eeaa9fde881be58465
dist/2025-01-08/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=b042f515a81b7151a0930e852fcb23632b74579ddd8be53dc37bf09fa94747f4
dist/2025-01-08/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=6f850810bcb1ab381e0245ce7d7881d86852d041d679d622dab4f4317aca54db
dist/2025-01-08/rust-std-beta-x86_64-unknown-freebsd.tar.gz=e415f16fbe3bfd0d9283ee41dc385f3a1a79f33730aba9d04da2acf7ea993617
dist/2025-01-08/rust-std-beta-x86_64-unknown-freebsd.tar.xz=ce6967397e9dcf20c700957d5ef3a8fbe35795f0b7be1e8f2fc61ebebdd9771d
dist/2025-01-08/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=6233e4e853dcbfe5dab0b1258fdadeec39f3d343fd99e597956677a949de1945
dist/2025-01-08/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=228a0ccf377f633b450b6bdaec99f351cc9db41e61d3caeba85f675bc9e07954
dist/2025-01-08/rust-std-beta-x86_64-unknown-illumos.tar.gz=d729b6e0f6d70104c730e7cb4d4472ce02452acceecabf98e411b2ad0d6cfdfc
dist/2025-01-08/rust-std-beta-x86_64-unknown-illumos.tar.xz=51dad4bf611ab3bef919a9961f1a4d02f0203c63db501e32ff0810b2a1d81617
dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=6c859df64c707c7783863a17e2980c2139a98293473363efa6873d6549b52e3f
dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=f4cce8d15f242168ba0ec7942a1140b1dadcaeebc8c0e7e7bd35ef7f91e4b390
dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=f7a559f89b5fa340c2974b8c85aad21e48995af01add8e459b82bae890f0b2e5
dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=73007a7a396864a71003de912ceb847e8684c4c63d45f032da628267aa28cb7f
dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=7746927bd5283c05717e006d252bba797b48bb9f50b3674587025125e1916ff7
dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=4d2cc7aaa081dcc0b9fbf09601881023b6749d8b2986a01f82caae0218d2cdc9
dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=6f2ecafe9003c8fba1f43e1acdd477cf0482e7f97c1687d6255c696bc45cf662
dist/2025-01-08/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=c82ece042d0980b1707d3871aa35b4b816179c3214e84ca7666e2189e4f062cc
dist/2025-01-08/rust-std-beta-x86_64-unknown-netbsd.tar.gz=d41dcec02cd3dc2536786aa461256bf5ce1b65174ab6cc532564dbfb6dbb37bb
dist/2025-01-08/rust-std-beta-x86_64-unknown-netbsd.tar.xz=cfc7dd1eaf1420db8b87d13bd9a857e258c2db4137ce1fab03583b82cff5e3b0
dist/2025-01-08/rust-std-beta-x86_64-unknown-none.tar.gz=234209f51b8e8637cb2742cd482be0a333e4463869abbd5f00e548f03eb79483
dist/2025-01-08/rust-std-beta-x86_64-unknown-none.tar.xz=36a5a189997d1c6eb05397007223611fc9777cee6fc495a885e46c2f52f62040
dist/2025-01-08/rust-std-beta-x86_64-unknown-redox.tar.gz=a8df20db51fd121a970d6dcd24e583ac831c956f37b7e47b1533cba6f4b27dd4
dist/2025-01-08/rust-std-beta-x86_64-unknown-redox.tar.xz=d1368bfa84bae9366cde19cb201fd13fe09d2c0b53f82cabefa85a78acf423e2
dist/2025-01-08/rust-std-beta-x86_64-unknown-uefi.tar.gz=625834a177f20b99f706b9b25c60388db6cc42de7dd54a9ae10b16a86f4ab9bd
dist/2025-01-08/rust-std-beta-x86_64-unknown-uefi.tar.xz=89a95f2c6a11a0788fcb4fb12c7b37dcae62ff682ae8e1d24910f64dcf801be6
dist/2025-01-08/cargo-beta-aarch64-apple-darwin.tar.gz=be3bbcf4c95c1d30634cdd87efaf0ea57b8199649a9e502245ee3915f93f49c5
dist/2025-01-08/cargo-beta-aarch64-apple-darwin.tar.xz=74eb6c112313e7bc0104e211397ef998c2713f3c350a0b8995355ea04f4c1df6
dist/2025-01-08/cargo-beta-aarch64-pc-windows-msvc.tar.gz=089863e43456e8c2613cf63f82172c9b2b220d582d448a88a9301f12aa5471e2
dist/2025-01-08/cargo-beta-aarch64-pc-windows-msvc.tar.xz=fe604aaf5d859192fa13c78643c072d49b31f1b16fdbb088e2917631aa683431
dist/2025-01-08/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=f4c710be8d286696c57bce005e43458a5031fec2b706a8e825c498e7b1c9faa1
dist/2025-01-08/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=18e510f07b0a6b94cc1ec14503c7a2c992ce17c9897c472d9330cf55514ca4c2
dist/2025-01-08/cargo-beta-aarch64-unknown-linux-musl.tar.gz=b2a4e280c9150683d14ab98770a4bb6f27c74144abcb0d075e81e537cbd2e2d0
dist/2025-01-08/cargo-beta-aarch64-unknown-linux-musl.tar.xz=096d0926b219a8dbb6952a66ff742936c7307baa236262b2d6ee5238c2b44153
dist/2025-01-08/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=58eb3f62b876ee4be22ca51720204da9c3734a5a4a5365dedcede0a012a48891
dist/2025-01-08/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=1ca32ac5479c6d27191c7726b0dad38af34e6423ba8e644461ca30c82382ce06
dist/2025-01-08/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=45895027f54b7c4f1222196317ac1cc38a84ccf07696a72fb91b2d42218d4281
dist/2025-01-08/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=f08639a9a86802637b08df47815e2b0e32ce826f76c7187a140f97abf1eaebf5
dist/2025-01-08/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=63dfd33bb41426e81a8be487580656699502396350cd6c50a3bf32cacf2f5eb6
dist/2025-01-08/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=1033972fe7345a4cb84d0ba8a479159bdda53d42f581a7087eb517144026e870
dist/2025-01-08/cargo-beta-i686-pc-windows-gnu.tar.gz=2f00a1e75d995f89ad2b5fd509dcbce97aad2096638cea05d0e9662fe8f21997
dist/2025-01-08/cargo-beta-i686-pc-windows-gnu.tar.xz=535e4ea02ffcb59ab5c492689aa25aaa7dd026a9db7e5a5e1a674464488e86fb
dist/2025-01-08/cargo-beta-i686-pc-windows-msvc.tar.gz=e2c01590495c6c2384afb0287104bb9e9d8ba555c100c18c8bfd7f06bb4daf43
dist/2025-01-08/cargo-beta-i686-pc-windows-msvc.tar.xz=6ace1bb6fb5cc03358433476d31f25076eb8d963d685df9c8dfc389a9caad479
dist/2025-01-08/cargo-beta-i686-unknown-linux-gnu.tar.gz=a50b87367e59dcc3a1c22101d69cbf45a1485e42b2e12b6211d0f35059698d36
dist/2025-01-08/cargo-beta-i686-unknown-linux-gnu.tar.xz=76d25cafff7f67abe142ba7183b9e1a1fcc18bbfe6969ea03783fd1cbdc7cd68
dist/2025-01-08/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=3bd98bbaf3c1f718e4f40aea4dc0ad47e6c33b46b4b169841497b49a582b7caa
dist/2025-01-08/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=62e384bb07173661c6c1e6ddad3d0fab31a25184966020f70b8492c916cf852b
dist/2025-01-08/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=6bd1ed4631ae5020d4529fc404ef4cf6bf4a93616fd15e1cad9527277fbe200f
dist/2025-01-08/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=e27425b6e8f6c5114aedce100068bda25be975d80761d6478c49588c45f3611a
dist/2025-01-08/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=2b14ae8e9f383d2682292ce26bb5dbe9dab69b450564a5e3f7db3fb93864a21c
dist/2025-01-08/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=dcb68fdece4a4a365a95c440de9bd360f8c1079f4f15eee3d61a53d83957c7e3
dist/2025-01-08/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=9e9c94abd8fcdea831451105bc351bd9407f3ab4925226a171cb0d170a4a697b
dist/2025-01-08/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=4cdd8795488a4c6ffcf9bc446576191dcc364e58dee785bf3ac2e756e3a9d5fa
dist/2025-01-08/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=4eb0a9d2a1b85326c393250873a4550c8e6617e56df9a2d313aa220ffcb7a9ca
dist/2025-01-08/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=2cf68732cc6926ae9727f627e64fab12c9fbe8803a640b25697ff6af23dbd8ab
dist/2025-01-08/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=4f276075cf0ce993ac88728992369d996dcbe4e1f68e5e80e620c0a6b305a484
dist/2025-01-08/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=5b52acb5500d93fdccc9bdc03e6e91313deff0a2801c2b8a587681239b2a6ecf
dist/2025-01-08/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=8325fda118d5da0b376c0db751cf2ceeae2dd3021b930e3b55c14e02d0ac438b
dist/2025-01-08/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=2a764695907dcef6b4259831636d0020e72dde5d213f532b3f04b0bae3615d4f
dist/2025-01-08/cargo-beta-s390x-unknown-linux-gnu.tar.gz=12045986bfc2c346a914bd0b18d84d3e1c3103d6082b08659aa2508a483e0817
dist/2025-01-08/cargo-beta-s390x-unknown-linux-gnu.tar.xz=ed09f5e3c37582c4ab42f0b4ef1353ff29182579818be28d8a184b33bec728f2
dist/2025-01-08/cargo-beta-x86_64-apple-darwin.tar.gz=d026df870421796b76749529fd0a7965d83c2d915fa42599613c7521f92e391f
dist/2025-01-08/cargo-beta-x86_64-apple-darwin.tar.xz=b2174c6efe4336f76d30f55cf83dd5604b2a4f706a76be1cc57780a45d5fe1dd
dist/2025-01-08/cargo-beta-x86_64-pc-windows-gnu.tar.gz=7047bc8731c2eb00043f0237a12f5261942a1b6b99d574cbb6db32f2f1930180
dist/2025-01-08/cargo-beta-x86_64-pc-windows-gnu.tar.xz=578f2d6d433dc249fe923edd0519f3db953c0a9beb8a2f2641e1bdb65863526b
dist/2025-01-08/cargo-beta-x86_64-pc-windows-msvc.tar.gz=0b4dadaece478e1c0cadbb479bd2acffda3254f2ca3c2529e3b81a0357019239
dist/2025-01-08/cargo-beta-x86_64-pc-windows-msvc.tar.xz=19dc7572f4ae2a9b46c9017f78c5ff7108e9e293f21a3a52eba03f29dd204f62
dist/2025-01-08/cargo-beta-x86_64-unknown-freebsd.tar.gz=71672eeeedc18240a33ea8b0ee0ce2ca8fdb020d5701cf4b8d3cc464a0199cdd
dist/2025-01-08/cargo-beta-x86_64-unknown-freebsd.tar.xz=e853f0e42602ff80f64fe245863ba0a4f50d8197ab4cde56c4bed53f4d7d9cbb
dist/2025-01-08/cargo-beta-x86_64-unknown-illumos.tar.gz=42c1b82bfbccc05f381376b59c92d453810ea57d85e206b9ad958d0e9faa480d
dist/2025-01-08/cargo-beta-x86_64-unknown-illumos.tar.xz=b83b7cfb56b087a0dc648eab5f695104a1f220896a2981d2b65f67aa1584838b
dist/2025-01-08/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=0b87cfd9dd3349b23fdcedad9a0fca316ac59e720c4c8f7b67c44020dcaa9665
dist/2025-01-08/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=19883a7bde6ed9a4587469f0c7bacb434b9734eb74c4b9c570fd3c217db6a52b
dist/2025-01-08/cargo-beta-x86_64-unknown-linux-musl.tar.gz=11934bf3879a9c395676b9fb737fc9e6e0b54314e51008875a72a80d8e773a74
dist/2025-01-08/cargo-beta-x86_64-unknown-linux-musl.tar.xz=2ccf643a305060f2fcd24b957a8f9db28dc6fbe44d1b947007a571cea976d973
dist/2025-01-08/cargo-beta-x86_64-unknown-netbsd.tar.gz=f9982255fb124e74a79708e9e566fd3713b904919260ea498279cde580c9b899
dist/2025-01-08/cargo-beta-x86_64-unknown-netbsd.tar.xz=18bd7da3c593a0bdcb14140ce19e5a43d42e041fb897fa4acf12f35e03b2d766
dist/2025-01-08/clippy-beta-aarch64-apple-darwin.tar.gz=511e0a0b6bf59a8e9ff299a32e46586ced5f13a1ad43c9564921c27b905457c3
dist/2025-01-08/clippy-beta-aarch64-apple-darwin.tar.xz=dd75a377e5a28aff5eca49c73b0b52a2141f347fbb3d2c164d87122663c60ed7
dist/2025-01-08/clippy-beta-aarch64-pc-windows-msvc.tar.gz=3097ed66faa8489f2fac32453d2ebeb7bc39d5d58b2fa60d47e5f539a57d3658
dist/2025-01-08/clippy-beta-aarch64-pc-windows-msvc.tar.xz=dd26d47db7f35a41eb16829b35079d2137eb41a254c810e8a9e6d393a899ed96
dist/2025-01-08/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=a3bdd2413e3d040a1063113d6ba868ed4ffad157f97f180ce6410dc07d89fec4
dist/2025-01-08/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=308402abb63ae6e364d4ef014aa9dcf338b86982a25fc0570c4ca0e348b50bbe
dist/2025-01-08/clippy-beta-aarch64-unknown-linux-musl.tar.gz=07a3f0f0f6eca797d9feb6b3339a7c87ac4063bd4c898cb49d3a61c43b7b8ee6
dist/2025-01-08/clippy-beta-aarch64-unknown-linux-musl.tar.xz=9b2fbae0ec014d61a3d20e532b526fb92bde03ab154b0ee02cb5aa4071c319cb
dist/2025-01-08/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=9d6c781e2414d9ba43648fa958b2cee3937fa62d118ffbd7ae11fd71ca797011
dist/2025-01-08/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=73d6d532acdcd6c64f48d12a24ee4abb6f46c6dbfc3d5c3d593887e98313c1a5
dist/2025-01-08/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=0d698e42477ce7c068df67b389e8f63f82649e1e2b38324e3c3b8906ee9f056d
dist/2025-01-08/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=9b94df3a1bcf891595a8263a61e3aa82a66013a5c59e8d8ac7742e033a1ac590
dist/2025-01-08/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=c010c51bd0665e4fc8a3d0bc27af75d2bd112dc8cbb841252b3d44b3789665f8
dist/2025-01-08/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=c7f9ecb195ded5ac7a03d353e51c264e5ccb4a3460733b06fdf967d8e3a5f085
dist/2025-01-08/clippy-beta-i686-pc-windows-gnu.tar.gz=5f4ccf0aaeff0eb0970796ea23aae4590285b42b62b165fe3898649e203f57da
dist/2025-01-08/clippy-beta-i686-pc-windows-gnu.tar.xz=4400d650806cbdb2a8e8e2d6ed0bd5f90fa46b8f2398f09fed98ef565135635f
dist/2025-01-08/clippy-beta-i686-pc-windows-msvc.tar.gz=062eb313a72787fe53435c57b8a5b0c16ad2abd0644d8669038090d3572bc94d
dist/2025-01-08/clippy-beta-i686-pc-windows-msvc.tar.xz=ae493ceb9e334b05345cd94a26b87f317909ee82c02f704c2c3b487f5b28e897
dist/2025-01-08/clippy-beta-i686-unknown-linux-gnu.tar.gz=0d7ba60792aa6e5cd531362ab92977ae3368b2ca2284174019133c2ed9d495a7
dist/2025-01-08/clippy-beta-i686-unknown-linux-gnu.tar.xz=ded4113933755736c3248f1b0e26cc42d436eb4c6cbb21745f87a2428eae6ae9
dist/2025-01-08/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=a4525272c4d46ab120d61855d5e453b92b0fa83623c8c5cdf4384b746ba56925
dist/2025-01-08/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=5acf5b947a7d7f546cc405975ce5eb1f7e1a86ffaa6ea7c18f5baccbe8e26a7c
dist/2025-01-08/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=628a86af3590cf6ec46173bfd18790958618e1236d3bb54f6eb92be7f78cbdc5
dist/2025-01-08/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=970c1e229fe35bbeb251e6e1291618d9da5334c1608685d8d602209bccafb4e8
dist/2025-01-08/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=25ecca37c54464052f44b79ae061c992f9bb29a671881f5fdc7a8f4e1953e543
dist/2025-01-08/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=e353972b9c73228c523077137a000d1c265dd24012fd1f3f44cb16ab172561c2
dist/2025-01-08/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=b6d050a3cde8ff3c94dd072fce770ddf43486c8db37ca2ce2096f427f169cb81
dist/2025-01-08/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=1728393681aa26afdd9b4c6147b1cd95a43e614cb379fd2f0e38fd68b26cd1fe
dist/2025-01-08/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=4136945a33e3658464835c0c31a244b953b1bc2614dd38266f650ee8e330d5fc
dist/2025-01-08/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=e121b45e188df1d540bd3d3d691b0b4043d5d067b52286e3e82c544d1f059a38
dist/2025-01-08/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=6323723980ac6c17e951272bf5473b0f3735d05f00a469317d0371db9f1b562f
dist/2025-01-08/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=9f7120352e4b0e147159df5e04c1d1939dfe0e1081a6a0d8915ab75709147079
dist/2025-01-08/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=32f52736c78922bb47a624365f3bd7a06d28581ef4f1fffcb57575b6de739431
dist/2025-01-08/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=50c2b4e8c57bd0f4aed56d88e1bfbab2fc8f6c6e6d2aa8cf83dbb36067f2ca69
dist/2025-01-08/clippy-beta-s390x-unknown-linux-gnu.tar.gz=5c2082cb9fa73e0af8b3384a3caf76c7dccbe7a78f553a5527b3539bbee83c0b
dist/2025-01-08/clippy-beta-s390x-unknown-linux-gnu.tar.xz=ca8c580219fe697b9dae674edb2a2c6ea6c737ebfc4d2580cb184745625874c0
dist/2025-01-08/clippy-beta-x86_64-apple-darwin.tar.gz=83ac808792dadc4e5779c0b2185514de339cb61359b185d714713ab366909de4
dist/2025-01-08/clippy-beta-x86_64-apple-darwin.tar.xz=c6a92d2b255736788cd53cb99b84e20ff135c4e5a7ed9cb2ccc9e5eb37523239
dist/2025-01-08/clippy-beta-x86_64-pc-windows-gnu.tar.gz=6984f5b15e2f56e12924cb251d99f7b52307b1368c47ddc6ec4d17bbce8959e1
dist/2025-01-08/clippy-beta-x86_64-pc-windows-gnu.tar.xz=fecd2eb58e8e1c9422e4433f120c3456f9cbd0f216863d9e3d37129bda966f79
dist/2025-01-08/clippy-beta-x86_64-pc-windows-msvc.tar.gz=674115dee679648c45203b9014ce2aaf3812b3de079fc12aab4ba34aa4d8e8e1
dist/2025-01-08/clippy-beta-x86_64-pc-windows-msvc.tar.xz=892ca2c9bb499ab0922919d89bba3c176e75570be2f4f2a1ac08608ba490d4cb
dist/2025-01-08/clippy-beta-x86_64-unknown-freebsd.tar.gz=513b3402e525d1e28c648a640d4506f9456c5c2fb45e2b7bc7f2c325a2d2f920
dist/2025-01-08/clippy-beta-x86_64-unknown-freebsd.tar.xz=5e5a6c353aa3c8cfaafa694e70b69ed54a8c8dea5ea46412fd191a28be3bd926
dist/2025-01-08/clippy-beta-x86_64-unknown-illumos.tar.gz=f16841404d8bb2aa1bd530eb6c2850e665c9e90f82eb6968cfcd4063b5ff8d10
dist/2025-01-08/clippy-beta-x86_64-unknown-illumos.tar.xz=3c23e2df43a58499b4cf3652b2b02b1f68141b417829eb06d44c977c745fc7ff
dist/2025-01-08/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=43bda68cf861a73c8e9bb461e4c28d3c5315f04900db68168584db4f85e50492
dist/2025-01-08/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=0d3bac2b017cb529d3fcf81042edae79362842f191a6759441afab41b19cd0eb
dist/2025-01-08/clippy-beta-x86_64-unknown-linux-musl.tar.gz=af7613a78ea98f2f134a69a32bdc09a103f83d6b1ea2ea3c27ddb3eb74430695
dist/2025-01-08/clippy-beta-x86_64-unknown-linux-musl.tar.xz=78baca17912ad3cf49214187471ddcca890e787dc9821daf37103ea9f8632c1a
dist/2025-01-08/clippy-beta-x86_64-unknown-netbsd.tar.gz=f85ce010c7d235358e532b23e85ca8fd287376c311ca9427bd41ca0b3f04510b
dist/2025-01-08/clippy-beta-x86_64-unknown-netbsd.tar.xz=aacc604a5b53267a8eb936a433eba97ad4a002558836c933548152fc6cf50b0f
dist/2025-01-08/rustfmt-nightly-aarch64-apple-darwin.tar.gz=1ad6d3a92bfd2398af3f712b8238014b5517c80c54e2334e6bdf5bfec349bf0e
dist/2025-01-08/rustfmt-nightly-aarch64-apple-darwin.tar.xz=fcee1911fad43cb5689786b9603ca43fe2e6fccc89aec1f63b8afba4df915a71
dist/2025-01-08/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=3d219a1e888acdccaf75afc7c7820f45eb2161a0c78304f76a28af95c5a53dde
dist/2025-01-08/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=0b4ea270256e8efb6df7d60473db256455fe7d5de835f164bdd0a92c3cea7369
dist/2025-01-08/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=a7edc1692f4a5975fa5877e1af63c8e9c0a2d0946086413678973990fda8ee50
dist/2025-01-08/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=bd4b98f560d00da97f2e7899ca32729581f9c5a386f398cf477c1ba6c922029e
dist/2025-01-08/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=49387f42c45fcb21d55e056843ec3ea210c89b10722adfd2ad6ee5d4a929f7c8
dist/2025-01-08/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=778b995192beced6c690d80103c719e4b30c16b5e3caa2e2586693baac7ead18
dist/2025-01-08/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=906191d5b2ca8e7645d6ff8571419aa8b50ca62fe10a1934722f1a493230da83
dist/2025-01-08/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=6944b61661c3b1f72ec86a80b222bdc0a20e88a4e2a2f342bbb7ae2f8a1e1a6b
dist/2025-01-08/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=e7fd3ba048b6d20956f6a76b6e859204bb9847bbc1305482426bb40f5b28ad36
dist/2025-01-08/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=312042e89eb0007fccdc5effa6098a762b94ff3a15840dee0fe681486b0ebda6
dist/2025-01-08/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=584de19a62f85c418d01bc7943f0e3793f4c79776b8aeb5a7993cd1e7141bd7f
dist/2025-01-08/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=43327de3051396e27793390468003d1f13da0f0ed1cb7d5224ededf2787fefe8
dist/2025-01-08/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=bbb72a900c77cebec9cae4b2c6fd0e3bce3451bb2fb65fabfb9f042a55163f78
dist/2025-01-08/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=fbf8acb567141328ca628bd3c81af9477eb177bb398be3feef55d57acde2af5b
dist/2025-01-08/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=4a80751fdd514a71d20d440260a86510c83cadbeac3bf03014ef5377c6530e10
dist/2025-01-08/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=fa3d56f5ec9f88448a2b6c36809b6c21bacb2cec7350571d386320aae2b410e5
dist/2025-01-08/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=0f11501ddf7be92b987404df21fb4ed83ec8893d887943d86031709e7d671900
dist/2025-01-08/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=264accec3e4ff18a3f21508bdc22988c86c0c899be83ed491f7f45f4d8d1f76e
dist/2025-01-08/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=a32c70abfec103c12119a5adceb83eae81b7fc950733e6039e0b3d3a589d16c5
dist/2025-01-08/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=b0ed3c98ee0cabe8e85d031539796f0ff3e6fb3ed90275242d6fe9f55900abed
dist/2025-01-08/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=b4f8456e420eea3025f32303cda5de26c67d061e04fb2229a247411ac7dd8351
dist/2025-01-08/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=e66969acdf2d98ffd854f19e7d9f8beee8ec8fe7ed4493bd308b2f9b44cd9c90
dist/2025-01-08/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=f97621947a0a90815867d7a0a08722f87cab26584a4b61dca7d81e50336b16cd
dist/2025-01-08/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=9af1743797ac19982892046c5d4d1865c0fa1e7cc0a38ef43f2364e215a2b5ad
dist/2025-01-08/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=fdf25dcd2c911c4fc6fbb3a184d078e36cd908a6a7b135c2a48a6f6efabcfd78
dist/2025-01-08/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=6df2621585eb4d0c5be9b3118034b70dc12e3ac999a47e843b9b2c8ca48629c8
dist/2025-01-08/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=bd6c79723c219e2c2b56bea90e3c2808bdf2119d299fb84d11d021895292d464
dist/2025-01-08/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=4e1f249176e480b12ea11bb49377cda875189f382086339ed3ce591e3c7576e1
dist/2025-01-08/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=36877f682d6c43aaa755b5edb5599e9ee8f48969e93532f458f516ac052dd47b
dist/2025-01-08/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=ef36ffefbe132c56c3a993ba4f8b9048f65ac87f3f22e9471064d3fa7c0e9bbd
dist/2025-01-08/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=2d9a0f3c007b59fb107c859ee4eab0ceadfe4c220ba45bc8c8f4bf5cb2608ba7
dist/2025-01-08/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=f09cde2c36a4b9791f1492b0319ef1444418b2162215d48d18a6eb7493dd275a
dist/2025-01-08/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=585ef59a9fcb414ddec4fb69a6c33548a38b62c87be3c707443954c7be9eb764
dist/2025-01-08/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=4da9c4095b0e30d61c9617a5cbfd69ebc77d54f248dfa3c2f9c096383184a762
dist/2025-01-08/rustfmt-nightly-x86_64-apple-darwin.tar.gz=28ed0f8745b5b68527ca735a794b11a1411574cb0756b74b7e5ad1f0652f1670
dist/2025-01-08/rustfmt-nightly-x86_64-apple-darwin.tar.xz=6b3c264c1e1002c381bc952ae5f24f56f7bd623067ef0f0179677798539d0aa9
dist/2025-01-08/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=46b9ee6fe5c5bc6ec504b62fd9356cf467ea001cea073056fd8b53265b424940
dist/2025-01-08/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=d888eaa7a4b42b4761cba736c75c29d047e31d6d3918c3d64e8347236918f035
dist/2025-01-08/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=3b04474137945edf639d267a67712166c07df4c018276dfabbd7ad714c952750
dist/2025-01-08/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=f5268dc4d20eb86ae882c5faffdc1b6dfee52ab4487569a02f92e2e001a936ba
dist/2025-01-08/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=6fe48737c200f3ab1ebea3b5089403ad76a8dad4754cbdfa274c89dbf9b0ea45
dist/2025-01-08/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=04f1a8d21dc54470df735f6b1f09e9d6e26c106d4ae4405962aaed11da80bea6
dist/2025-01-08/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=0dfa280e767a16665aad2bb6051b88a84850ccc408a24d99b89bf8d659149833
dist/2025-01-08/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=601215d564ed36cdd9be9abfc3ba42bbc15fc75d306e0921b36083a293067980
dist/2025-01-08/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=ce5f4421a454ac2e5f8e53d0ab6050be45f73a3931b9e60240b13f7bf06800ee
dist/2025-01-08/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=7cda6e670d0718d13b89225f58df1c6a2473e6d2626144354c854d671c778ba2
dist/2025-01-08/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=26e3275bab7d39c465bab76074dd54f534980c89f5460838da9745c171859604
dist/2025-01-08/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=b33178fff841b91968c2f6fc108389a1740d865214729406de40b49e6969d22f
dist/2025-01-08/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=cc8439ce6628f864503c7ca322ec0607000536c002895dc872ad1bca8e865119
dist/2025-01-08/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=2d3c2f666bf57384e11f12dcb00346f73953ca8a2a60947ae5c0b14b856b9170
dist/2025-01-08/rustc-nightly-aarch64-apple-darwin.tar.gz=febc42bc953bf6b23253670756fb294545a1db22b02fbe2273e1030a78f0dc8a
dist/2025-01-08/rustc-nightly-aarch64-apple-darwin.tar.xz=f978d9d9e0bcc75efd4250406b796fb3f6cae31ec41ca2a40f88f7e70201171c
dist/2025-01-08/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=6dfd42938c385aba18ba477e4430dd89e9b780d9217f410f68094d7bbbc722a3
dist/2025-01-08/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=d79b6f6158a99ea82314a99a68c52c63deb16d777d74426780df06c5110576a5
dist/2025-01-08/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=5dfaa19982b344ba8d3f59418a847a764eb8b6b4a9809b8a63aeafd4725cb406
dist/2025-01-08/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=dbe770d4594c9f8cd27aec8d342fd5f6bb44570723228726cbf19424dc0d7708
dist/2025-01-08/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=41357e54d974f3dfe0e71cac0eedc69625ddf7e2a1cf563c2e9689afa53cef11
dist/2025-01-08/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=208ffbee7b68121ddc0cb92dc1ab73dc3b489869ab190abd99174026724a3493
dist/2025-01-08/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=7970e126f177ea336cc243448d034c8ad1aa6489db36ea0bde54e2df472552df
dist/2025-01-08/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=8333efc4f3bf9d6fb01a947a6f631f03fd506a494060e426ee7621831dfc3a95
dist/2025-01-08/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=f8b9030db15e6004647772700a7b137fe9e7ff1c24fa0742c45a25d072e1f1e4
dist/2025-01-08/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=f554b976502cdc78735def853947d9b48ab1ff1aca208cb348efdedae0df407d
dist/2025-01-08/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=402109bd4811e723999c8747978452e2a96e2ddf1109393302f9c1be7e36348e
dist/2025-01-08/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=b2dd7f94bbc34b91fd2dc2c1bab7179a51265bc51ac58b66c8aedbe849103749
dist/2025-01-08/rustc-nightly-i686-pc-windows-gnu.tar.gz=9e3f1aa453de7bfd9a15f1925d96b46ce6375b49c6656db14bd2ed99f4138e1c
dist/2025-01-08/rustc-nightly-i686-pc-windows-gnu.tar.xz=468a157752c69bb2096ffe91413086d04eef8c64b9cdc44b51d7e9a94d2f4b5e
dist/2025-01-08/rustc-nightly-i686-pc-windows-msvc.tar.gz=1a9977db5843941c49c808830364e32c7e57190d3bf4dcf74e2a109473f808c0
dist/2025-01-08/rustc-nightly-i686-pc-windows-msvc.tar.xz=7cc68c40929538b7711f5bccfa964841094eed9859f490846de0db0b2ba74343
dist/2025-01-08/rustc-nightly-i686-unknown-linux-gnu.tar.gz=08c86c8984b966d3943de2252318aad2a27899fb58c5eb1079b8b8164b56d21f
dist/2025-01-08/rustc-nightly-i686-unknown-linux-gnu.tar.xz=d3b53723f085887709951dae7b0389b8cd4159a22fc7189bf7d7bc15ecb4bc57
dist/2025-01-08/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=515db325eb12b211d08367436fd07f5ceff4743930b9e685b0b13b94b99bfa34
dist/2025-01-08/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=b4986e7aca0325059689f8d7ead67616b2965922e77da33d9d03a7235520b585
dist/2025-01-08/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=541571e5deb51d360eeaf2c88a28cc25c98dead983a3b8f2a6e3f371df3ce0cb
dist/2025-01-08/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=44fa8d77bf945b1a5ea9ed2a7e8228c8c0d5770098bbd8687173dff58b7005a1
dist/2025-01-08/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=1ecae3935e253cc9b7aa44c8e7835fdf039d44ae19080e2316421b47453e3527
dist/2025-01-08/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=b512b895e9b78069e57fce8c1982ea6fb8e463fbfe626474a6399008d5c149cf
dist/2025-01-08/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=91c4ddebe0b50e8778297793d77a583b23b6c333d785564b97ea38a137c3b7df
dist/2025-01-08/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=562f81acf112aefc6878132d7cf352da64b0eb1803d8c371e6713e270bea15bc
dist/2025-01-08/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=147bcd50f63f068a5814200ffeb8adc775c65187fb9c178dae5468af3fc04611
dist/2025-01-08/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=9b6e863729599a96547119c1c2a04f23167cb142447644b88ccaa86d073e1471
dist/2025-01-08/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=85c085bf2771eb79dd3aca31ff9896de969de229c0549bd8c89a539393ef5cab
dist/2025-01-08/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=107bba3499f4446aec6d79919453341a0d10fa5e6001da4cc9d3f1a618871989
dist/2025-01-08/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=ca6663608404909610479a33562049d313882ab8252fd302657598b0251746ad
dist/2025-01-08/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=f66d3d9a1d897346945b254aed29e29b82be1255908dd0accc7deebd698a0b78
dist/2025-01-08/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=480fdbaad5a5e9d6412682c61de324ac37093f60377e5f772c59dab58e63e6a2
dist/2025-01-08/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=c438d14d90ed5acfa2108788b7179aebd7fcbac10703b2c5207ed7eaf988ddeb
dist/2025-01-08/rustc-nightly-x86_64-apple-darwin.tar.gz=b91f15c087c859b8ea6a5d556835c296ff480f6927efa9e535b9dcd726c8c4de
dist/2025-01-08/rustc-nightly-x86_64-apple-darwin.tar.xz=64b1129ba56b964ad433a499b2b5dd590371a4a7fa0f859c551bced786d876f4
dist/2025-01-08/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=c90d259076abbb62f26348a2bfaf5bc1dca1e6ba7d4c1dec8f02d9dfaa21cc53
dist/2025-01-08/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=127c2335d668cb93169681ec3775e0c9a91e0c5e1dd6043bd9236e18b7dedbf1
dist/2025-01-08/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=a0dd89c80a4c2c724a8910c33c6d5159beef9b462f912326c659defb87ebe41e
dist/2025-01-08/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=b2c1972028521d6cd643a7a1f4db2eca1da5eb8ea03187bab5a7bef63377eec4
dist/2025-01-08/rustc-nightly-x86_64-unknown-freebsd.tar.gz=3eb87ac0585b6a4a3cd0525e3f7fc04eafcb28b64ddb866beedbf24401810bf6
dist/2025-01-08/rustc-nightly-x86_64-unknown-freebsd.tar.xz=fa93c78e53bc3e408c1b6d7917e643fb7f1f6203ec4a44036e8b73d37e650b82
dist/2025-01-08/rustc-nightly-x86_64-unknown-illumos.tar.gz=3017ba6134aaf6cae0b7980ef211420ae1c09d230fc082e9f68a5a1a7335aad2
dist/2025-01-08/rustc-nightly-x86_64-unknown-illumos.tar.xz=5a5881f7883eeb638c00ccc7a4cf453ddb987983228b066ec955b92d4e4855a7
dist/2025-01-08/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=9c7796ef52678a29ea7e0406c1f2273ee11d907b379b3616237df9a05505140e
dist/2025-01-08/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=0c978e79f9794221ebd7c0fc0d4313e323d1aef1a5358ffc9cb806fcd997e4ef
dist/2025-01-08/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=21ff96c7b7c0a5a18051c12f01b67e90fef620c887f7d91e78944b5a1a0e8838
dist/2025-01-08/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=2b7ffa8d546ed9b89472fd25ac56b4f6e968e99bfae9045a4019fab319716cf4
dist/2025-01-08/rustc-nightly-x86_64-unknown-netbsd.tar.gz=ea30e5cef50b7b207844bc30ceaee4bcd30cde86f636080b243eb3e7e5367042
dist/2025-01-08/rustc-nightly-x86_64-unknown-netbsd.tar.xz=c07dc61336037f475cb74945c0925fabd1fb33412eb4e6eba4004f207db67f3e

View file

@ -114,6 +114,7 @@ static TARGETS: &[&str] = &[
"loongarch64-unknown-none",
"loongarch64-unknown-none-softfloat",
"m68k-unknown-linux-gnu",
"m68k-unknown-none-elf",
"csky-unknown-linux-gnuabiv2",
"csky-unknown-linux-gnuabiv2hf",
"mips-unknown-linux-gnu",
@ -128,6 +129,8 @@ static TARGETS: &[&str] = &[
"mipsisa64r6el-unknown-linux-gnuabi64",
"mipsel-unknown-linux-gnu",
"mipsel-unknown-linux-musl",
"mips-mti-none-elf",
"mipsel-mti-none-elf",
"nvptx64-nvidia-cuda",
"powerpc-unknown-linux-gnu",
"powerpc64-unknown-linux-gnu",

@ -1 +1 @@
Subproject commit fd784878cfa843e3e29a6654ecf564c62fae6735
Subproject commit 088d496082726091024f1689c124a0c3dccbd775

View file

@ -17,6 +17,9 @@ jobs:
# Setup
- name: Checkout
uses: actions/checkout@v4
with:
# Unsetting this would make so that any malicious package could get our Github Token
persist-credentials: false
# Run
- name: Build

View file

@ -23,6 +23,8 @@ jobs:
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
# Unsetting this would make so that any malicious package could get our Github Token
persist-credentials: false
# Run
- name: Check Changelog
@ -63,6 +65,8 @@ jobs:
# Setup
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install i686 dependencies
if: matrix.host == 'i686-unknown-linux-gnu'
@ -74,7 +78,8 @@ jobs:
- name: Install toolchain
run: |
rustup set default-host ${{ matrix.host }}
rustup show active-toolchain
# Use a way compatible with Rustup pre-1.28.0 and Rustup 1.28.0
rustup show active-toolchain || rustup toolchain install
# Run
- name: Build
@ -121,9 +126,13 @@ jobs:
# Setup
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install toolchain
run: rustup show active-toolchain
run: |
# Use a way compatible with Rustup pre-1.28.0 and Rustup 1.28.0
rustup show active-toolchain || rustup toolchain install
- name: Test metadata collection
run: cargo collect-metadata
@ -136,9 +145,13 @@ jobs:
# Setup
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install toolchain
run: rustup show active-toolchain
run: |
# Use a way compatible with Rustup pre-1.28.0 and Rustup 1.28.0
rustup show active-toolchain || rustup toolchain install
# Run
- name: Build Integration Test
@ -188,9 +201,13 @@ jobs:
# Setup
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install toolchain
run: rustup show active-toolchain
run: |
# Use a way compatible with Rustup pre-1.28.0 and Rustup 1.28.0
rustup show active-toolchain || rustup toolchain install
# Download
- name: Download target dir
@ -205,7 +222,7 @@ jobs:
# Run
- name: Test ${{ matrix.integration }}
run: |
TOOLCHAIN=$(rustup show active-toolchain | cut -f1 -d' ')
TOOLCHAIN=$(rustup show active-toolchain | head -n 1 | cut -f1 -d' ')
rustup run $TOOLCHAIN $CARGO_TARGET_DIR/debug/integration --show-output
env:
INTEGRATION: ${{ matrix.integration }}

View file

@ -25,9 +25,14 @@ jobs:
# Setup
- name: Checkout
uses: actions/checkout@v4
with:
# Unsetting this would make so that any malicious package could get our Github Token
persist-credentials: false
- name: Install toolchain
run: rustup show active-toolchain
run: |
# Use a way compatible with Rustup pre-1.28.0 and Rustup 1.28.0
rustup show active-toolchain || rustup toolchain install
# Run
- name: Build

View file

@ -22,19 +22,27 @@ jobs:
# Setup
- name: Checkout
uses: actions/checkout@v4
with:
# Unsetting this would make so that any malicious package could get our Github Token
persist-credentials: false
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ env.TARGET_BRANCH }}
path: 'out'
# Unsetting this would make so that any malicious package could get our Github Token
persist-credentials: false
# Run
- name: Set tag name
if: startswith(github.ref, 'refs/tags/')
run: |
TAG=$(basename ${{ github.ref }})
TAG=$(basename "${TAGNAME}")
echo "TAG_NAME=$TAG" >> $GITHUB_ENV
env:
# Make sure that the reference gets expanded before injecting it
TAGNAME: ${{ github.ref }}
- name: Set beta to true
if: github.ref == 'refs/heads/beta'
run: echo "BETA=true" >> $GITHUB_ENV

View file

@ -21,6 +21,8 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 2
# Unsetting this would make so that any malicious package could get our Github Token
persist-credentials: false
# HEAD is the generated merge commit `refs/pull/N/merge` between the PR and `master`, `HEAD^`
# being the commit from `master` that is the base of the merge
@ -73,6 +75,9 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# Unsetting this would make so that any malicious package could get our Github Token
persist-credentials: false
- name: Cache lintcheck bin
id: cache-lintcheck-bin
@ -103,6 +108,9 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# Unsetting this would make so that any malicious package could get our Github Token
persist-credentials: false
- name: Restore lintcheck bin
uses: actions/cache/restore@v4

View file

@ -12,6 +12,9 @@ jobs:
# Setup
- name: Checkout
uses: actions/checkout@v4
with:
# Unsetting this would make so that any malicious package could get our Github Token
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4

View file

@ -6,11 +6,52 @@ document.
## Unreleased / Beta / In Rust Nightly
[aa0d5513...master](https://github.com/rust-lang/rust-clippy/compare/aa0d5513...master)
[786fbd6d...master](https://github.com/rust-lang/rust-clippy/compare/786fbd6d...master)
## Rust 1.84
Current stable, released 2025-01-09
[View all 84 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-10-03T21%3A23%3A58Z..2024-11-14T17%3A41%3A37Z+base%3Amaster)
### New Lints
* Added [`unnecessary_map_or`] to `style`
[#11796](https://github.com/rust-lang/rust-clippy/pull/11796)
* Added [`arbitrary_source_item_ordering`] to `restriction`
[#13376](https://github.com/rust-lang/rust-clippy/pull/13376)
* Added [`map_with_unused_argument_over_ranges`] to `restriction`
[#13034](https://github.com/rust-lang/rust-clippy/pull/13034)
* Added [`map_all_any_identity`] to `complexity`
[#13499](https://github.com/rust-lang/rust-clippy/pull/13499)
* Added [`needless_as_bytes`] to `complexity`
[#13437](https://github.com/rust-lang/rust-clippy/pull/13437)
* Added [`unnecessary_literal_bound`] to `pedantic`
[#13395](https://github.com/rust-lang/rust-clippy/pull/13395)
* Added [`manual_ignore_case_cmp`] to `perf`
[#13334](https://github.com/rust-lang/rust-clippy/pull/13334)
* Added [`regex_creation_in_loops`] to `perf`
[#13412](https://github.com/rust-lang/rust-clippy/pull/13412)
### Moves and Deprecations
* Moved [`manual_is_power_of_two`] to `pedantic` (From `complexity`, now allow-by-default)
[#13553](https://github.com/rust-lang/rust-clippy/pull/13553)
* Move [`module_name_repetitions`] to `restriction` (from `pedantic`)
[#13541](https://github.com/rust-lang/rust-clippy/pull/13541)
### Enhancements
* [`doc_markdown`]: Added the following identifiers to [`doc-valid-idents`]:
CoAP, MHz, GHz, and THz
[#13633](https://github.com/rust-lang/rust-clippy/pull/13633)
[#13460](https://github.com/rust-lang/rust-clippy/pull/13460)
* [`large_const_arrays`]: Changed the default of [`array-size-threshold`] to `16kb` (from `512kb`)
[#13485](https://github.com/rust-lang/rust-clippy/pull/13485)
## Rust 1.83
Current stable, released 2024-11-28
Released 2024-11-28
[View all 64 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-08-25T09%3A59%3A01Z..2024-10-03T13%3A42%3A56Z+base%3Amaster)
@ -5493,6 +5534,7 @@ Released 2018-09-13
[`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
[`doc_nested_refdefs`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_nested_refdefs
[`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
[`double_ended_iterator_last`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_ended_iterator_last
[`double_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_must_use
[`double_neg`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_neg
[`double_parens`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_parens
@ -6252,6 +6294,7 @@ Released 2018-09-13
[`future-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#future-size-threshold
[`ignore-interior-mutability`]: https://doc.rust-lang.org/clippy/lint_configuration.html#ignore-interior-mutability
[`large-error-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-threshold
[`lint-inconsistent-struct-field-initializers`]: https://doc.rust-lang.org/clippy/lint_configuration.html#lint-inconsistent-struct-field-initializers
[`literal-representation-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#literal-representation-threshold
[`matches-for-let-else`]: https://doc.rust-lang.org/clippy/lint_configuration.html#matches-for-let-else
[`max-fn-params-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-fn-params-bools

View file

@ -1,7 +1,7 @@
[package]
name = "clippy"
# begin autogenerated version
version = "0.1.85"
version = "0.1.86"
# 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

@ -83,7 +83,12 @@ As section headers, we use:
```
### New Lints
* Added [`LINT`] to `GROUP`
### Moves and Deprecations
* Moved [`LINT`] to `GROUP` (From `GROUP`, now LEVEL-by-default)
* Renamed `LINT` to [`LINT`]
### Enhancements
### False Positive Fixes
### Suggestion Fixes/Improvements

View file

@ -21,7 +21,7 @@ use clippy_utils::is_trait_method;
impl<'tcx> LateLintPass<'tcx> for OurFancyMethodLint {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
// Check our expr is calling a method with pattern matching
if let hir::ExprKind::MethodCall(path, _, [self_arg, ..]) = &expr.kind
if let hir::ExprKind::MethodCall(path, _, [self_arg, ..], _) = &expr.kind
// Check if the name of this method is `our_fancy_method`
&& path.ident.name.as_str() == "our_fancy_method"
// We can check the type of the self argument whenever necessary.

View file

@ -582,6 +582,33 @@ The maximum size of the `Err`-variant in a `Result` returned from a function
* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err)
## `lint-inconsistent-struct-field-initializers`
Whether to suggest reordering constructor fields when initializers are present.
Warnings produced by this configuration aren't necessarily fixed by just reordering the fields. Even if the
suggested code would compile, it can change semantics if the initializer expressions have side effects. The
following example [from rust-clippy#11846] shows how the suggestion can run into borrow check errors:
```rust
struct MyStruct {
vector: Vec<u32>,
length: usize
}
fn main() {
let vector = vec![1,2,3];
MyStruct { length: vector.len(), vector};
}
```
[from rust-clippy#11846]: https://github.com/rust-lang/rust-clippy/issues/11846#issuecomment-1820747924
**Default Value:** `false`
---
**Affected lints:**
* [`inconsistent_struct_constructor`](https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor)
## `literal-representation-threshold`
The lower bound for linting decimal literals

View file

@ -1,5 +1,7 @@
avoid-breaking-exported-api = false
lint-inconsistent-struct-field-initializers = 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"

View file

@ -1,7 +1,7 @@
[package]
name = "clippy_config"
# begin autogenerated version
version = "0.1.85"
version = "0.1.86"
# end autogenerated version
edition = "2021"
publish = false

View file

@ -532,6 +532,26 @@ define_Conf! {
/// The maximum size of the `Err`-variant in a `Result` returned from a function
#[lints(result_large_err)]
large_error_threshold: u64 = 128,
/// Whether to suggest reordering constructor fields when initializers are present.
///
/// Warnings produced by this configuration aren't necessarily fixed by just reordering the fields. Even if the
/// suggested code would compile, it can change semantics if the initializer expressions have side effects. The
/// following example [from rust-clippy#11846] shows how the suggestion can run into borrow check errors:
///
/// ```rust
/// struct MyStruct {
/// vector: Vec<u32>,
/// length: usize
/// }
/// fn main() {
/// let vector = vec![1,2,3];
/// MyStruct { length: vector.len(), vector};
/// }
/// ```
///
/// [from rust-clippy#11846]: https://github.com/rust-lang/rust-clippy/issues/11846#issuecomment-1820747924
#[lints(inconsistent_struct_constructor)]
lint_inconsistent_struct_field_initializers: bool = false,
/// The lower bound for linting decimal literals
#[lints(decimal_literal_representation)]
literal_representation_threshold: u64 = 16384,

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