Auto merge of #88362 - pietroalbini:bump-stage0, r=Mark-Simulacrum

Pin bootstrap checksums and add a tool to update it automatically

⚠️ ⚠️ This is just a proactive hardening we're performing on the build system, and it's not prompted by any known compromise. If you're aware of security issues being exploited please [check out our responsible disclosure page](https://www.rust-lang.org/policies/security). ⚠️ ⚠️

---

This PR aims to improve Rust's supply chain security by pinning the checksums of the bootstrap compiler downloaded by `x.py`, preventing a compromised `static.rust-lang.org` from affecting building the compiler. The checksums are stored in `src/stage0.json`, which replaces `src/stage0.txt`. This PR also adds a tool to automatically update the bootstrap compiler.

The changes in this PR were originally discussed in [Zulip](https://zulip-archive.rust-lang.org/stream/241545-t-release/topic/pinning.20stage0.20hashes.html).

## Potential attack

Before this PR, an attacker who wanted to compromise the bootstrap compiler would "just" need to:

1. Gain write access to `static.rust-lang.org`, either by compromising DNS or the underlying storage.
2. Upload compromised binaries and corresponding `.sha256` files to `static.rust-lang.org`.

There is no signature verification in `x.py` as we don't want the build system to depend on GPG. Also, since the checksums were not pinned inside the repository, they were downloaded from `static.rust-lang.org` too: this only protected from accidental changes in `static.rust-lang.org` that didn't change the `*.sha256` files. The attack would allow the attacker to compromise past and future invocations of `x.py`.

## Mitigations introduced in this PR

This PR adds pinned checksums for all the bootstrap components in `src/stage0.json` instead of downloading the checksums from `static.rust-lang.org`. This changes the attack scenario to:

1. Gain write access to `static.rust-lang.org`, either by compromising DNS or the underlying storage.
2. Upload compromised binaries to `static.rust-lang.org`.
3. Land a (reviewed) change in the `rust-lang/rust` repository changing the pinned hashes.

Even with a successful attack, existing clones of the Rust repository won't be affected, and once the attack is detected reverting the pinned hashes changes should be enough to be protected from the attack. This also enables further mitigations to be implemented in following PRs, such as verifying signatures when pinning new checksums (removing the trust on first use aspect of this PR) and adding a check in CI making sure a PR updating the checksum has not been tampered with (see the future improvements section).

## Additional changes

There are additional changes implemented in this PR to enable the mitigation:

* The `src/stage0.txt` file has been replaced with `src/stage0.json`. The reasoning for the change is that there is existing tooling to read and manipulate JSON files compared to the custom format we were using before, and the slight challenge of manually editing JSON files (no comments, no trailing commas) are not a problem thanks to the new `bump-stage0`.

* A new tool has been added to the repository, `bump-stage0`. When invoked, the tool automatically calculates which release should be used as the bootstrap compiler given the current version and channel, gathers all the relevant checksums and updates `src/stage0.json`. The tool can be invoked by running:

  ```
  ./x.py run src/tools/bump-stage0
  ```

* Support for downloading releases from `https://dev-static.rust-lang.org` has been removed, as it's not possible to verify checksums there (it's customary to replace existing artifacts there if a rebuild is warranted). This will require a change to the release process to avoid bumping the bootstrap compiler on beta before the stable release.

## Future improvements

* Add signature verification as part of `bump-stage0`, which would require the attacker to also obtain the release signing keys in order to successfully compromise the bootstrap compiler. This would be fine to add now, as the burden of installing the tool to verify signatures would only be placed on whoever updates the bootstrap compiler, instead of everyone compiling Rust.

* Add a check on CI that ensures the checksums in `src/stage0.json` are the expected ones. If a PR changes the stage0 file CI should also run the `bump-stage0` tool and fail if the output in CI doesn't match the committed file. This prevents the PR author from tweaking the output of the tool manually, which would otherwise be close to impossible for a human to detect.

* Automate creating the PRs bumping the bootstrap compiler, by setting up a scheduled job in GitHub Actions that runs the tool and opens a PR.

* Investigate whether a similar mitigation can be done for "download from CI" components like the prebuilt LLVM.

r? `@Mark-Simulacrum`
This commit is contained in:
bors 2021-09-06 16:01:17 +00:00
commit 8ceea01bb4
13 changed files with 677 additions and 149 deletions

View File

