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"
dependencies = [
"cargo_metadata 0.12.0",
"clippy_lints",
- "compiletest_rs",
+ "compiletest_rs 0.6.0",
"derive-new",
"filetime",
"quote",
"winapi",
]
+[[package]]
+name = "compiletest_rs"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64698e5e2435db061a85e6320af12c30c5fd88eb84b35d2c1e03ce4f143255ca"
+dependencies = [
+ "diff",
+ "filetime",
+ "getopts",
+ "lazy_static",
+ "libc",
+ "log",
+ "miow",
+ "regex",
+ "rustfix 0.5.1",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "tempfile",
+ "tester",
+ "winapi",
+]
+
[[package]]
name = "core"
version = "0.0.0"
dependencies = [
"autocfg",
"hashbrown",
+ "serde",
]
[[package]]
version = "0.1.0"
dependencies = [
"colored",
- "compiletest_rs",
+ "compiletest_rs 0.7.0",
"env_logger 0.8.1",
"getrandom 0.2.0",
"hex 0.4.2",
"src/tools/expand-yaml-anchors",
"src/tools/jsondocck",
"src/tools/html-checker",
+ "src/tools/bump-stage0",
]
exclude = [
use std::iter::FromIterator;
-/// A vector type optimized for cases where this size is usually 0 (cf. `SmallVector`).
+/// A vector type optimized for cases where this size is usually 0 (cf. `SmallVec`).
/// The `Option<Box<..>>` wrapping allows us to represent a zero sized vector with `None`,
/// which uses only a single (null) pointer.
#[derive(Clone, Encodable, Decodable, Debug)]
use std::env;
use std::fs;
use std::io::{self, Read};
-use std::path::Path;
+use std::path::{Path, PathBuf};
+use rustc_data_structures::memmap::Mmap;
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
use rustc_serialize::Encoder;
+use rustc_session::Session;
/// The first few bytes of files generated by incremental compilation.
const FILE_MAGIC: &[u8] = b"RSIC";
/// the Git commit hash.
const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION");
-pub fn write_file_header(stream: &mut FileEncoder, nightly_build: bool) -> FileEncodeResult {
+pub(crate) fn write_file_header(stream: &mut FileEncoder, nightly_build: bool) -> FileEncodeResult {
stream.emit_raw_bytes(FILE_MAGIC)?;
stream.emit_raw_bytes(&[
(HEADER_FORMAT_VERSION >> 0) as u8,
stream.emit_raw_bytes(rustc_version.as_bytes())
}
+pub(crate) fn save_in<F>(sess: &Session, path_buf: PathBuf, name: &str, encode: F)
+where
+ F: FnOnce(&mut FileEncoder) -> FileEncodeResult,
+{
+ debug!("save: storing data in {}", path_buf.display());
+
+ // Delete the old file, if any.
+ // Note: It's important that we actually delete the old file and not just
+ // truncate and overwrite it, since it might be a shared hard-link, the
+ // underlying data of which we don't want to modify.
+ //
+ // We have to ensure we have dropped the memory maps to this file
+ // before performing this removal.
+ match fs::remove_file(&path_buf) {
+ Ok(()) => {
+ debug!("save: remove old file");
+ }
+ Err(err) if err.kind() == io::ErrorKind::NotFound => (),
+ Err(err) => {
+ sess.err(&format!(
+ "unable to delete old {} at `{}`: {}",
+ name,
+ path_buf.display(),
+ err
+ ));
+ return;
+ }
+ }
+
+ let mut encoder = match FileEncoder::new(&path_buf) {
+ Ok(encoder) => encoder,
+ Err(err) => {
+ sess.err(&format!("failed to create {} at `{}`: {}", name, path_buf.display(), err));
+ return;
+ }
+ };
+
+ if let Err(err) = write_file_header(&mut encoder, sess.is_nightly_build()) {
+ sess.err(&format!("failed to write {} header to `{}`: {}", name, path_buf.display(), err));
+ return;
+ }
+
+ if let Err(err) = encode(&mut encoder) {
+ sess.err(&format!("failed to write {} to `{}`: {}", name, path_buf.display(), err));
+ return;
+ }
+
+ if let Err(err) = encoder.flush() {
+ sess.err(&format!("failed to flush {} to `{}`: {}", name, path_buf.display(), err));
+ return;
+ }
+
+ debug!("save: data written to disk successfully");
+}
+
/// Reads the contents of a file with a file header as defined in this module.
///
/// - Returns `Ok(Some(data, pos))` if the file existed and was generated by a
report_incremental_info: bool,
path: &Path,
nightly_build: bool,
-) -> io::Result<Option<(Vec<u8>, usize)>> {
- let data = match fs::read(path) {
- Ok(data) => data,
+) -> io::Result<Option<(Mmap, usize)>> {
+ let file = match fs::File::open(path) {
+ Ok(file) => file,
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(None),
Err(err) => return Err(err),
};
+ // SAFETY: This process must not modify nor remove the backing file while the memory map lives.
+ // For the dep-graph and the work product index, it is as soon as the decoding is done.
+ // For the query result cache, the memory map is dropped in save_dep_graph before calling
+ // save_in and trying to remove the backing file.
+ //
+ // There is no way to prevent another process from modifying this file.
+ let mmap = unsafe { Mmap::map(file) }?;
- let mut file = io::Cursor::new(data);
+ let mut file = io::Cursor::new(&*mmap);
// Check FILE_MAGIC
{
}
let post_header_start_pos = file.position() as usize;
- Ok(Some((file.into_inner(), post_header_start_pos)))
+ Ok(Some((mmap, post_header_start_pos)))
}
fn report_format_mismatch(report_incremental_info: bool, file: &Path, message: &str) {
//! Code to save/load the dep-graph from files.
use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::memmap::Mmap;
use rustc_middle::dep_graph::{SerializedDepGraph, WorkProduct, WorkProductId};
use rustc_middle::ty::OnDiskCache;
use rustc_serialize::opaque::Decoder;
report_incremental_info: bool,
path: &Path,
nightly_build: bool,
-) -> LoadResult<(Vec<u8>, usize)> {
+) -> LoadResult<(Mmap, usize)> {
match file_format::read_file(report_incremental_info, path, nightly_build) {
Ok(Some(data_and_pos)) => LoadResult::Ok { data: data_and_pos },
Ok(None) => {
use rustc_serialize::Encodable as RustcEncodable;
use rustc_session::Session;
use std::fs;
-use std::io;
-use std::path::PathBuf;
use super::data::*;
use super::dirty_clean;
join(
move || {
sess.time("incr_comp_persist_result_cache", || {
- save_in(sess, query_cache_path, "query cache", |e| encode_query_cache(tcx, e));
+ // Drop the memory map so that we can remove the file and write to it.
+ if let Some(odc) = &tcx.on_disk_cache {
+ odc.drop_serialized_data(tcx);
+ }
+
+ file_format::save_in(sess, query_cache_path, "query cache", |e| {
+ encode_query_cache(tcx, e)
+ });
});
},
move || {
debug!("save_work_product_index()");
dep_graph.assert_ignored();
let path = work_products_path(sess);
- save_in(sess, path, "work product index", |e| encode_work_product_index(&new_work_products, e));
+ file_format::save_in(sess, path, "work product index", |e| {
+ encode_work_product_index(&new_work_products, e)
+ });
// We also need to clean out old work-products, as not all of them are
// deleted during invalidation. Some object files don't change their
});
}
-pub(crate) fn save_in<F>(sess: &Session, path_buf: PathBuf, name: &str, encode: F)
-where
- F: FnOnce(&mut FileEncoder) -> FileEncodeResult,
-{
- debug!("save: storing data in {}", path_buf.display());
-
- // Delete the old file, if any.
- // Note: It's important that we actually delete the old file and not just
- // truncate and overwrite it, since it might be a shared hard-link, the
- // underlying data of which we don't want to modify
- match fs::remove_file(&path_buf) {
- Ok(()) => {
- debug!("save: remove old file");
- }
- Err(err) if err.kind() == io::ErrorKind::NotFound => (),
- Err(err) => {
- sess.err(&format!(
- "unable to delete old {} at `{}`: {}",
- name,
- path_buf.display(),
- err
- ));
- return;
- }
- }
-
- let mut encoder = match FileEncoder::new(&path_buf) {
- Ok(encoder) => encoder,
- Err(err) => {
- sess.err(&format!("failed to create {} at `{}`: {}", name, path_buf.display(), err));
- return;
- }
- };
-
- if let Err(err) = file_format::write_file_header(&mut encoder, sess.is_nightly_build()) {
- sess.err(&format!("failed to write {} header to `{}`: {}", name, path_buf.display(), err));
- return;
- }
-
- if let Err(err) = encode(&mut encoder) {
- sess.err(&format!("failed to write {} to `{}`: {}", name, path_buf.display(), err));
- return;
- }
-
- if let Err(err) = encoder.flush() {
- sess.err(&format!("failed to flush {} to `{}`: {}", name, path_buf.display(), err));
- return;
- }
-
- debug!("save: data written to disk successfully");
-}
-
fn encode_work_product_index(
work_products: &FxHashMap<WorkProductId, WorkProduct>,
encoder: &mut FileEncoder,
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync {
/// Creates a new `OnDiskCache` instance from the serialized data in `data`.
- fn new(sess: &'tcx Session, data: Vec<u8>, start_pos: usize) -> Self
+ fn new(sess: &'tcx Session, data: Mmap, start_pos: usize) -> Self
where
Self: Sized;
fn register_reused_dep_node(&self, tcx: TyCtxt<'tcx>, dep_node: &DepNode);
fn store_foreign_def_id_hash(&self, def_id: DefId, hash: DefPathHash);
+ fn drop_serialized_data(&self, tcx: TyCtxt<'tcx>);
+
fn serialize(&self, tcx: TyCtxt<'tcx>, encoder: &mut FileEncoder) -> FileEncodeResult;
}
use crate::QueryCtxt;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
-use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, OnceCell};
+use rustc_data_structures::memmap::Mmap;
+use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, OnceCell, RwLock};
use rustc_data_structures::unhash::UnhashMap;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE};
use rustc_hir::definitions::DefPathHash;
/// any side effects that have been emitted during a query.
pub struct OnDiskCache<'sess> {
// The complete cache data in serialized form.
- serialized_data: Vec<u8>,
+ serialized_data: RwLock<Option<Mmap>>,
// Collects all `QuerySideEffects` created during the current compilation
// session.
}
impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
- fn new(sess: &'sess Session, data: Vec<u8>, start_pos: usize) -> Self {
+ /// Creates a new `OnDiskCache` instance from the serialized data in `data`.
+ fn new(sess: &'sess Session, data: Mmap, start_pos: usize) -> Self {
debug_assert!(sess.opts.incremental.is_some());
// Wrap in a scope so we can borrow `data`.
};
Self {
- serialized_data: data,
+ serialized_data: RwLock::new(Some(data)),
file_index_to_stable_id: footer.file_index_to_stable_id,
file_index_to_file: Default::default(),
cnum_map: OnceCell::new(),
fn new_empty(source_map: &'sess SourceMap) -> Self {
Self {
- serialized_data: Vec::new(),
+ serialized_data: RwLock::new(None),
file_index_to_stable_id: Default::default(),
file_index_to_file: Default::default(),
cnum_map: OnceCell::new(),
}
}
- fn serialize(&self, tcx: TyCtxt<'sess>, encoder: &mut FileEncoder) -> FileEncodeResult {
+ /// Execute all cache promotions and release the serialized backing Mmap.
+ ///
+ /// Cache promotions require invoking queries, which needs to read the serialized data.
+ /// In order to serialize the new on-disk cache, the former on-disk cache file needs to be
+ /// deleted, hence we won't be able to refer to its memmapped data.
+ fn drop_serialized_data(&self, tcx: TyCtxt<'tcx>) {
+ // Register any dep nodes that we reused from the previous session,
+ // but didn't `DepNode::construct` in this session. This ensures
+ // that their `DefPathHash` to `RawDefId` mappings are registered
+ // in 'latest_foreign_def_path_hashes' if necessary, since that
+ // normally happens in `DepNode::construct`.
+ tcx.dep_graph.register_reused_dep_nodes(tcx);
+
+ // Load everything into memory so we can write it out to the on-disk
+ // cache. The vast majority of cacheable query results should already
+ // be in memory, so this should be a cheap operation.
+ // Do this *before* we clone 'latest_foreign_def_path_hashes', since
+ // loading existing queries may cause us to create new DepNodes, which
+ // may in turn end up invoking `store_foreign_def_id_hash`
+ tcx.dep_graph.exec_cache_promotions(QueryCtxt::from_tcx(tcx));
+
+ *self.serialized_data.write() = None;
+ }
+
+ fn serialize<'tcx>(&self, tcx: TyCtxt<'tcx>, encoder: &mut FileEncoder) -> FileEncodeResult {
// Serializing the `DepGraph` should not modify it.
tcx.dep_graph.with_ignore(|| {
// Allocate `SourceFileIndex`es.
(file_to_file_index, file_index_to_stable_id)
};
- // Register any dep nodes that we reused from the previous session,
- // but didn't `DepNode::construct` in this session. This ensures
- // that their `DefPathHash` to `RawDefId` mappings are registered
- // in 'latest_foreign_def_path_hashes' if necessary, since that
- // normally happens in `DepNode::construct`.
- tcx.dep_graph.register_reused_dep_nodes(tcx);
-
- // Load everything into memory so we can write it out to the on-disk
- // cache. The vast majority of cacheable query results should already
- // be in memory, so this should be a cheap operation.
- // Do this *before* we clone 'latest_foreign_def_path_hashes', since
- // loading existing queries may cause us to create new DepNodes, which
- // may in turn end up invoking `store_foreign_def_id_hash`
- tcx.dep_graph.exec_cache_promotions(QueryCtxt::from_tcx(tcx));
-
let latest_foreign_def_path_hashes = self.latest_foreign_def_path_hashes.lock().clone();
let hygiene_encode_context = HygieneEncodeContext::default();
})
}
- fn with_decoder<'a, 'tcx, T, F: FnOnce(&mut CacheDecoder<'sess, 'tcx>) -> T>(
+ fn with_decoder<'a, 'tcx, T, F: for<'s> FnOnce(&mut CacheDecoder<'s, 'tcx>) -> T>(
&'sess self,
tcx: TyCtxt<'tcx>,
pos: AbsoluteBytePos,
{
let cnum_map = self.cnum_map.get_or_init(|| Self::compute_cnum_map(tcx));
+ let serialized_data = self.serialized_data.read();
let mut decoder = CacheDecoder {
tcx,
- opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()),
+ opaque: opaque::Decoder::new(serialized_data.as_deref().unwrap_or(&[]), pos.to_usize()),
source_map: self.source_map,
cnum_map,
file_index_to_file: &self.file_index_to_file,
};
}
+macro_rules! map_from_iter_rand_bench {
+ ($name: ident, $n: expr, $map: ident) => {
+ #[bench]
+ pub fn $name(b: &mut Bencher) {
+ let n: usize = $n;
+ // setup
+ let mut rng = thread_rng();
+ let mut vec = Vec::with_capacity(n);
+
+ for _ in 0..n {
+ let i = rng.gen::<usize>() % n;
+ vec.push((i, i));
+ }
+
+ // measure
+ b.iter(|| {
+ let map: $map<_, _> = vec.iter().copied().collect();
+ black_box(map);
+ });
+ }
+ };
+}
+
+macro_rules! map_from_iter_seq_bench {
+ ($name: ident, $n: expr, $map: ident) => {
+ #[bench]
+ pub fn $name(b: &mut Bencher) {
+ let n: usize = $n;
+ // setup
+ let mut vec = Vec::with_capacity(n);
+
+ for i in 0..n {
+ vec.push((i, i));
+ }
+
+ // measure
+ b.iter(|| {
+ let map: $map<_, _> = vec.iter().copied().collect();
+ black_box(map);
+ });
+ }
+ };
+}
+
macro_rules! map_find_rand_bench {
($name: ident, $n: expr, $map: ident) => {
#[bench]
map_insert_seq_bench! {insert_seq_100, 100, BTreeMap}
map_insert_seq_bench! {insert_seq_10_000, 10_000, BTreeMap}
+map_from_iter_rand_bench! {from_iter_rand_100, 100, BTreeMap}
+map_from_iter_rand_bench! {from_iter_rand_10_000, 10_000, BTreeMap}
+
+map_from_iter_seq_bench! {from_iter_seq_100, 100, BTreeMap}
+map_from_iter_seq_bench! {from_iter_seq_10_000, 10_000, BTreeMap}
+
map_find_rand_bench! {find_rand_100, 100, BTreeMap}
map_find_rand_bench! {find_rand_10_000, 10_000, BTreeMap}
--- /dev/null
+use core::iter::Peekable;
+
+/// A iterator for deduping the key of a sorted iterator.
+/// When encountering the duplicated key, only the last key-value pair is yielded.
+///
+/// Used by [`BTreeMap::bulk_build_from_sorted_iter`].
+pub struct DedupSortedIter<K, V, I>
+where
+ I: Iterator<Item = (K, V)>,
+{
+ iter: Peekable<I>,
+}
+
+impl<K, V, I> DedupSortedIter<K, V, I>
+where
+ I: Iterator<Item = (K, V)>,
+{
+ pub fn new(iter: I) -> Self {
+ Self { iter: iter.peekable() }
+ }
+}
+
+impl<K, V, I> Iterator for DedupSortedIter<K, V, I>
+where
+ K: Eq,
+ I: Iterator<Item = (K, V)>,
+{
+ type Item = (K, V);
+
+ fn next(&mut self) -> Option<(K, V)> {
+ loop {
+ let next = match self.iter.next() {
+ Some(next) => next,
+ None => return None,
+ };
+
+ let peeked = match self.iter.peek() {
+ Some(peeked) => peeked,
+ None => return Some(next),
+ };
+
+ if next.0 != peeked.0 {
+ return Some(next);
+ }
+ }
+ }
+}
+use crate::vec::Vec;
use core::borrow::Borrow;
use core::cmp::Ordering;
use core::fmt::{self, Debug};
use core::ptr;
use super::borrow::DormantMutRef;
+use super::dedup_sorted_iter::DedupSortedIter;
use super::navigate::{LazyLeafRange, LeafRange};
use super::node::{self, marker, ForceResult::*, Handle, NodeRef, Root};
use super::search::SearchResult::*;
pub fn into_values(self) -> IntoValues<K, V> {
IntoValues { inner: self.into_iter() }
}
+
+ /// Makes a `BTreeMap` from a sorted iterator.
+ pub(crate) fn bulk_build_from_sorted_iter<I>(iter: I) -> Self
+ where
+ K: Ord,
+ I: Iterator<Item = (K, V)>,
+ {
+ let mut root = Root::new();
+ let mut length = 0;
+ root.bulk_push(DedupSortedIter::new(iter), &mut length);
+ BTreeMap { root: Some(root), length }
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "rust1", since = "1.0.0")]
impl<K: Ord, V> FromIterator<(K, V)> for BTreeMap<K, V> {
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> BTreeMap<K, V> {
- let mut map = BTreeMap::new();
- map.extend(iter);
- map
+ let mut inputs: Vec<_> = iter.into_iter().collect();
+
+ if inputs.is_empty() {
+ return BTreeMap::new();
+ }
+
+ // use stable sort to preserve the insertion order.
+ inputs.sort_by(|a, b| a.0.cmp(&b.0));
+ BTreeMap::bulk_build_from_sorted_iter(inputs.into_iter())
}
}
/// let map2: BTreeMap<_, _> = [(1, 2), (3, 4)].into();
/// assert_eq!(map1, map2);
/// ```
- fn from(arr: [(K, V); N]) -> Self {
- core::array::IntoIter::new(arr).collect()
+ fn from(mut arr: [(K, V); N]) -> Self {
+ if N == 0 {
+ return BTreeMap::new();
+ }
+
+ // use stable sort to preserve the insertion order.
+ arr.sort_by(|a, b| a.0.cmp(&b.0));
+ BTreeMap::bulk_build_from_sorted_iter(core::array::IntoIter::new(arr))
}
}
mod append;
mod borrow;
+mod dedup_sorted_iter;
mod fix;
pub mod map;
mod mem;
const PERMITS_TRAVERSAL: bool = true;
}
impl BorrowType for Owned {
- // Traversal isn't needede, it happens using the result of `borrow_mut`.
+ // Traversal isn't needed, it happens using the result of `borrow_mut`.
// By disabling traversal, and only creating new references to roots,
// we know that every reference of the `Owned` type is to a root node.
const PERMITS_TRAVERSAL: bool = false;
// This is pretty much entirely stolen from TreeSet, since BTreeMap has an identical interface
// to TreeMap
+use crate::vec::Vec;
use core::borrow::Borrow;
use core::cmp::Ordering::{Equal, Greater, Less};
use core::cmp::{max, min};
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord> FromIterator<T> for BTreeSet<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> BTreeSet<T> {
- let mut set = BTreeSet::new();
- set.extend(iter);
- set
+ let mut inputs: Vec<_> = iter.into_iter().collect();
+
+ if inputs.is_empty() {
+ return BTreeSet::new();
+ }
+
+ // use stable sort to preserve the insertion order.
+ inputs.sort();
+ let iter = inputs.into_iter().map(|k| (k, ()));
+ let map = BTreeMap::bulk_build_from_sorted_iter(iter);
+ BTreeSet { map }
}
}
/// let set2: BTreeSet<_> = [1, 2, 3, 4].into();
/// assert_eq!(set1, set2);
/// ```
- fn from(arr: [T; N]) -> Self {
- core::array::IntoIter::new(arr).collect()
+ fn from(mut arr: [T; N]) -> Self {
+ if N == 0 {
+ return BTreeSet::new();
+ }
+
+ // use stable sort to preserve the insertion order.
+ arr.sort();
+ let iter = core::array::IntoIter::new(arr).map(|k| (k, ()));
+ let map = BTreeMap::bulk_build_from_sorted_iter(iter);
+ BTreeSet { map }
}
}
}
}
-/// Creates a new file symbolic link on the filesystem.
+/// Creates a new symlink to a non-directory file on the filesystem.
///
/// The `link` path will be a file symbolic link pointing to the `original`
/// path.
///
+/// The `original` path should not be a directory or a symlink to a directory,
+/// otherwise the symlink will be broken. Use [`symlink_dir`] for directories.
+///
+/// This function currently corresponds to [`CreateSymbolicLinkW`][CreateSymbolicLinkW].
+/// Note that this [may change in the future][changes].
+///
+/// [CreateSymbolicLinkW]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createsymboliclinkw
+/// [changes]: io#platform-specific-behavior
+///
/// # Examples
///
/// ```no_run
sys::fs::symlink_inner(original.as_ref(), link.as_ref(), false)
}
-/// Creates a new directory symlink on the filesystem.
+/// Creates a new symlink to a directory on the filesystem.
///
/// The `link` path will be a directory symbolic link pointing to the `original`
/// path.
///
+/// The `original` path must be a directory or a symlink to a directory,
+/// otherwise the symlink will be broken. Use [`symlink_file`] for other files.
+///
+/// This function currently corresponds to [`CreateSymbolicLinkW`][CreateSymbolicLinkW].
+/// Note that this [may change in the future][changes].
+///
+/// [CreateSymbolicLinkW]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createsymboliclinkw
+/// [changes]: io#platform-specific-behavior
+///
/// # Examples
///
/// ```no_run
import datetime
import distutils.version
import hashlib
+import json
import os
import re
import shutil
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
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 verbose:
- print("removing", path)
- os.unlink(path)
+ if os.path.isfile(temp_path):
+ if verbose:
+ print("removing", temp_path)
+ os.unlink(temp_path)
def download(path, url, probably_big, verbose):
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"
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
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
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 \
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:
):
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")
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):
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
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)
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')
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"""
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']
-
- if "rustfmt" in data:
- build.rustfmt_channel = data['rustfmt']
+ 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 '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()
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!")
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):
TEST_LOADER = unittest.TestLoader()
SUITE.addTest(doctest.DocTestSuite(bootstrap))
SUITE.addTests([
- TEST_LOADER.loadTestsFromTestCase(Stage0DataTestCase),
TEST_LOADER.loadTestsFromTestCase(VerifyTestCase),
TEST_LOADER.loadTestsFromTestCase(ProgramOutOfDate)])
install::Src,
install::Rustc
),
- Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest),
+ Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest, run::BumpStage0),
}
}
//! 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.
//!
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);
+ }
+}
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;
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!"
- );
- }
- }
}
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)]
--- /dev/null
+{
+ "__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"
+ }
+}
+++ /dev/null
-# 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
--- /dev/null
+#![feature(generic_const_exprs, array_map)]
+#![allow(incomplete_features)]
+
+pub struct ConstCheck<const CHECK: bool>;
+
+pub trait True {}
+impl True for ConstCheck<true> {}
+
+pub trait OrdesDec {
+ type Newlen;
+ type Output;
+
+ fn pop(self) -> (Self::Newlen, Self::Output);
+}
+
+impl<T, const N: usize> OrdesDec for [T; N]
+where
+ ConstCheck<{N > 1}>: True,
+ [T; N - 1]: Sized,
+{
+ type Newlen = [T; N - 1];
+ type Output = T;
+
+ fn pop(self) -> (Self::Newlen, Self::Output) {
+ let mut iter = IntoIter::new(self);
+ //~^ ERROR: failed to resolve: use of undeclared type `IntoIter`
+ let end = iter.next_back().unwrap();
+ let new = [(); N - 1].map(move |()| iter.next().unwrap());
+ (new, end)
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0433]: failed to resolve: use of undeclared type `IntoIter`
+ --> $DIR/issue-82956.rs:25:24
+ |
+LL | let mut iter = IntoIter::new(self);
+ | ^^^^^^^^ not found in this scope
+ |
+help: consider importing one of these items
+ |
+LL | use std::array::IntoIter;
+ |
+LL | use std::collections::binary_heap::IntoIter;
+ |
+LL | use std::collections::btree_map::IntoIter;
+ |
+LL | use std::collections::btree_set::IntoIter;
+ |
+ and 8 other candidates
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
--- /dev/null
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+trait Bar<const N: usize> {}
+
+trait Foo<'a> {
+ const N: usize;
+ type Baz: Bar<{ Self::N }>;
+ //~^ ERROR: unconstrained generic constant
+}
+
+fn main() {}
--- /dev/null
+error: unconstrained generic constant
+ --> $DIR/issue-84659.rs:8:15
+ |
+LL | type Baz: Bar<{ Self::N }>;
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { Self::N }]:`
+
+error: aborting due to previous error
+
--- /dev/null
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub trait X {
+ const Y: usize;
+}
+
+fn z<T>(t: T)
+where
+ T: X,
+ [(); T::Y]: ,
+{
+}
+
+fn unit_literals() {
+ z(" ");
+ //~^ ERROR: the trait bound `&str: X` is not satisfied
+}
+
+fn main() {}
--- /dev/null
+error[E0277]: the trait bound `&str: X` is not satisfied
+ --> $DIR/issue-86530.rs:16:7
+ |
+LL | z(" ");
+ | ^^^ the trait `X` is not implemented for `&str`
+ |
+note: required by a bound in `z`
+ --> $DIR/issue-86530.rs:10:8
+ |
+LL | fn z<T>(t: T)
+ | - required by a bound in this
+LL | where
+LL | T: X,
+ | ^ required by this bound in `z`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// run-pass
+#![feature(adt_const_params, generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub trait Foo {
+ const ASSOC_C: usize;
+ fn foo() where [(); Self::ASSOC_C]:;
+}
+
+struct Bar<const N: &'static ()>;
+impl<const N: &'static ()> Foo for Bar<N> {
+ const ASSOC_C: usize = 3;
+
+ fn foo() where [u8; Self::ASSOC_C]: {
+ let _: [u8; Self::ASSOC_C] = loop {};
+ }
+}
+
+fn main() {}
--- /dev/null
+// run-pass
+#![feature(adt_const_params, generic_const_exprs)]
+#![allow(incomplete_features, unused_variables)]
+
+struct F<const S: &'static str>;
+impl<const S: &'static str> X for F<{ S }> {
+ const W: usize = 3;
+
+ fn d(r: &[u8; Self::W]) -> F<{ S }> {
+ let x: [u8; Self::W] = [0; Self::W];
+ F
+ }
+}
+
+pub trait X {
+ const W: usize;
+ fn d(r: &[u8; Self::W]) -> Self;
+}
+
+fn main() {}
--- /dev/null
+trait Trait<const N: usize> {
+ const Assoc: usize;
+}
+
+impl<const N: usize> Trait<N> for () {
+ const Assoc: usize = 1;
+}
+
+
+pub const fn foo<const N: usize>() where (): Trait<N> {
+ let bar = [(); <()>::Assoc];
+ //~^ error: constant expression depends on a generic parameter
+}
+
+trait Trait2<const N: usize> {
+ const Assoc2: usize;
+}
+
+impl<const N: usize> Trait2<N> for () {
+ const Assoc2: usize = N - 1;
+}
+
+
+pub const fn foo2<const N: usize>() where (): Trait2<N> {
+ let bar2 = [(); <()>::Assoc2];
+ //~^ error: constant expression depends on a generic parameter
+}
+
+fn main() {
+ foo::<0>();
+ foo2::<0>();
+}
--- /dev/null
+error: constant expression depends on a generic parameter
+ --> $DIR/sneaky-array-repeat-expr.rs:11:20
+ |
+LL | let bar = [(); <()>::Assoc];
+ | ^^^^^^^^^^^
+ |
+ = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
+ --> $DIR/sneaky-array-repeat-expr.rs:25:21
+ |
+LL | let bar2 = [(); <()>::Assoc2];
+ | ^^^^^^^^^^^^
+ |
+ = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 2 previous errors
+
// arms whose patterns were composed solely of constants to not have
// them linked in the cfg.
//
-// THis was broken for various reasons. In particular, that hack was
+// This was broken for various reasons. In particular, that hack was
// originally authored under the assunption that other checks
// elsewhere would ensure that the two patterns did not overlap. But
// that assumption did not hold, at least not in the long run (namely,
--- /dev/null
+[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"
--- /dev/null
+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>,
+}
-Subproject commit 09cadcbb62a3529801d0463d9878db3f0b5060c7
+Subproject commit 7a2f1cadcd5120c44eda3596053de767cd8173a2
-Subproject commit 996300f4a061e895a339a909fddce94f68ce7d19
+Subproject commit b73b321478d3b2a98d380eb79de717e01620c4e9