@ -220,6 +220,18 @@ dependencies = [
name = "build_helper"
version = "0.1.0"
[[package]]
name = "bump-stage0"
version = "0.1.0"
dependencies = [
"anyhow",
"curl",
"indexmap",
"serde",
"serde_json",
"toml",
]
[[package]]
name = "byte-tools"
version = "0.3.1"
@ -1663,6 +1675,7 @@ checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
dependencies = [
"autocfg",
"hashbrown",
"serde",
]
[[package]]

View File

@ -35,6 +35,7 @@ members = [
"src/tools/expand-yaml-anchors",
"src/tools/jsondocck",
"src/tools/html-checker",
"src/tools/bump-stage0",
]
exclude = [

View File

@ -4,6 +4,7 @@ import contextlib
import datetime
import distutils.version
import hashlib
import json
import os
import re
import shutil
@ -24,19 +25,17 @@ def support_xz():
except tarfile.CompressionError:
return False
def get(url, path, verbose=False, do_verify=True):
suffix = '.sha256'
sha_url = url + suffix
def get(base, url, path, checksums, verbose=False, do_verify=True):
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
temp_path = temp_file.name
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as sha_file:
sha_path = sha_file.name
try:
if do_verify:
download(sha_path, sha_url, False, verbose)
if url not in checksums:
raise RuntimeError("src/stage0.json doesn't contain a checksum for {}".format(url))
sha256 = checksums[url]
if os.path.exists(path):
if verify(path, sha_path, False):
if verify(path, sha256, False):
if verbose:
print("using already-download file", path)
return
@ -45,23 +44,17 @@ def get(url, path, verbose=False, do_verify=True):
print("ignoring already-download file",
path, "due to failed verification")
os.unlink(path)
download(temp_path, url, True, verbose)
if do_verify and not verify(temp_path, sha_path, verbose):
download(temp_path, "{}/{}".format(base, url), True, verbose)
if do_verify and not verify(temp_path, sha256, verbose):
raise RuntimeError("failed verification")
if verbose:
print("moving {} to {}".format(temp_path, path))
shutil.move(temp_path, path)
finally:
delete_if_present(sha_path, verbose)
delete_if_present(temp_path, verbose)
def delete_if_present(path, verbose):
"""Remove the given file if present"""
if os.path.isfile(path):
if os.path.isfile(temp_path):
if verbose:
print("removing", path)
os.unlink(path)
print("removing", temp_path)
os.unlink(temp_path)
def download(path, url, probably_big, verbose):
@ -98,14 +91,12 @@ def _download(path, url, probably_big, verbose, exception):
exception=exception)
def verify(path, sha_path, verbose):
def verify(path, expected, verbose):
"""Check if the sha256 sum of the given path is valid"""
if verbose:
print("verifying", path)
with open(path, "rb") as source:
found = hashlib.sha256(source.read()).hexdigest()
with open(sha_path, "r") as sha256sum:
expected = sha256sum.readline().split()[0]
verified = found == expected
if not verified:
print("invalid checksum:\n"
@ -176,15 +167,6 @@ def require(cmd, exit=True):
sys.exit(1)
def stage0_data(rust_root):
"""Build a dictionary from stage0.txt"""
nightlies = os.path.join(rust_root, "src/stage0.txt")
with open(nightlies, 'r') as nightlies:
lines = [line.rstrip() for line in nightlies
if not line.startswith("#")]
return dict([line.split(": ", 1) for line in lines if line])
def format_build_time(duration):
"""Return a nicer format for build time
@ -372,13 +354,22 @@ def output(filepath):
os.rename(tmp, filepath)
class Stage0Toolchain:
def __init__(self, stage0_payload):
self.date = stage0_payload["date"]
self.version = stage0_payload["version"]
def channel(self):
return self.version + "-" + self.date
class RustBuild(object):
"""Provide all the methods required to build Rust"""
def __init__(self):
self.date = ''
self.checksums_sha256 = {}
self.stage0_compiler = None
self.stage0_rustfmt = None
self._download_url = ''
self.rustc_channel = ''
self.rustfmt_channel = ''
self.build = ''
self.build_dir = ''
self.clean = False
@ -402,11 +393,10 @@ class RustBuild(object):
will move all the content to the right place.
"""
if rustc_channel is None:
rustc_channel = self.rustc_channel
rustfmt_channel = self.rustfmt_channel
rustc_channel = self.stage0_compiler.version
bin_root = self.bin_root(stage0)
key = self.date
key = self.stage0_compiler.date
if not stage0:
key += str(self.rustc_commit)
if self.rustc(stage0).startswith(bin_root) and \
@ -445,19 +435,23 @@ class RustBuild(object):
if self.rustfmt() and self.rustfmt().startswith(bin_root) and (
not os.path.exists(self.rustfmt())
or self.program_out_of_date(self.rustfmt_stamp(), self.rustfmt_channel)
or self.program_out_of_date(
self.rustfmt_stamp(),
"" if self.stage0_rustfmt is None else self.stage0_rustfmt.channel()
)
):
if rustfmt_channel:
if self.stage0_rustfmt is not None:
tarball_suffix = '.tar.xz' if support_xz() else '.tar.gz'
[channel, date] = rustfmt_channel.split('-', 1)
filename = "rustfmt-{}-{}{}".format(channel, self.build, tarball_suffix)
filename = "rustfmt-{}-{}{}".format(
self.stage0_rustfmt.version, self.build, tarball_suffix,
)
self._download_component_helper(
filename, "rustfmt-preview", tarball_suffix, key=date
filename, "rustfmt-preview", tarball_suffix, key=self.stage0_rustfmt.date
)
self.fix_bin_or_dylib("{}/bin/rustfmt".format(bin_root))
self.fix_bin_or_dylib("{}/bin/cargo-fmt".format(bin_root))
with output(self.rustfmt_stamp()) as rustfmt_stamp:
rustfmt_stamp.write(self.rustfmt_channel)
rustfmt_stamp.write(self.stage0_rustfmt.channel())
# Avoid downloading LLVM twice (once for stage0 and once for the master rustc)
if self.downloading_llvm() and stage0:
@ -518,7 +512,7 @@ class RustBuild(object):
):
if key is None:
if stage0:
key = self.date
key = self.stage0_compiler.date
else:
key = self.rustc_commit
cache_dst = os.path.join(self.build_dir, "cache")
@ -527,12 +521,21 @@ class RustBuild(object):
os.makedirs(rustc_cache)
if stage0:
url = "{}/dist/{}".format(self._download_url, key)
base = self._download_url
url = "dist/{}".format(key)
else:
url = "https://ci-artifacts.rust-lang.org/rustc-builds/{}".format(self.rustc_commit)
base = "https://ci-artifacts.rust-lang.org"
url = "rustc-builds/{}".format(self.rustc_commit)
tarball = os.path.join(rustc_cache, filename)
if not os.path.exists(tarball):
get("{}/{}".format(url, filename), tarball, verbose=self.verbose, do_verify=stage0)
get(
base,
"{}/{}".format(url, filename),
tarball,
self.checksums_sha256,
verbose=self.verbose,
do_verify=stage0,
)
unpack(tarball, tarball_suffix, self.bin_root(stage0), match=pattern, verbose=self.verbose)
def _download_ci_llvm(self, llvm_sha, llvm_assertions):
@ -542,7 +545,8 @@ class RustBuild(object):
if not os.path.exists(rustc_cache):
os.makedirs(rustc_cache)
url = "https://ci-artifacts.rust-lang.org/rustc-builds/{}".format(llvm_sha)
base = "https://ci-artifacts.rust-lang.org"
url = "rustc-builds/{}".format(llvm_sha)
if llvm_assertions:
url = url.replace('rustc-builds', 'rustc-builds-alt')
# ci-artifacts are only stored as .xz, not .gz
@ -554,7 +558,14 @@ class RustBuild(object):
filename = "rust-dev-nightly-" + self.build + tarball_suffix
tarball = os.path.join(rustc_cache, filename)
if not os.path.exists(tarball):
get("{}/{}".format(url, filename), tarball, verbose=self.verbose, do_verify=False)
get(
base,
"{}/{}".format(url, filename),
tarball,
self.checksums_sha256,
verbose=self.verbose,
do_verify=False,
)
unpack(tarball, tarball_suffix, self.llvm_root(),
match="rust-dev",
verbose=self.verbose)
@ -816,7 +827,7 @@ class RustBuild(object):
def rustfmt(self):
"""Return config path for rustfmt"""
if not self.rustfmt_channel:
if self.stage0_rustfmt is None:
return None
return self.program_config('rustfmt')
@ -1040,19 +1051,12 @@ class RustBuild(object):
self.update_submodule(module[0], module[1], recorded_submodules)
print("Submodules updated in %.2f seconds" % (time() - start_time))
def set_normal_environment(self):
def set_dist_environment(self, url):
"""Set download URL for normal environment"""
if 'RUSTUP_DIST_SERVER' in os.environ:
self._download_url = os.environ['RUSTUP_DIST_SERVER']
else:
self._download_url = 'https://static.rust-lang.org'
def set_dev_environment(self):
"""Set download URL for development environment"""
if 'RUSTUP_DEV_DIST_SERVER' in os.environ:
self._download_url = os.environ['RUSTUP_DEV_DIST_SERVER']
else:
self._download_url = 'https://dev-static.rust-lang.org'
self._download_url = url
def check_vendored_status(self):
"""Check that vendoring is configured properly"""
@ -1161,17 +1165,14 @@ def bootstrap(help_triggered):
build_dir = build.get_toml('build-dir', 'build') or 'build'
build.build_dir = os.path.abspath(build_dir.replace("$ROOT", build.rust_root))
data = stage0_data(build.rust_root)
build.date = data['date']
build.rustc_channel = data['rustc']
with open(os.path.join(build.rust_root, "src", "stage0.json")) as f:
data = json.load(f)
build.checksums_sha256 = data["checksums_sha256"]
build.stage0_compiler = Stage0Toolchain(data["compiler"])
if data.get("rustfmt") is not None:
build.stage0_rustfmt = Stage0Toolchain(data["rustfmt"])
if "rustfmt" in data:
build.rustfmt_channel = data['rustfmt']
if 'dev' in data:
build.set_dev_environment()
else:
build.set_normal_environment()
build.set_dist_environment(data["dist_server"])
build.build = args.build or build.build_triple()
build.update_submodules()

View File

@ -13,38 +13,18 @@ from shutil import rmtree
import bootstrap
class Stage0DataTestCase(unittest.TestCase):
"""Test Case for stage0_data"""
def setUp(self):
self.rust_root = tempfile.mkdtemp()
os.mkdir(os.path.join(self.rust_root, "src"))
with open(os.path.join(self.rust_root, "src",
"stage0.txt"), "w") as stage0:
stage0.write("#ignore\n\ndate: 2017-06-15\nrustc: beta\ncargo: beta\nrustfmt: beta")
def tearDown(self):
rmtree(self.rust_root)
def test_stage0_data(self):
"""Extract data from stage0.txt"""
expected = {"date": "2017-06-15", "rustc": "beta", "cargo": "beta", "rustfmt": "beta"}
data = bootstrap.stage0_data(self.rust_root)
self.assertDictEqual(data, expected)
class VerifyTestCase(unittest.TestCase):
"""Test Case for verify"""
def setUp(self):
self.container = tempfile.mkdtemp()
self.src = os.path.join(self.container, "src.txt")
self.sums = os.path.join(self.container, "sums")
self.bad_src = os.path.join(self.container, "bad.txt")
content = "Hello world"
self.expected = hashlib.sha256(content.encode("utf-8")).hexdigest()
with open(self.src, "w") as src:
src.write(content)
with open(self.sums, "w") as sums:
sums.write(hashlib.sha256(content.encode("utf-8")).hexdigest())
with open(self.bad_src, "w") as bad:
bad.write("Hello!")
@ -53,11 +33,11 @@ class VerifyTestCase(unittest.TestCase):
def test_valid_file(self):
"""Check if the sha256 sum of the given file is valid"""
self.assertTrue(bootstrap.verify(self.src, self.sums, False))
self.assertTrue(bootstrap.verify(self.src, self.expected, False))
def test_invalid_file(self):
"""Should verify that the file is invalid"""
self.assertFalse(bootstrap.verify(self.bad_src, self.sums, False))
self.assertFalse(bootstrap.verify(self.bad_src, self.expected, False))
class ProgramOutOfDate(unittest.TestCase):
@ -99,7 +79,6 @@ if __name__ == '__main__':
TEST_LOADER = unittest.TestLoader()
SUITE.addTest(doctest.DocTestSuite(bootstrap))
SUITE.addTests([
TEST_LOADER.loadTestsFromTestCase(Stage0DataTestCase),
TEST_LOADER.loadTestsFromTestCase(VerifyTestCase),
TEST_LOADER.loadTestsFromTestCase(ProgramOutOfDate)])

View File

@ -523,7 +523,7 @@ impl<'a> Builder<'a> {
install::Src,
install::Rustc
),
Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest),
Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest, run::BumpStage0),
}
}

View File

@ -31,7 +31,7 @@
//! When you execute `x.py build`, the steps executed are:
//!
//! * First, the python script is run. This will automatically download the
//! stage0 rustc and cargo according to `src/stage0.txt`, or use the cached
//! stage0 rustc and cargo according to `src/stage0.json`, or use the cached
//! versions if they're available. These are then used to compile rustbuild
//! itself (using Cargo). Finally, control is then transferred to rustbuild.
//!

View File

@ -82,3 +82,24 @@ impl Step for BuildManifest {
builder.run(&mut cmd);
}
}
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct BumpStage0;
impl Step for BumpStage0 {
type Output = ();
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/tools/bump-stage0")
}
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(BumpStage0);
}
fn run(self, builder: &Builder<'_>) -> Self::Output {
let mut cmd = builder.tool_cmd(Tool::BumpStage0);
builder.run(&mut cmd);
}
}

View File

@ -15,7 +15,7 @@ use std::fs;
use std::path::PathBuf;
use std::process::Command;
use build_helper::{output, t};
use build_helper::output;
use crate::cache::INTERNER;
use crate::config::Target;
@ -227,14 +227,4 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
if let Some(ref s) = build.config.ccache {
cmd_finder.must_have(s);
}
if build.config.channel == "stable" {
let stage0 = t!(fs::read_to_string(build.src.join("src/stage0.txt")));
if stage0.contains("\ndev:") {
panic!(
"bootstrapping from a dev compiler in a stable release, but \
should only be bootstrapping from a released compiler!"
);
}
}
}

View File

@ -377,6 +377,7 @@ bootstrap_tool!(
LintDocs, "src/tools/lint-docs", "lint-docs";
JsonDocCk, "src/tools/jsondocck", "jsondocck";
HtmlChecker, "src/tools/html-checker", "html-checker";
BumpStage0, "src/tools/bump-stage0", "bump-stage0";
);
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]

346
src/stage0.json Normal file
View File

@ -0,0 +1,346 @@
{
"__comment": "Generated by `./x.py run src/tools/bump-stage0`. Run that command again to update the bootstrap compiler.",
"dist_server": "https://static.rust-lang.org",
"compiler": {
"date": "2021-08-22",
"version": "beta"
},
"rustfmt": {
"date": "2021-08-26",
"version": "nightly"
},
"checksums_sha256": {
"dist/2021-08-22/cargo-beta-aarch64-apple-darwin.tar.gz": "1aae6206b6ee057a53c6863d1aa9246a913bd8cc87945221ffe25a0763198ec9",
"dist/2021-08-22/cargo-beta-aarch64-apple-darwin.tar.xz": "9bb4026714d46f99077c4ec2ac1f818a059252996077569339a72704a1044cc5",
"dist/2021-08-22/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "127a066958fe2f67154ae5e5ffdf67e216cd9da5c8ca7f6f5818017ef647eb57",
"dist/2021-08-22/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "f62459d78c012d129a38f9f05975f784ca59f613cb77f273ac1be992320968ca",
"dist/2021-08-22/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "eb0e5765d0d37129a1e70680cb701fc7968baf98a183a25fbe495d5e1818a67c",
"dist/2021-08-22/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "8168902da36e32c2b2946ec18d41c4877191e3b5ec95276d85a1453541be8adf",
"dist/2021-08-22/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "e8a774fd383d0a7a3a1216ebd3a005fe01560002c8a28b89ce7f9a0ac522a07f",
"dist/2021-08-22/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "da7e246ca883ace9f9006257dd52756395307613f2bc10d86bacfe9b24f861c8",
"dist/2021-08-22/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "bc20e1ffe92aeca2a01bab6b1e383dfd7cecde01780bb2369ef5e10ef6e88bc7",
"dist/2021-08-22/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "5020ad70b694f18fa19be09d86983a7f396b38d71a65cf061438870d9264de45",
"dist/2021-08-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "53792dbfd932874bc7be8cf6683e5fa318afe9e59a3069f1c82279d9b66edcfd",
"dist/2021-08-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "cb393c4f0c0b6ef9c921733267192c01935fec55944c770765e3dcc37d9c20a8",
"dist/2021-08-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "96f017458f94370758b2cfa30f787707f548aeb9ca2dd9a52a43b27c73040b82",
"dist/2021-08-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "aa0b966b0ae33dc01714f16b3e511ae1f60da0a1a0e4de32e09cbe7a5e6a67b3",
"dist/2021-08-22/cargo-beta-i686-pc-windows-gnu.tar.gz": "38f9b818c71bbf607cd0db8e73b539506f42c529fb8a5053860e844914e0ade3",
"dist/2021-08-22/cargo-beta-i686-pc-windows-gnu.tar.xz": "ddfe1cee4f7d8a451ff5d1eb880c3e9ffa3fa1e59a8c12322e46562e379101de",
"dist/2021-08-22/cargo-beta-i686-pc-windows-msvc.tar.gz": "33d5d918ae8d35ecc760bf876573a51d62c98a46eb6c60c2e3ba8acba4ce6488",
"dist/2021-08-22/cargo-beta-i686-pc-windows-msvc.tar.xz": "0424f863ecf6e6d870325539637899720806a4130ffe815c724cdc34d8eb444f",
"dist/2021-08-22/cargo-beta-i686-unknown-linux-gnu.tar.gz": "d5e71781a82b424b28b90fe08d2ac4d86b37acd476bc36c106222128202a9476",
"dist/2021-08-22/cargo-beta-i686-unknown-linux-gnu.tar.xz": "65f860c74140318eb5c034a04c85e3eabfb31dfa8d70791d701f15d979d50361",
"dist/2021-08-22/cargo-beta-mips-unknown-linux-gnu.tar.gz": "034e491668d0f55b1fba9d606c2acb2d7d1d00db528f141207202ec6e5ca4410",
"dist/2021-08-22/cargo-beta-mips-unknown-linux-gnu.tar.xz": "f320d08c2116bcf1646f141426785e2b27488e48cf7e0ab97dab39efa4668efd",
"dist/2021-08-22/cargo-beta-mips64-unknown-linux-gnuabi64.tar.gz": "8bcb363d7dd7656bdeb5525df048dea384b34d564c98e3374c8c82f037e5074d",
"dist/2021-08-22/cargo-beta-mips64-unknown-linux-gnuabi64.tar.xz": "bbb924b505c82fef0d8912deb95b312d6547f96d15ff7cb06c5d77ee56c6fbbb",
"dist/2021-08-22/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "056e1662756321e884b84e662b9e465d58187f1fd9227ae4d7a9fce0110ddfb8",
"dist/2021-08-22/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "c01a661eee4e2ab0c93cc6575f8ae56c16b79bd0d5479d9f918004cf8a8abc2b",
"dist/2021-08-22/cargo-beta-mipsel-unknown-linux-gnu.tar.gz": "b74739855529627407a72244de3efd706ed99c347061513a677ebc7fd3b4e7c1",
"dist/2021-08-22/cargo-beta-mipsel-unknown-linux-gnu.tar.xz": "a275d7e95312e868636aa1539de0b2f490973119ffb4863f5534eed395c4113e",
"dist/2021-08-22/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "4f6326173b50952d933b02cc477156d5aad067798b347ce502889e607e98c84c",
"dist/2021-08-22/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "86ffca7848946079b62f083a92e47440a431b5c451aca3600efc0a5f3939ba2f",
"dist/2021-08-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "9c9406fcb15e88f93a23d0a275e44559e33b4a2eeab4403cbb2184bdca36318e",
"dist/2021-08-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "99ca6df78a1dfcb0c9a919f0eec47783f95399bae39271a6367c07b8ef346a5a",
"dist/2021-08-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "c24493b3e919ec268aa4b98da0a66332fa4e104210ed15b8f6c3b8c240ebeffe",
"dist/2021-08-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "7cfec0a0bae8471a32385a7c19d1ec17dba25ab1d6211cd062df73a9a1c030a2",
"dist/2021-08-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "8a8d81661cc1789185be6d4c13ac2ee602194a5526467ab34e4f23243cb9f474",
"dist/2021-08-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "b8ada6046b5351a627ae1fb4ee8ba059fa551f1de4444aba1d1915a27371d339",
"dist/2021-08-22/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "946d2d77ec784019f18372610ff438321e22f7e0d2e0045cc71180f3b2f6d376",
"dist/2021-08-22/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "2f3756d68b354341f98a3cfa4c89d78bf6e8c631dfb6477fceec5e6b00833d30",
"dist/2021-08-22/cargo-beta-x86_64-apple-darwin.tar.gz": "bccb3002b5cc3556555bb05208b7d64b9aee3a7dc3b482c03090ad0102c22570",
"dist/2021-08-22/cargo-beta-x86_64-apple-darwin.tar.xz": "a0f7dbfb008cb12bc7a8c9f464715e5aedfae175fdf5bb7bdf3d971072cd9b54",
"dist/2021-08-22/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "26fcc16d533e427eeded47f8c088aaa180602f68043f5dcd84755ac2166f16af",
"dist/2021-08-22/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "d5bc7bc9f2d5d2bbe7167f810b1334a86ddd694d111e145223474f8d6dee00af",
"dist/2021-08-22/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "6f3fe7f685324ff07995e5fb453462a1c4b5dac9208cd23935f6435af9146692",
"dist/2021-08-22/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "86e37578645f4436b7889c3b9c110888a2aff7af2833a7f5f38fa345a6f36e76",
"dist/2021-08-22/cargo-beta-x86_64-unknown-freebsd.tar.gz": "f0964def1f80732c1a67f0e4258a301ae2ee27d7ea474f70ab44816907a95ec3",
"dist/2021-08-22/cargo-beta-x86_64-unknown-freebsd.tar.xz": "6a4655c9b902b904b3dd2ca00dd656d0ef99c77e632f6d6ffc615486b4bfa543",
"dist/2021-08-22/cargo-beta-x86_64-unknown-illumos.tar.gz": "5aeb8db8c2e5afd80378a0aa1572c57ff021fb5dccb1bd914b994f0ca8764667",
"dist/2021-08-22/cargo-beta-x86_64-unknown-illumos.tar.xz": "0892a93f462e70aee33117de90caaa7b7ef363a27e573602c1d606c0309ae2d9",
"dist/2021-08-22/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "e4be5cd72bb220514c73d7da14ff2962dcd74b8602c1724d71538ab11da94132",
"dist/2021-08-22/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "0b643ba40ce6dbb270f85f45b2dd4d727051a896099493166cfad05c9be96b1f",
"dist/2021-08-22/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "998df5339f738815ab7c38b32df00eef09ff0e415a85d2ae2ab1c0836a380906",
"dist/2021-08-22/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "4ca058f973e2d439e812f839e57920dd9e73a0da9f9bf37889c06f3b1755b07e",
"dist/2021-08-22/cargo-beta-x86_64-unknown-netbsd.tar.gz": "6511df143067a3c3f6f741540f890f3bca46b11c01cda1c92e1708d0be30ebeb",
"dist/2021-08-22/cargo-beta-x86_64-unknown-netbsd.tar.xz": "4ebef9830e25fb28e12ea538e17a46cfe0748e6a14cf976048df056ae708b1ea",
"dist/2021-08-22/rust-std-beta-aarch64-apple-darwin.tar.gz": "6af3a7f720d5a7100683636c387865b3d4e9b5148ca04c1238662b81c8bbde9c",
"dist/2021-08-22/rust-std-beta-aarch64-apple-darwin.tar.xz": "459e63b66eb8e53e106896c3003183c5ef3803a8dd3d501d50e6d4e03343ad66",
"dist/2021-08-22/rust-std-beta-aarch64-apple-ios.tar.gz": "95c816378d57b5d7336373f7f53b603dd8a4efcf17634d4e008b6bd896947cac",
"dist/2021-08-22/rust-std-beta-aarch64-apple-ios.tar.xz": "209caeea6df90996d5239d0900767135bde716387317a10dc348b96aa818a93a",
"dist/2021-08-22/rust-std-beta-aarch64-fuchsia.tar.gz": "54ec6a313cc523fc568c4879cf36ab90bade8a1ae9c2ee89bafd57c2c9f3f754",
"dist/2021-08-22/rust-std-beta-aarch64-fuchsia.tar.xz": "82de1d66bf9cf226b80fea722d2828f368cbe75bc5d99a524193b50db6003636",
"dist/2021-08-22/rust-std-beta-aarch64-linux-android.tar.gz": "1a08cd54ff716d6ef3e53177e31787e8aa00f948054b42f94d791d3d59aa3169",
"dist/2021-08-22/rust-std-beta-aarch64-linux-android.tar.xz": "32c1b56cc223bab3e7f15de719488c874011dd6be622038ce5b1f7ff03b05c59",
"dist/2021-08-22/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "62a85f52db02e9afc659e84ea8bc3c8828f6a9fe4c1b58eecc3cefeb99e2d8ac",
"dist/2021-08-22/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "1e6126312252956f5ad887ca5e8271be3cf31ac8d793071f6af8c2adcdd57f00",
"dist/2021-08-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "5542b7e2ee1611f0410e2e962796cd7067e483b37730061a4f788f853f31c7c1",
"dist/2021-08-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "97f149839149fcff4004260eb119c1213f10a455b37a8256aec977bc04c9e2c0",
"dist/2021-08-22/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "48dada900d144fc9a17ff273ab44d9c4c5fb0cfbaae986d6396aaa6c9c5c22d5",
"dist/2021-08-22/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "c93b5da1e22138da0a97be32b9498a3ede270253a22a9d9275f610e349438bfb",
"dist/2021-08-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "904b39e24f5fe72393f943a5ecb3bfa6e07f3623a0cde911b161558660ee27d9",
"dist/2021-08-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "013646fe9e3f640ae820bfccce656c1bc94d0c3856613dbdea8b06574e072ad4",
"dist/2021-08-22/rust-std-beta-aarch64-unknown-none.tar.gz": "59de57b6902c755a2d92d5aa154452e84c747bc414605cebb367a4a17cf16ae7",
"dist/2021-08-22/rust-std-beta-aarch64-unknown-none.tar.xz": "9822fd8d21f863018ead909155ed7d931c5a9bb9ac6461c1f19609ad1a206a48",
"dist/2021-08-22/rust-std-beta-arm-linux-androideabi.tar.gz": "235bc683a244a69b1f36a875a418efb56af6e1f8411dbace6f9cef3ce1191f7d",
"dist/2021-08-22/rust-std-beta-arm-linux-androideabi.tar.xz": "a2d267e75d64e0bb96c9a8b78bb67db4ba46576edc51955108595c17ff285083",
"dist/2021-08-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "cc5d42c65ebc2733017a463c5a4903c681fd923dfa820ed6e420950f6c599ba5",
"dist/2021-08-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "1e9b3e5c0025c15f485eee6a39dc20ea62bfa777a820bd524817eeab07878e67",
"dist/2021-08-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "5f298d431d03d56112d2527c889d94296c03fb4187bbe26bd0e2be50bc9207ed",
"dist/2021-08-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "8be37b928562c4f08342b0661077dca25484d9e12e1e48b375fef02f6699fe87",
"dist/2021-08-22/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "db7d25058f4f39007495e864a20a398d307f9505721c9f5991db6d7065db50ee",
"dist/2021-08-22/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "fc858a2f2b7fe83cd148ee133b952ef8d63a6f39600fb101c7b98d37734484df",
"dist/2021-08-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "bc1ab01b0d7783c8cde71c1d4507fbf68330933e86d5b0280426eb9e9103ba38",
"dist/2021-08-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "18a1ca7fb88d56832ee5a331c3f3fa38ff2c72ecded3e093f4d6aef5e67e886d",
"dist/2021-08-22/rust-std-beta-armebv7r-none-eabi.tar.gz": "3eef0c676173ae40e3b1f900627c953955fdea5b3a24401bf69e9d433c9b0996",
"dist/2021-08-22/rust-std-beta-armebv7r-none-eabi.tar.xz": "58cdd696c46434bc0aea39b562aab818da1644da08bb385047b7b83cfedf9334",
"dist/2021-08-22/rust-std-beta-armebv7r-none-eabihf.tar.gz": "0035c38e059eac51cf8786bfde6162bb27ee8c642260af40646665902f9e4cc8",
"dist/2021-08-22/rust-std-beta-armebv7r-none-eabihf.tar.xz": "893d2d56614198da58327881684b1edab0a7d849eb8e3d6ba1705c192c98718e",
"dist/2021-08-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "489d6080bf6ab3dddfd490cc2c6cd956473389678eafe4b85b88e0ba06dfd73a",
"dist/2021-08-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "10ed28b9ce5b2d94492034e707a78d18540b096d1439faf5c7370d29c50ea105",
"dist/2021-08-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "febbed115d82f51d8c19b49f89a6fb9f1062826d6283e5877b8327b4b0572671",
"dist/2021-08-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "0f96c9b4bc3464cef4deeec087da38fc39d2cefb1cff7b413aedb8a79f412dc8",
"dist/2021-08-22/rust-std-beta-armv7-linux-androideabi.tar.gz": "8d407d9ddbe27ac708efb40d12b2292857c49f306afa018fd7df44116ccade3c",
"dist/2021-08-22/rust-std-beta-armv7-linux-androideabi.tar.xz": "253b5f4613369b4431296b1151b7c4228594889ac69674a0e3ef75438120868a",
"dist/2021-08-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "11e715bf0082733d94a796ed4e123f7ec77aa5fe0e8d037dd513dd69bc230a2e",
"dist/2021-08-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "a2d8a16c08721a406f8132f5deb960b65e38d3235a76b72d5f267b2bddb9ad91",
"dist/2021-08-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "2351b24b205851ff51e79a228416bb6ea801551050cb791464a0364a56a0133b",
"dist/2021-08-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "12da6b0947eebc24ae2a279bad6f1a50d26d57c956cb66840b5db6ef266975e4",
"dist/2021-08-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "96d333f046236bbfe809a5526e798197e8416442ddaec5e692aa642dd58f3397",
"dist/2021-08-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "f2d5832790120cceda3c07cb2dadb4d4e8e30228ffedbf4988a52573382689c1",
"dist/2021-08-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "d71cf49d01b781c55a64b174d4b91906771aeb90e885310576b5d77a068a8961",
"dist/2021-08-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "3e9b5c730f855b690103d44929384738748bdbc312fe5f8bdb9cb3fe1d8dc701",
"dist/2021-08-22/rust-std-beta-armv7a-none-eabi.tar.gz": "b0464837c6303c85d67ebcf45752ad9c859ea4ff013310c4ae64a2ff318db56b",
"dist/2021-08-22/rust-std-beta-armv7a-none-eabi.tar.xz": "13aec30cbdfb84483669a5d5a5d2f465f60692e997a6073d5f749c2950fe6a45",
"dist/2021-08-22/rust-std-beta-armv7r-none-eabi.tar.gz": "4c54b72683f8800f77b60889a8e91fe293a21916f756ab6fbe5f1e39884a11b2",
"dist/2021-08-22/rust-std-beta-armv7r-none-eabi.tar.xz": "5b917d543bd41f47ac8983cc5f3dfb19515b940eff644c5421f23575d8958e35",
"dist/2021-08-22/rust-std-beta-armv7r-none-eabihf.tar.gz": "305fce68a56206cffb34b4735fbff367b8d1f3131a043f5cf03de1ede9402323",
"dist/2021-08-22/rust-std-beta-armv7r-none-eabihf.tar.xz": "511fe782be16d7402519546af50427fc953f599773466668c0133e3d252874ce",
"dist/2021-08-22/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "31223e26db1d00219cf78e70c096aaec45a5ba2f2835dcb55edcc1e2e83e28b8",
"dist/2021-08-22/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "2453e08515943e38def4d65c8278f2d25c5b7dfa7883040346c0824abaab9cb0",
"dist/2021-08-22/rust-std-beta-i586-pc-windows-msvc.tar.gz": "1f22b735b50f2ccbb3ba99a27e4901b2da9d408361ad8ce2710ab61dbb6a8c46",
"dist/2021-08-22/rust-std-beta-i586-pc-windows-msvc.tar.xz": "e2f31b9933df67a5fdae28f26b38f907fb2607ccfc2a1f2e6b6fd9853eb6eb6a",
"dist/2021-08-22/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "a3d2d4184376f6d398a3b1bfbab881659408340287d61d7f29d70bb167824427",
"dist/2021-08-22/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "3803e83360d67e1866d2dada4f62fbf2a04ac3cbc7c347ba4ce97b2e6adf9ced",
"dist/2021-08-22/rust-std-beta-i586-unknown-linux-musl.tar.gz": "c2890c8ae6c3bb71811867ab953e774161415d454009d9f36a116c86994a9056",
"dist/2021-08-22/rust-std-beta-i586-unknown-linux-musl.tar.xz": "671191cab9795d52a7ed9762951de46a89988bb22233b6a0b09e85bdc5e5d904",
"dist/2021-08-22/rust-std-beta-i686-linux-android.tar.gz": "3e83c96f73f5b526e3f20939338e0b51a94898ffcfa3c7d08ef72966e9161f71",
"dist/2021-08-22/rust-std-beta-i686-linux-android.tar.xz": "8c96f60b63bdcec60ea52cbb3880f2d684b2b96a37b37946a24d893eafb4dc77",
"dist/2021-08-22/rust-std-beta-i686-pc-windows-gnu.tar.gz": "760e6deb8aec1185b8127bc012794463eefa87dd48a1fb69e6f79ccad45422e5",
"dist/2021-08-22/rust-std-beta-i686-pc-windows-gnu.tar.xz": "82809e4bf5b89cfad4d8c8770deb5c2bab4ed1f17463a09c728c25684b7d2d72",
"dist/2021-08-22/rust-std-beta-i686-pc-windows-msvc.tar.gz": "288086c4caf64a38b441937f9d3335b0ef419bb6a2693216b48aefe31c34f7ea",
"dist/2021-08-22/rust-std-beta-i686-pc-windows-msvc.tar.xz": "06bb31b48abfbfdf4c627d87717987cb0e721100f952e77435c156bd45eb02a3",
"dist/2021-08-22/rust-std-beta-i686-unknown-freebsd.tar.gz": "589d7aeabc268fb06f3fd7ff37dfff434924fe87fb778ffa366a27ebf815a26c",
"dist/2021-08-22/rust-std-beta-i686-unknown-freebsd.tar.xz": "b5b7bf0752034c4e79827e2155afbc7b2fd59a5220e8acf9b244023a725f9483",
"dist/2021-08-22/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "94c9450ad3915dd6367833b59e07b66083d653eaa72b3b486676c3475fcca86e",
"dist/2021-08-22/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "014e3abef9cbea6008653ba3e85c7cf074add0bbfa71afa90a9f577f014de19c",
"dist/2021-08-22/rust-std-beta-i686-unknown-linux-musl.tar.gz": "9897bea4ada2d49e055210699a757f59620d8092e9b40c3eba2dd9fde0205309",
"dist/2021-08-22/rust-std-beta-i686-unknown-linux-musl.tar.xz": "7c53fbd4643e4f9f5e441a79bdbbf8044b3d35d113ca2ce670462433c9299ce4",
"dist/2021-08-22/rust-std-beta-mips-unknown-linux-gnu.tar.gz": "2d4af2bd5c632de7de1abf556acda7c4897f5475221a7e72d36d70236c90a332",
"dist/2021-08-22/rust-std-beta-mips-unknown-linux-gnu.tar.xz": "f388bb0bbfa4d505101b6f087205cef9593b29d55d04dc0f08629d23df6f4dd5",
"dist/2021-08-22/rust-std-beta-mips-unknown-linux-musl.tar.gz": "7a35ebffe2858e68c8585c54d980edfb7fd84b3a78856110871d062f58e4c4d9",
"dist/2021-08-22/rust-std-beta-mips-unknown-linux-musl.tar.xz": "40ca86dbff7248854b86ae2a4c05efa5e240ae40d88a887a2681aa0c4995fad3",
"dist/2021-08-22/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.gz": "3d380de1f425c4e022037805b4687567870d84bd06375c26528e5a9529b1f0df",
"dist/2021-08-22/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.xz": "15f951100779f6535a25f91b58630951376d9191dabb3405b34a78246bd07d6b",
"dist/2021-08-22/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "d1d2f014a7d0c5b6140d282bf38d5fc4c7a93df0e484d9f893fe3ed25c5cf384",
"dist/2021-08-22/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "7f96e0ebaa820cf927962b0c0c584b4b96d3fd34e90e281162138937f145fde5",
"dist/2021-08-22/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "e6d8a5e5de7328d045ccc4c6457e82282c7b0a23bc35443f402672d94df088ef",
"dist/2021-08-22/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "d015d566ae58d854de39337ddfc31f29cdbb4e87320e20b0fbcc83912415d11f",
"dist/2021-08-22/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "cbbcf7edb5f785d89bc20c287a6dcab69eabbdfff0ed8d9283ea0766d98ccfee",
"dist/2021-08-22/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "4b988afc44729564783300cfd47b1ace974bd8eacb52cc553365fdd07b8b38e7",
"dist/2021-08-22/rust-std-beta-mipsel-unknown-linux-gnu.tar.gz": "674d244f0d536ff053be6384ee9ba9b80db2cc6d9bd840434d26fabdb259d7be",
"dist/2021-08-22/rust-std-beta-mipsel-unknown-linux-gnu.tar.xz": "07aa043aac39364935f6758e1d2200d6334b719e4b13ad7bcc9e693cfef90e3c",
"dist/2021-08-22/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "19aa1bc698c24eb1136de2a8ace0b872a472e9fb5b1c1fbd48d03fa8e3dab00b",
"dist/2021-08-22/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "a9db5dfaca379bcb6a2c3bb5c6d6eafe4dace2e814c7edb5fdf6a26595be2538",
"dist/2021-08-22/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "ebe482fecfce4ff0ee9dd514b984b9c04565470ecd7a24d94778d51e31107915",
"dist/2021-08-22/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "b663ce48f79cf4634d35e8c35f10c2c51d775c906b9c7a46ae6e67d7070e1b21",
"dist/2021-08-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "aeb314e2de96b9d7623a8b58d34fb1d290039b1ad63ad91da5052bbcb8569d66",
"dist/2021-08-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "87731e0ea78d1478f87c50d770618b7feb6d404ae257704a1a622bbfc4a079cc",
"dist/2021-08-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "5eeea41e13e8941e1a7e29dc649cc34fafad8ef01fdeffb133cf0dad6cc57997",
"dist/2021-08-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "3435ba7a88ad51266a32fdba648f1d4a60a918ad396261a03593a409db028f1b",
"dist/2021-08-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "d453444ef726401c683042f2d33c70fc078ef79d95d4cbd0f007d41bb8894e2b",
"dist/2021-08-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "ab83c5f5477bb3a800e2054d345ed48bba162c871788f7b187f875652f9e8163",
"dist/2021-08-22/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "d007269d819f76c53e211c8a2871db177c6f910de463f87ae1cc3d3e3f0d42b8",
"dist/2021-08-22/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "3bc82447155b9a453abe1788705b61ea41f017048a017d973a41a587b81b4bab",
"dist/2021-08-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "5c6b7fb54fa4effd3140848b9f7779b4139971f0666758bff43c8bc93877d962",
"dist/2021-08-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "4043a4dca70b44ff5471a3457fbc85218850ab0dd52bbeef87bc629170f07bc3",
"dist/2021-08-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "aaa6eee8c67c6c666cca044c75e0049fc982442647528263ac87bfd17bddd0e5",
"dist/2021-08-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "ce8633daef8fab199318c26cac981de0a7db1e93a066c05187f4f3165826da6a",
"dist/2021-08-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "d5323d5b0a8a9c4f7f688449ac4b39b1b0e30ae26fbdb355ab3477c033e86f74",
"dist/2021-08-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "e4dd4e3b3fef2434ad5b96d7c966576f9d27cca146bb1df3ec0dea92e65d1234",
"dist/2021-08-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "ca1e486ed9b37d64c4c1ff4ade719bd4d75ea42d862a53e7ce5106045498618e",
"dist/2021-08-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "b07b65d1df2b7147cfcda1aa8c43b64cb0f29290fe9518569969550fd176399e",
"dist/2021-08-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "3225c1a028dbff77a73c8209417261689dcffff8c9019bfb81d7c2ddf440999d",
"dist/2021-08-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "d219a81bc543d000200f0a11de6db87f5f0b135122150f37782d0e1132669ffc",
"dist/2021-08-22/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "92a70667972c1fa0e5963ef189a450f65861d779f2251e10884bc9dac3751e2a",
"dist/2021-08-22/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "31405140b78366c182ebcb02632983017409c3c282a2eac6716d410fc2f6d1a4",
"dist/2021-08-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "3f6dfab8290bdd2e12f7a4a8ba0e2b58006e0a0096357077cdd1392e94a81bd7",
"dist/2021-08-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "327a86e0e83ccaac9ebb5458e48906a5e83ec928fc01939758a50ce46c114334",
"dist/2021-08-22/rust-std-beta-sparcv9-sun-solaris.tar.gz": "c798402360747dac456746c4fb68de30e702ba6a3a1cea0bd5884546d1c2f714",
"dist/2021-08-22/rust-std-beta-sparcv9-sun-solaris.tar.xz": "63a9ebcbb4e97cd80c0c97ba6323614cc69a4ff15904e6120aae970a803b3402",
"dist/2021-08-22/rust-std-beta-thumbv6m-none-eabi.tar.gz": "bf1ae6e7ceeee0b9631d638aa33b29fc064699eebf1da192aed0b7c0a98f6866",
"dist/2021-08-22/rust-std-beta-thumbv6m-none-eabi.tar.xz": "da183dbff702ab18cf02d34c395c6dc70344b525c0d09bc26a8670b75e6e900a",
"dist/2021-08-22/rust-std-beta-thumbv7em-none-eabi.tar.gz": "f6c66612b1f500218927504a23eb3df1bd8ff5a6171d576ebb681bb0f426d5c6",
"dist/2021-08-22/rust-std-beta-thumbv7em-none-eabi.tar.xz": "8364308682a2c6e91b2c7bfacb09dd9a7487c106ae95c489286d13e641ecaaa0",
"dist/2021-08-22/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "711e05b89ab2cf2cc17aa7beeb5bc2aafcd851606a8dd535230e64bc5d232dea",
"dist/2021-08-22/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "f444669bde93eae4599db7624f830b031f4d4d116d0344829be3177558a5dfd1",
"dist/2021-08-22/rust-std-beta-thumbv7m-none-eabi.tar.gz": "9b4699b67763b7c2691a95c69827f6c8ce8847c64e0806b0c3f36f48848a7e4e",
"dist/2021-08-22/rust-std-beta-thumbv7m-none-eabi.tar.xz": "2c038bc6607b115f817859aae07c495d6d2a1bd4cfe9007f36494b9229a68d86",
"dist/2021-08-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "7634d01dfdb18a43bc8a230df711e8254f3bbc214b89844475bfba9eb920a5cf",
"dist/2021-08-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "ba0815d8b0d5600cd09148343bcbfa25004b3092bee1ed0e0673fdf8937ebf62",
"dist/2021-08-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "823ee6535da426700b0aed6a33201873d8b6611248506e436cdddae92a074a06",
"dist/2021-08-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "c4b21b5300959794c811653aa907fd259970b08c41d4ce303384b34783b142cf",
"dist/2021-08-22/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "d71ce2ec3eb040244c017dc7bb40342da106d097a579ab69312f1879d5c446c7",
"dist/2021-08-22/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "05375174c0d6f9480c5b504ee16823a28d2994bea0eee52242cef25f9d7b766d",
"dist/2021-08-22/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "9e9efb15d1718421b5537aca94dbc078d8cf4f1651b0b2e790af5fb0d8592ea4",
"dist/2021-08-22/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "d7ffe70ed73bf689c3edcccc1bfc23ba75737f2d0841d471720d23a67b2cd63e",
"dist/2021-08-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "704a086e751b96f1249bd295a9dc45f9aeee0d93bf96d2d6fe00ffaf33af3062",
"dist/2021-08-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "c7ea8e97a90c4e27f910f8ef1e64885540179dc55ef09e4f5a844bb7ab3d0c9b",
"dist/2021-08-22/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "2165a0868d21ce1cf10e6360f8384866a985358475cae1bfa74d33d3516db565",
"dist/2021-08-22/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "6909a1ace7b22fa66b175cbf3de0cc54708f0aa73baa3e2168f3e758698c26c8",
"dist/2021-08-22/rust-std-beta-wasm32-unknown-unknown.tar.gz": "dd2eb7f4fb9285c11cdbeddaee20a75179a1588486ccbcb7b6e32971790acaf6",
"dist/2021-08-22/rust-std-beta-wasm32-unknown-unknown.tar.xz": "9e51dc30f624af1410a77b4f77f01868ec141d6288b09827f7e3a313b276f78a",
"dist/2021-08-22/rust-std-beta-wasm32-wasi.tar.gz": "b29b2748928aaf72aa30117cfd8bd9c6c13a6c7255efe1bcbd6bf535aefb1294",
"dist/2021-08-22/rust-std-beta-wasm32-wasi.tar.xz": "90f58b108a9538e190fd3ecec97581b95c85ed27ebcbf1f4ef85b4e3248db0f5",
"dist/2021-08-22/rust-std-beta-x86_64-apple-darwin.tar.gz": "b6549bfeb4ad3de444ff7afce6baaa34ee7468d41480a86072cd3a26e1191de0",
"dist/2021-08-22/rust-std-beta-x86_64-apple-darwin.tar.xz": "44d77279c9997ebc5f4952fde208de6747f6b95e1887c1ac637f3f5170cda003",
"dist/2021-08-22/rust-std-beta-x86_64-apple-ios.tar.gz": "3a69d284711c0eab25a73b6d22a3fd92e6741e22a454d0210694c73c2775e6db",
"dist/2021-08-22/rust-std-beta-x86_64-apple-ios.tar.xz": "08b97affa6264d739eb31925f3d4a2fb0feb32e6b3eff770c580782bea216ca0",
"dist/2021-08-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "15334ea58e51d1d5f35f15c75a0f941b3648d9bc2acbb57a6c07b788c78aa6d2",
"dist/2021-08-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "7aad1c1dc41f5713fb9a3414b0cd64b78f3b8cd6bd12a9fe14318cbab5c804aa",
"dist/2021-08-22/rust-std-beta-x86_64-fuchsia.tar.gz": "48e706203750b335276140b8156c5c74ed48cd36aa7a6f732f7febe3d517da76",
"dist/2021-08-22/rust-std-beta-x86_64-fuchsia.tar.xz": "d0a14f312a2f91961f955352f6e508cdf5e5ac82be10837843ec7c87ed9d3ff9",
"dist/2021-08-22/rust-std-beta-x86_64-linux-android.tar.gz": "12a29451878739ba28838a8bf0eda9ab4826457a6ef249644bbe11e3afbde650",
"dist/2021-08-22/rust-std-beta-x86_64-linux-android.tar.xz": "f2fe871094a8dbd11bf15d9139ca0d630b9fc2c03d1bfed295d1ee01a8484910",
"dist/2021-08-22/rust-std-beta-x86_64-pc-solaris.tar.gz": "42237c674c4c5f6181da0eaeffc755a08087b87350770fca6a3d707158cd66f4",
"dist/2021-08-22/rust-std-beta-x86_64-pc-solaris.tar.xz": "167aa8827682e3a6c140a7607ede1c0ca90014634940c228dc538263b6e1ea8d",
"dist/2021-08-22/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "7517896917e38d12d3265b0202ea8bd839d8cfd08b9c6b2c6033b5f70d24f049",
"dist/2021-08-22/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "902b1a27c034206fd03457a52eb495c2bed5d3f4355e4d94d1dea05746e10df1",
"dist/2021-08-22/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "3b2143072753553cc05d40e0684fdbabe6eb8c436588ce2f29ca393f3c5a8609",
"dist/2021-08-22/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "47d03efe92f8fcfbdb192565dcf4db4e4c1c301ff4bd8cb15e0ae74c5ee00122",
"dist/2021-08-22/rust-std-beta-x86_64-sun-solaris.tar.gz": "7394b58442de5d444c1fdaef7d91da57f6bd64a50ccd8be518e2e620e0829036",
"dist/2021-08-22/rust-std-beta-x86_64-sun-solaris.tar.xz": "4839a52f87ec51bdf0438dfaeb57f3757b481ad47a7e86db9740d3e86e2c261f",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "a44012100040021f42335ba35be08570c86d72c371783e203fd1a6144d46a6fe",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "7279b03775bd896709700727d9db6030a05a4cad3842c1b225404bd1545a0ba9",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-illumos.tar.gz": "ee719a8fc9a6a5ba1d47fc5d95ebdc8f692b473ed22202d3315de1aebcbae374",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-illumos.tar.xz": "a85f334cf580035472b054383365c6da4509aa85a3901e6d30649c3e6f1af4f9",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "96884f6544e2d51034cac32618e4e35ee0c84467d8a80f635d8073980fed0ce6",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "98f745588c290a0319216d067a60ba3665506111bdcc4a773b5b850f9ac8107a",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "cb3249e99fd60a57cdab4a529c14eae3d76fc85768ec9cb9186eeafc32f45214",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "614acd645f9c79eda648236e6f3c028d9bb5482297059bfc93dab9f2e90d1478",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "c7988d678d330d31c3e88df27b9c2b482854d0b7f277f8126e2996a9f4180387",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "11d16c7f5b64e3d4bcfcad489c2710ca7e3cad12c82221848c51ed839688e02b",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "45f880920e746f53810fc70526e18ef807e6d4089ef147bed8c53c536624f646",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "0910b51938eed74ad4af9e07f74ea5648a143fbd142a9cb4fe1bc7f7b7bd6159",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-redox.tar.gz": "c14fd257005a11026cc3ebf23fb9f2d35a6d99f9136471574d8c0d18fc66e3b7",
"dist/2021-08-22/rust-std-beta-x86_64-unknown-redox.tar.xz": "9c3438ecac2dfaf827039b506c114bdc06c05a69b81761abfb63f8a227950da7",
"dist/2021-08-22/rustc-beta-aarch64-apple-darwin.tar.gz": "357bb650d7377610e61a9ff2167a7fd480ca844322849e5dcc80a91edc5fffa5",
"dist/2021-08-22/rustc-beta-aarch64-apple-darwin.tar.xz": "3f0883cd2c1d1bc31dd89a72711ba6a22a1c455f28dc2d5644e70898614a637a",
"dist/2021-08-22/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "6366923332e491d21b5f448500fd56673fd21738e6edcbdb21c11fafb00723de",
"dist/2021-08-22/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "b0e7462540e6c96b373f6aebf6ab58ca4c2cc62627c5c5ec8b135516ce9098f9",
"dist/2021-08-22/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "21bdf608d2bc3799206065225410ccbb015a379cbcf79a901e4e9420d1a4feb4",
"dist/2021-08-22/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "4b1520615af8f2baad919740716c482cd5ac421bd87e44cde21788e79c996a4c",
"dist/2021-08-22/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "4aece49879bb274f0170b98941fa220d1ae4f1c4cb33c3fa7ae4146679675d1d",
"dist/2021-08-22/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "d3c565f7a2a1bcf21849122c1c6fbbf81ce1e8dbaf103e8f5c406b2f35aadde1",
"dist/2021-08-22/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "311df5769ba9a2889c1e9a97df6c1bd369224832a80789bae339121138e40513",
"dist/2021-08-22/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "e2818874f3f3d873e858e78585e60804971d57e206c023e8a1c82d03cc9ee5b3",
"dist/2021-08-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "9bb1e02517abfe3e626812cea2d389b26451db341bd1c56f5c06f90a71936cde",
"dist/2021-08-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "fe02b9b389297a781bbdac812ac3526973a221edc2cd7b2be4fcb197e817b148",
"dist/2021-08-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "c6733d130bda448d7801caa215d3f58abd6576119eb764a55c326344fcbbdede",
"dist/2021-08-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "0a553a9821eb076873976bf523c8b1278de367854d6fbca0728bde97768c4ec9",
"dist/2021-08-22/rustc-beta-i686-pc-windows-gnu.tar.gz": "c5a724275014bf1c244ff6ab878271747097b3f216e5753e3ca65c1714a2456a",
"dist/2021-08-22/rustc-beta-i686-pc-windows-gnu.tar.xz": "0a6ff560eb1a7d02e48661939bbb940cdb5d988ccacbcbdc0f7fa24890b0d9b2",
"dist/2021-08-22/rustc-beta-i686-pc-windows-msvc.tar.gz": "da487112240ab21c3b3f9d9816e7b4738022f58ba0e93c0772a8fcbb17ba0573",
"dist/2021-08-22/rustc-beta-i686-pc-windows-msvc.tar.xz": "944bd6f24ff92a748c804e3deac1994fe03cda4b897be3eb12f21d069add4cdd",
"dist/2021-08-22/rustc-beta-i686-unknown-linux-gnu.tar.gz": "e986624d0a97155a588c9b95c7470c1b322bbae11f9582ad62d2c914642400d9",
"dist/2021-08-22/rustc-beta-i686-unknown-linux-gnu.tar.xz": "dbaf95a9b3f6fccab5d59533be35f59b7901b31e61488f85032bd15bfb67eb34",
"dist/2021-08-22/rustc-beta-mips-unknown-linux-gnu.tar.gz": "374bd970d5cba1b9af4a36250dfea2eaacafd9e6b4b0d4d9165abdd11841d4c3",
"dist/2021-08-22/rustc-beta-mips-unknown-linux-gnu.tar.xz": "2ddec9e30d15f2e1f05e9a59c739f1be51fc8d836acda395aacfb933826a5637",
"dist/2021-08-22/rustc-beta-mips64-unknown-linux-gnuabi64.tar.gz": "a21a1c099324517b6da6dfd8f2154b4d32bfe69d3a1f386e1bc5be2c3743b938",
"dist/2021-08-22/rustc-beta-mips64-unknown-linux-gnuabi64.tar.xz": "b81fa8c2d534386ceb0bb0767c260e340cda7122e23c834afb17097976ff682d",
"dist/2021-08-22/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "2822fdb98095c292a4e0b0e6ee3be4e1cc5ffda42dae101b2c6a6c4bb7a1ec4e",
"dist/2021-08-22/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "7d40bef08d3f0d097755eae0b26057f579fd40f4968dd9e5cc82c2b9b67d9c0e",
"dist/2021-08-22/rustc-beta-mipsel-unknown-linux-gnu.tar.gz": "f64962ca9b60013ce98e634ebb5207dac14c7b39aca5de37db8a6b3debad7250",
"dist/2021-08-22/rustc-beta-mipsel-unknown-linux-gnu.tar.xz": "a3f8dfb574b3af0ac48011cc7ec69d9f3e89a1994a475c3c6920b0a110db141c",
"dist/2021-08-22/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "6dcce24fa93e66b69495df2d8e9aee15bbba263945fa3dea5cdb1d2c499c9744",
"dist/2021-08-22/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "038d888fea4ff185329b4ac93066167ec7cfd05a3f23be0a2fae5b8eab51d0ac",
"dist/2021-08-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "6a83680ff659d7b9717639d56eb18c230162ee4983ce5ac4aef78b8d9d0829ef",
"dist/2021-08-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "43313c88c1950ec36549f023d8e7b6c6cccb9749159115dad5255451c65f98c8",
"dist/2021-08-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "635544e9035d213ac7e3a82d08b445b2a446119511c219c0ad870f185133f76d",
"dist/2021-08-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "e2fca8f43e37ed2d4896df1429e9b806f02b0e8bdd0f136cf16f606eb1ac15e2",
"dist/2021-08-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "ae8bafeb6423cb270b3a2538db07946d35f2514d5d5116ea085a78e4b80596aa",
"dist/2021-08-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "c8abe082666ea792414943eab46d00727acafa97760e799a4d22ec9ff27a810f",
"dist/2021-08-22/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "b680196dea6eb4bf49afa002e6115645a67c2f7ed6de8ffcc0ace6ed2c193c76",
"dist/2021-08-22/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "1d3cca881398f45c8ef9db64820cd2afb542b55517c9ea66b71955a31fb7fad1",
"dist/2021-08-22/rustc-beta-x86_64-apple-darwin.tar.gz": "493431cd41fae24883877615ca83c1a4e94cafa7e6d6f587dfcce9782c36edaa",
"dist/2021-08-22/rustc-beta-x86_64-apple-darwin.tar.xz": "08b5610cc53cfe64914866b115ca15d184df83cf0c8bb65106380bd875bf62cb",
"dist/2021-08-22/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "17c0e93976b2a83df5f6baabd67412389550f3694268e5478440c8579efbbd18",
"dist/2021-08-22/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "0e736cf5ac25a78e611ea89589a8f6f0eda9891646579fe0a0b8853ab210ee19",
"dist/2021-08-22/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "33f17eb3e95e4b00895c234f5d2d2c9ce19d1d36811bebc3f92bcfeed770a6bf",
"dist/2021-08-22/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "b26e0adcfeb9b95dce5d39c7d34126a405d9705cf58a6ee560b10eeb274b6ef0",
"dist/2021-08-22/rustc-beta-x86_64-unknown-freebsd.tar.gz": "27d6e27acb2d060b59e35789b81779f48a520670ad1590cb46b9862a6be74a63",
"dist/2021-08-22/rustc-beta-x86_64-unknown-freebsd.tar.xz": "39670b9f1865ab74458dded5a9e9f181045c8eb7e7bc82ffc308fcbc5bc26267",
"dist/2021-08-22/rustc-beta-x86_64-unknown-illumos.tar.gz": "d970bcce7178cc0ddb96de50450da71b236ab56861efd399da03f916ce059685",
"dist/2021-08-22/rustc-beta-x86_64-unknown-illumos.tar.xz": "6d6bda8752a6b205ca8e155624f671e716e80c78256f052c22dc2e53c379b589",
"dist/2021-08-22/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "e667282411745dfa982922d139a26058097250c33e83ca955e75b65c6098f651",
"dist/2021-08-22/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "7ed509f918aed5d259479663911427564c066b41487d4550050a9c07096344d9",
"dist/2021-08-22/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "59b3aac5504deea4daf79d5ee90951c3df5247568419a3605c8895698e7a460c",
"dist/2021-08-22/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "941f93fd0a542b9aa6b35fe26a5145085cf758c10b185e9892acf52796efe944",
"dist/2021-08-22/rustc-beta-x86_64-unknown-netbsd.tar.gz": "755987f90f50bbcf9881f62849bfc5749e41d95e5d6b2a35c7fce4218ba3dc60",
"dist/2021-08-22/rustc-beta-x86_64-unknown-netbsd.tar.xz": "09cead4864a49e750d91438149b74fa4c0d4b923efda40ba638b2ca0d3ad97c6",
"dist/2021-08-26/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "17e7cb26d7c13cc14d826966a4b93e9c152b46f2d7081038e8d3385ed5d3ba43",
"dist/2021-08-26/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "85f896275ecef1d491bb8beab54ab13d612d49fb8386b6b61d9121f52fb15e44",
"dist/2021-08-26/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "e948e456f51a9fb983d36d15352d8e7782051e1fb62a4adad2ae973725aa6091",
"dist/2021-08-26/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "d21b59cc2c1706e9c14bf1464b17ed5bd51e2d225e1b3ea53c13d90ae34d4a2d",
"dist/2021-08-26/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "a51b04fa8b159ac5c80ec1db0518cf589a8530820863870173347941a5d3e0e0",
"dist/2021-08-26/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "bbb801bd4ddaeb4d2494039943e8ac746fd41fb625d3c544af2a79587f9e327e",
"dist/2021-08-26/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "8d94c74ac727b381433ff010d6a5b6576d326c88418afb1ee8a67de5731c1bd9",
"dist/2021-08-26/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "da44eae518dc561f89c810d4a5f50da38b938e22542193595be615c147973ee9",
"dist/2021-08-26/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "11e8422a4b4ab386015c54cf488c40297e6b63006989c40b1e4321a325333433",
"dist/2021-08-26/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "b8e835cfd7f32a823ed00d174c4158220b8572c2d76486c60a20cbdad11bb216",
"dist/2021-08-26/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "ff7a412a7923a24cb118979cc772863e6d9844ab6bcc619d9adca6d36b89daf8",
"dist/2021-08-26/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "4fcf56bfbae46ff5cf7c28d787992d5d108231659e447cecbd25035009e0c783",
"dist/2021-08-26/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "4ae574d1aab0e0c191327fa5ad79a4e9367702ef3fd1655661a8c253bf55b7e3",
"dist/2021-08-26/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "8786f646813f5ab71f5786efa6cc14e567a9dd1b2532b34d9d85ee900dafe68c",
"dist/2021-08-26/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "752fdf667b1f4713b6ad3378a15835902fd7fea200c8d37f28a444dc3616b89d",
"dist/2021-08-26/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "43e401e2112120970c4a7e3dacbc5ea631c1816f27db33a28f5b9cc49e4dd5da",
"dist/2021-08-26/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "6935d612513b61092b36bae3a2cb11c29e05cd8773c65aa61b4451dab8cb9f43",
"dist/2021-08-26/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "326177f9fda4923b010fdbefbb9703aee727b4d2871ffb1cc97321c09fc3ff51",
"dist/2021-08-26/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "875d3d7fc0e1cfda7b029656b27436f2b9d332b3f46988dba1cfbfd8d244cd7e",
"dist/2021-08-26/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "4b3e9d27d256cbbe65c0330d557dbcdd6b6144222936680705f9e74deabe80f0",
"dist/2021-08-26/rustfmt-nightly-mips-unknown-linux-gnu.tar.gz": "d26a73c2ccaee81d92980a3cca0508abfce7a02f56f25f3bf9c06e6fcf3aa537",
"dist/2021-08-26/rustfmt-nightly-mips-unknown-linux-gnu.tar.xz": "3f69c9a1161aeb25f03681e43d35388bf75a0e20e086d6e353911aa839fcd294",
"dist/2021-08-26/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "401fbf935e3b06e185f4426a655f2d38e058409921486758f60363f92bbc8117",
"dist/2021-08-26/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "325d89dc02f7aea4803539211c45d8044986d55f7d1331a231b5d0c0ecfe5238",
"dist/2021-08-26/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "3da7ef60aff98439a1c58d504bc62aac1d2cfa29879a28968c5a61b72e9fa33f",
"dist/2021-08-26/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "3aa2757120df94d2660b7e909e4a7d66aa73ca9f9b700231d1f21bdea2b0b5db",
"dist/2021-08-26/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.gz": "74a28139895365cdffdece9920ba6fd31a982cd5620342fbdd653084621b7726",
"dist/2021-08-26/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.xz": "7915f9e15b274e938d5e318544322d233434b6554a25ff063181e7f9cc8a8ef9",
"dist/2021-08-26/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "3b56ab5ce09e8f90ee80ccfcfdbc30f52309547b5123ef474a78cbbd6ca64dad",
"dist/2021-08-26/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "dcb27f9d9f425b81d7ac21025eae60b2e5bbb4cb1e2c21e6970f28e5a574cbb6",
"dist/2021-08-26/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "cb5627d2075b726c4a30b36cdf234371d02f1fe0b545fd50e02b65588b7bbe5f",
"dist/2021-08-26/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "d7d075dc678d545fedfdff220dd6b9b9c91cbf5b58fd9cb486777c596c20c20f",
"dist/2021-08-26/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "fe6af0046c2a6cc8c66d0d51590c7a725115fe785b06bed555c9c68dfaf9819f",
"dist/2021-08-26/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "559b98d646138414c3e0878bdc8245db35c17f9e804ccc0935c4f397672debcd",
"dist/2021-08-26/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "cda6141eff957bf7f7580b093d261d690fd660961722c37b19c390cb4ce85ecf",
"dist/2021-08-26/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "7c4eaccfd5704b0d6e7dfeb6cd70922625df90391f1e27e48bc75f0e79b3832a",
"dist/2021-08-26/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "1d16189f4fe2c5d6fb572e279eab121408c1d85d5fecb6a3f25b00ed748b8b14",
"dist/2021-08-26/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "99be46da8f40418b48261e61a645acd4755c132baf9e2f3a2ca64e853daab9ec",
"dist/2021-08-26/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "82daf2631178e46d94ce2a2718327c5e17da755397cfcddaff4b9d695aa88f3a",
"dist/2021-08-26/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "6288c9cbf5e33c59597d990bf99c9536414bb73aa0bcedf1175dab4c6dd9d188",
"dist/2021-08-26/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "29e13fd9d3eb61ea609bbb55bc5f36df094623f1f1a154d9554212bf4021b8cb",
"dist/2021-08-26/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "c287a80d6388527213d820c22d723fb9e17018425795f499521e7580ed9f6aed",
"dist/2021-08-26/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "2eefa9ae776a7760b3111b39e2c732d2303c4aab2e124cfbef2f7dddc32bdc30",
"dist/2021-08-26/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "a5544207cad0be04393f3a17f8f743340bf468d20a60aa44bbf3b1ea476e54d4",
"dist/2021-08-26/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "b4dfbc422e7b51db45555e6d1b775b214bf633ec6c93303fb7c52e4e25db69e4",
"dist/2021-08-26/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "158c6366adaaaf17d0d40f64a9c8887fc20f1c7600fb31b102fcc3bcbd388221",
"dist/2021-08-26/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "6fda2931d41c4c42b5f59df4a789ff3c2082ff65892e1318439aec555834a34e",
"dist/2021-08-26/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "25a2823ba3668506fe9bb85c1f51d2406b8654c4197d1dc7d88ee19f35e77756",
"dist/2021-08-26/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "2a79c57d33aca5bb6c0cc2497d6853a4df259537ba55acc66460be03c82cc9c0",
"dist/2021-08-26/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "065d95fc9b2d741ba1e8d20b90820a6ad72ce0cb802fd24842aacf01c3a7a589",
"dist/2021-08-26/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "313ea554f824d0176f44406ed70854736eefe94911182396c896ed454a07e6b8",
"dist/2021-08-26/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "23cce7c791cc4f49d5240898803b47f393b5f2f064a3273ffd290a8cf97b7591",
"dist/2021-08-26/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "0416a1a4ad3b9c9e1bf7bd67e49f16e7a4011ebd784966f439ac04a87cb4042f",
"dist/2021-08-26/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "64b29ff6dabc46d124ccf08e8fe351a2d46ed527efe98de36d38c0ec59b226cc"
}
}

View File

@ -1,42 +0,0 @@
# This file describes the stage0 compiler that's used to then bootstrap the Rust
# compiler itself.
#
# Currently Rust always bootstraps from the previous stable release, and in our
# train model this means that the master branch bootstraps from beta, beta
# bootstraps from current stable, and stable bootstraps from the previous stable
# release.
#
# If you're looking at this file on the master branch, you'll likely see that
# rustc is configured to `beta`, whereas if you're looking at a source tarball
# for a stable release you'll likely see `1.x.0` for rustc, with the previous
# stable release's version number. `date` is the date where the release we're
# bootstrapping off was released.
date: 2021-07-29
rustc: beta
# We use a nightly rustfmt to format the source because it solves some
# bootstrapping issues with use of new syntax in this repo. If you're looking at
# the beta/stable branch, this key should be omitted, as we don't want to depend
# on rustfmt from nightly there.
rustfmt: nightly-2021-03-25
# When making a stable release the process currently looks like:
#
# 1. Produce stable build, upload it to dev-static
# 2. Produce a beta build from the previous stable build, upload to static
# 3. Produce a nightly build from previous beta, upload to static
# 4. Upload stable build to static, publish full release
#
# This means that there's a small window of time (a few days) where artifacts
# are downloaded from dev-static.rust-lang.org instead of static.rust-lang.org.
# In order to ease this transition we have an extra key which is in the
# configuration file below. When uncommented this will instruct the bootstrap.py
# script to download from dev-static.rust-lang.org.
#
# This key is typically commented out at all times. If you're looking at a
# stable release tarball it should *definitely* be commented out. If you're
# looking at a beta source tarball and it's uncommented we'll shortly comment it
# out.
#dev: 1

View File

@ -0,0 +1,14 @@
[package]
name = "bump-stage0"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.34"
curl = "0.4.38"
indexmap = { version = "1.7.0", features = ["serde"] }
serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0.59"
toml = "0.5.7"

View File

@ -0,0 +1,204 @@
use anyhow::Error;
use curl::easy::Easy;
use indexmap::IndexMap;
use std::collections::HashMap;
use std::convert::TryInto;
const DIST_SERVER: &str = "https://static.rust-lang.org";
const COMPILER_COMPONENTS: &[&str] = &["rustc", "rust-std", "cargo"];
const RUSTFMT_COMPONENTS: &[&str] = &["rustfmt-preview"];
struct Tool {
channel: Channel,
version: [u16; 3],
checksums: IndexMap<String, String>,
}
impl Tool {
fn new() -> Result<Self, Error> {
let channel = match std::fs::read_to_string("src/ci/channel")?.trim() {
"stable" => Channel::Stable,
"beta" => Channel::Beta,
"nightly" => Channel::Nightly,
other => anyhow::bail!("unsupported channel: {}", other),
};
// Split "1.42.0" into [1, 42, 0]
let version = std::fs::read_to_string("src/version")?
.trim()
.split('.')
.map(|val| val.parse())
.collect::<Result<Vec<_>, _>>()?
.try_into()
.map_err(|_| anyhow::anyhow!("failed to parse version"))?;
Ok(Self { channel, version, checksums: IndexMap::new() })
}
fn update_json(mut self) -> Result<(), Error> {
std::fs::write(
"src/stage0.json",
format!(
"{}\n",
serde_json::to_string_pretty(&Stage0 {
comment: "Generated by `./x.py run src/tools/bump-stage0`. \
Run that command again to update the bootstrap compiler.",
dist_server: DIST_SERVER.into(),
compiler: self.detect_compiler()?,
rustfmt: self.detect_rustfmt()?,
checksums_sha256: {
// Keys are sorted here instead of beforehand because values in this map
// are added while filling the other struct fields just above this block.
self.checksums.sort_keys();
self.checksums
}
})?
),
)?;
Ok(())
}
// Currently Rust always bootstraps from the previous stable release, and in our train model
// this means that the master branch bootstraps from beta, beta bootstraps from current stable,
// and stable bootstraps from the previous stable release.
//
// On the master branch the compiler version is configured to `beta` whereas if you're looking
// at the beta or stable channel you'll likely see `1.x.0` as the version, with the previous
// release's version number.
fn detect_compiler(&mut self) -> Result<Stage0Toolchain, Error> {
let channel = match self.channel {
Channel::Stable | Channel::Beta => {
// The 1.XX manifest points to the latest point release of that minor release.
format!("{}.{}", self.version[0], self.version[1] - 1)
}
Channel::Nightly => "beta".to_string(),
};
let manifest = fetch_manifest(&channel)?;
self.collect_checksums(&manifest, COMPILER_COMPONENTS)?;
Ok(Stage0Toolchain {
date: manifest.date,
version: if self.channel == Channel::Nightly {
"beta".to_string()
} else {
// The version field is like "1.42.0 (abcdef1234 1970-01-01)"
manifest.pkg["rust"]
.version
.split_once(' ')
.expect("invalid version field")
.0
.to_string()
},
})
}
/// We use a nightly rustfmt to format the source because it solves some bootstrapping issues
/// with use of new syntax in this repo. For the beta/stable channels rustfmt is not provided,
/// as we don't want to depend on rustfmt from nightly there.
fn detect_rustfmt(&mut self) -> Result<Option<Stage0Toolchain>, Error> {
if self.channel != Channel::Nightly {
return Ok(None);
}
let manifest = fetch_manifest("nightly")?;
self.collect_checksums(&manifest, RUSTFMT_COMPONENTS)?;
Ok(Some(Stage0Toolchain { date: manifest.date, version: "nightly".into() }))
}
fn collect_checksums(&mut self, manifest: &Manifest, components: &[&str]) -> Result<(), Error> {
let prefix = format!("{}/", DIST_SERVER);
for component in components {
let pkg = manifest
.pkg
.get(*component)
.ok_or_else(|| anyhow::anyhow!("missing component from manifest: {}", component))?;
for target in pkg.target.values() {
for pair in &[(&target.url, &target.hash), (&target.xz_url, &target.xz_hash)] {
if let (Some(url), Some(sha256)) = pair {
let url = url
.strip_prefix(&prefix)
.ok_or_else(|| {
anyhow::anyhow!("url doesn't start with dist server base: {}", url)
})?
.to_string();
self.checksums.insert(url, sha256.clone());
}
}
}
}
Ok(())
}
}
fn main() -> Result<(), Error> {
let tool = Tool::new()?;
tool.update_json()?;
Ok(())
}
fn fetch_manifest(channel: &str) -> Result<Manifest, Error> {
Ok(toml::from_slice(&http_get(&format!(
"{}/dist/channel-rust-{}.toml",
DIST_SERVER, channel
))?)?)
}
fn http_get(url: &str) -> Result<Vec<u8>, Error> {
let mut data = Vec::new();
let mut handle = Easy::new();
handle.fail_on_error(true)?;
handle.url(url)?;
{
let mut transfer = handle.transfer();
transfer.write_function(|new_data| {
data.extend_from_slice(new_data);
Ok(new_data.len())
})?;
transfer.perform()?;
}
Ok(data)
}
#[derive(Debug, PartialEq, Eq)]
enum Channel {
Stable,
Beta,
Nightly,
}
#[derive(Debug, serde::Serialize)]
struct Stage0 {
#[serde(rename = "__comment")]
comment: &'static str,
dist_server: String,
compiler: Stage0Toolchain,
rustfmt: Option<Stage0Toolchain>,
checksums_sha256: IndexMap<String, String>,
}
#[derive(Debug, serde::Serialize)]
struct Stage0Toolchain {
date: String,
version: String,
}
#[derive(Debug, serde::Deserialize)]
struct Manifest {
date: String,
pkg: HashMap<String, ManifestPackage>,
}
#[derive(Debug, serde::Deserialize)]
struct ManifestPackage {
version: String,
target: HashMap<String, ManifestTargetPackage>,
}
#[derive(Debug, serde::Deserialize)]
struct ManifestTargetPackage {
available: bool,
url: Option<String>,
hash: Option<String>,
xz_url: Option<String>,
xz_hash: Option<String>,
}