Merge from rustc

This commit is contained in:
The Miri Conjob Bot 2024-02-10 05:02:28 +00:00
commit 3e97b415c3
951 changed files with 14585 additions and 6933 deletions

View file

@ -173,6 +173,8 @@ impl Step for Std {
{
builder.info("WARNING: Using a potentially old libstd. This may not behave well.");
builder.ensure(StartupObjects { compiler, target });
self.copy_extra_objects(builder, &compiler, target);
builder.ensure(StdLink::from_std(self, compiler));

View file

@ -732,7 +732,7 @@ impl<'a> Builder<'a> {
check::Rls,
check::Rustfmt,
check::RustAnalyzer,
check::Bootstrap
check::Bootstrap,
),
Kind::Test => describe!(
crate::core::build_steps::toolstate::ToolStateCheck,
@ -866,7 +866,7 @@ impl<'a> Builder<'a> {
install::Miri,
install::LlvmTools,
install::Src,
install::Rustc
install::Rustc,
),
Kind::Run => describe!(
run::ExpandYamlAnchors,

View file

@ -720,8 +720,10 @@ download-rustc = false
if !tarball.exists() {
let help_on_error = "ERROR: failed to download llvm from ci
HELP: old builds get deleted after a certain time
HELP: if trying to compile an old commit of rustc, disable `download-ci-llvm` in config.toml:
HELP: There could be two reasons behind this:
1) The host triple is not supported for `download-ci-llvm`.
2) Old builds get deleted after a certain time.
HELP: In either case, disable `download-ci-llvm` in your config.toml:
[llvm]
download-ci-llvm = false

View file

@ -90,10 +90,6 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
/* Extra values not defined in the built-in targets yet, but used in std */
(Some(Mode::Std), "target_env", Some(&["libnx"])),
// (Some(Mode::Std), "target_os", Some(&[])),
// #[cfg(bootstrap)] zkvm
(Some(Mode::Std), "target_os", Some(&["zkvm"])),
// #[cfg(bootstrap)] risc0
(Some(Mode::Std), "target_vendor", Some(&["risc0"])),
(Some(Mode::Std), "target_arch", Some(&["spirv", "nvptx", "xtensa"])),
/* Extra names used by dependencies */
// FIXME: Used by serde_json, but we should not be triggering on external dependencies.

View file

@ -72,8 +72,12 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
# Include cache version. Can be used to manually bust the Docker cache.
echo "2" >> $hash_key
echo "Image input"
cat $hash_key
cksum=$(sha512sum $hash_key | \
awk '{print $1}')
echo "Image input checksum ${cksum}"
fi
dockerfile="$docker_dir/$image/Dockerfile"
@ -84,9 +88,6 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
context="$script_dir"
fi
echo "::group::Building docker image for $image"
echo "Image input"
cat $hash_key
echo "Image input checksum ${cksum}"
# Print docker version
docker --version

View file

@ -191,15 +191,36 @@ pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [ast:
cx.tcx.get_attrs_unchecked(did)
}
pub(crate) fn item_relative_path(tcx: TyCtxt<'_>, def_id: DefId) -> Vec<Symbol> {
tcx.def_path(def_id)
.data
.into_iter()
.filter_map(|elem| {
// extern blocks (and a few others things) have an empty name.
match elem.data.get_opt_name() {
Some(s) if !s.is_empty() => Some(s),
_ => None,
}
})
.collect()
}
/// Record an external fully qualified name in the external_paths cache.
///
/// These names are used later on by HTML rendering to generate things like
/// source links back to the original item.
pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType) {
if did.is_local() {
if cx.cache.exact_paths.contains_key(&did) {
return;
}
} else if cx.cache.external_paths.contains_key(&did) {
return;
}
let crate_name = cx.tcx.crate_name(did.krate);
let relative =
cx.tcx.def_path(did).data.into_iter().filter_map(|elem| elem.data.get_opt_name());
let relative = item_relative_path(cx.tcx, did);
let fqn = if let ItemType::Macro = kind {
// Check to see if it is a macro 2.0 or built-in macro
if matches!(
@ -210,7 +231,7 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT
) {
once(crate_name).chain(relative).collect()
} else {
vec![crate_name, relative.last().expect("relative was empty")]
vec![crate_name, *relative.last().expect("relative was empty")]
}
} else {
once(crate_name).chain(relative).collect()

View file

@ -82,7 +82,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
// but there's already an item with the same namespace and same name. Rust gives
// priority to the not-imported one, so we should, too.
items.extend(doc.items.values().flat_map(|(item, renamed, import_id)| {
// First, lower everything other than imports.
// First, lower everything other than glob imports.
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
return Vec::new();
}

View file

@ -4,7 +4,7 @@ use std::fmt;
use serde::{Serialize, Serializer};
use rustc_hir::def::DefKind;
use rustc_hir::def::{CtorOf, DefKind};
use rustc_span::hygiene::MacroKind;
use crate::clean;
@ -115,7 +115,15 @@ impl<'a> From<&'a clean::Item> for ItemType {
impl From<DefKind> for ItemType {
fn from(other: DefKind) -> Self {
match other {
Self::from_def_kind(other, None)
}
}
impl ItemType {
/// Depending on the parent kind, some variants have a different translation (like a `Method`
/// becoming a `TyMethod`).
pub(crate) fn from_def_kind(kind: DefKind, parent_kind: Option<DefKind>) -> Self {
match kind {
DefKind::Enum => Self::Enum,
DefKind::Fn => Self::Function,
DefKind::Mod => Self::Module,
@ -131,30 +139,35 @@ impl From<DefKind> for ItemType {
MacroKind::Attr => ItemType::ProcAttribute,
MacroKind::Derive => ItemType::ProcDerive,
},
DefKind::ForeignTy
| DefKind::Variant
| DefKind::AssocTy
| DefKind::TyParam
DefKind::ForeignTy => Self::ForeignType,
DefKind::Variant => Self::Variant,
DefKind::Field => Self::StructField,
DefKind::AssocTy => Self::AssocType,
DefKind::AssocFn => {
if let Some(DefKind::Trait) = parent_kind {
Self::TyMethod
} else {
Self::Method
}
}
DefKind::Ctor(CtorOf::Struct, _) => Self::Struct,
DefKind::Ctor(CtorOf::Variant, _) => Self::Variant,
DefKind::AssocConst => Self::AssocConst,
DefKind::TyParam
| DefKind::ConstParam
| DefKind::Ctor(..)
| DefKind::AssocFn
| DefKind::AssocConst
| DefKind::ExternCrate
| DefKind::Use
| DefKind::ForeignMod
| DefKind::AnonConst
| DefKind::InlineConst
| DefKind::OpaqueTy
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::GlobalAsm
| DefKind::Impl { .. }
| DefKind::Closure => Self::ForeignType,
}
}
}
impl ItemType {
pub(crate) fn as_str(&self) -> &'static str {
match *self {
ItemType::Module => "mod",

View file

@ -32,6 +32,7 @@ use crate::clean::{
self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, ItemId,
PrimitiveType,
};
use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType;
use crate::html::escape::Escape;
use crate::html::render::Context;
@ -581,22 +582,11 @@ fn generate_macro_def_id_path(
cx: &Context<'_>,
root_path: Option<&str>,
) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
let tcx = cx.shared.tcx;
let tcx = cx.tcx();
let crate_name = tcx.crate_name(def_id.krate);
let cache = cx.cache();
let fqp: Vec<Symbol> = tcx
.def_path(def_id)
.data
.into_iter()
.filter_map(|elem| {
// extern blocks (and a few others things) have an empty name.
match elem.data.get_opt_name() {
Some(s) if !s.is_empty() => Some(s),
_ => None,
}
})
.collect();
let fqp = clean::inline::item_relative_path(tcx, def_id);
let mut relative = fqp.iter().copied();
let cstore = CStore::from_tcx(tcx);
// We need this to prevent a `panic` when this function is used from intra doc links...
@ -651,76 +641,82 @@ fn generate_macro_def_id_path(
Ok((url, ItemType::Macro, fqp))
}
pub(crate) fn href_with_root_path(
did: DefId,
fn generate_item_def_id_path(
mut def_id: DefId,
original_def_id: DefId,
cx: &Context<'_>,
root_path: Option<&str>,
original_def_kind: DefKind,
) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
use crate::rustc_trait_selection::infer::TyCtxtInferExt;
use crate::rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
use rustc_middle::traits::ObligationCause;
let tcx = cx.tcx();
let def_kind = tcx.def_kind(did);
let did = match def_kind {
DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant => {
// documented on their parent's page
tcx.parent(did)
}
DefKind::ExternCrate => {
// Link to the crate itself, not the `extern crate` item.
if let Some(local_did) = did.as_local() {
tcx.extern_mod_stmt_cnum(local_did).unwrap_or(LOCAL_CRATE).as_def_id()
} else {
did
}
}
_ => did,
};
let cache = cx.cache();
let relative_to = &cx.current;
fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] {
if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
let crate_name = tcx.crate_name(def_id.krate);
// No need to try to infer the actual parent item if it's not an associated item from the `impl`
// block.
if def_id != original_def_id && matches!(tcx.def_kind(def_id), DefKind::Impl { .. }) {
let infcx = tcx.infer_ctxt().build();
def_id = infcx
.at(&ObligationCause::dummy(), tcx.param_env(def_id))
.query_normalize(ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()))
.map(|resolved| infcx.resolve_vars_if_possible(resolved.value))
.ok()
.and_then(|normalized| normalized.skip_binder().ty_adt_def())
.map(|adt| adt.did())
.unwrap_or(def_id);
}
if !did.is_local()
&& !cache.effective_visibilities.is_directly_public(tcx, did)
&& !cache.document_private
&& !cache.primitive_locations.values().any(|&id| id == did)
{
return Err(HrefError::Private);
}
let relative = clean::inline::item_relative_path(tcx, def_id);
let fqp: Vec<Symbol> = once(crate_name).chain(relative).collect();
let def_kind = tcx.def_kind(def_id);
let shortty = def_kind.into();
let module_fqp = to_module_fqp(shortty, &fqp);
let mut is_remote = false;
let (fqp, shortty, mut url_parts) = match cache.paths.get(&did) {
Some(&(ref fqp, shortty)) => (fqp, shortty, {
let module_fqp = to_module_fqp(shortty, fqp.as_slice());
debug!(?fqp, ?shortty, ?module_fqp);
href_relative_parts(module_fqp, relative_to).collect()
}),
None => {
if let Some(&(ref fqp, shortty)) = cache.external_paths.get(&did) {
let module_fqp = to_module_fqp(shortty, fqp);
(
fqp,
shortty,
match cache.extern_locations[&did.krate] {
ExternalLocation::Remote(ref s) => {
is_remote = true;
let s = s.trim_end_matches('/');
let mut builder = UrlPartsBuilder::singleton(s);
builder.extend(module_fqp.iter().copied());
builder
}
ExternalLocation::Local => {
href_relative_parts(module_fqp, relative_to).collect()
}
ExternalLocation::Unknown => return Err(HrefError::DocumentationNotBuilt),
},
)
} else if matches!(def_kind, DefKind::Macro(_)) {
return generate_macro_def_id_path(did, cx, root_path);
} else {
return Err(HrefError::NotInExternalCache);
}
let url_parts = url_parts(cx.cache(), def_id, &module_fqp, &cx.current, &mut is_remote)?;
let (url_parts, shortty, fqp) = make_href(root_path, shortty, url_parts, &fqp, is_remote)?;
if def_id == original_def_id {
return Ok((url_parts, shortty, fqp));
}
let kind = ItemType::from_def_kind(original_def_kind, Some(def_kind));
Ok((format!("{url_parts}#{kind}.{}", tcx.item_name(original_def_id)), shortty, fqp))
}
fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] {
if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
}
fn url_parts(
cache: &Cache,
def_id: DefId,
module_fqp: &[Symbol],
relative_to: &[Symbol],
is_remote: &mut bool,
) -> Result<UrlPartsBuilder, HrefError> {
match cache.extern_locations[&def_id.krate] {
ExternalLocation::Remote(ref s) => {
*is_remote = true;
let s = s.trim_end_matches('/');
let mut builder = UrlPartsBuilder::singleton(s);
builder.extend(module_fqp.iter().copied());
Ok(builder)
}
};
ExternalLocation::Local => Ok(href_relative_parts(module_fqp, relative_to).collect()),
ExternalLocation::Unknown => Err(HrefError::DocumentationNotBuilt),
}
}
fn make_href(
root_path: Option<&str>,
shortty: ItemType,
mut url_parts: UrlPartsBuilder,
fqp: &[Symbol],
is_remote: bool,
) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
if !is_remote && let Some(root_path) = root_path {
let root = root_path.trim_end_matches('/');
url_parts.push_front(root);
@ -739,6 +735,76 @@ pub(crate) fn href_with_root_path(
Ok((url_parts.finish(), shortty, fqp.to_vec()))
}
pub(crate) fn href_with_root_path(
original_did: DefId,
cx: &Context<'_>,
root_path: Option<&str>,
) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
let tcx = cx.tcx();
let def_kind = tcx.def_kind(original_did);
let did = match def_kind {
DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant => {
// documented on their parent's page
tcx.parent(original_did)
}
// If this a constructor, we get the parent (either a struct or a variant) and then
// generate the link for this item.
DefKind::Ctor(..) => return href_with_root_path(tcx.parent(original_did), cx, root_path),
DefKind::ExternCrate => {
// Link to the crate itself, not the `extern crate` item.
if let Some(local_did) = original_did.as_local() {
tcx.extern_mod_stmt_cnum(local_did).unwrap_or(LOCAL_CRATE).as_def_id()
} else {
original_did
}
}
_ => original_did,
};
let cache = cx.cache();
let relative_to = &cx.current;
if !original_did.is_local() {
// If we are generating an href for the "jump to def" feature, then the only case we want
// to ignore is if the item is `doc(hidden)` because we can't link to it.
if root_path.is_some() {
if tcx.is_doc_hidden(original_did) {
return Err(HrefError::Private);
}
} else if !cache.effective_visibilities.is_directly_public(tcx, did)
&& !cache.document_private
&& !cache.primitive_locations.values().any(|&id| id == did)
{
return Err(HrefError::Private);
}
}
let mut is_remote = false;
let (fqp, shortty, url_parts) = match cache.paths.get(&did) {
Some(&(ref fqp, shortty)) => (fqp, shortty, {
let module_fqp = to_module_fqp(shortty, fqp.as_slice());
debug!(?fqp, ?shortty, ?module_fqp);
href_relative_parts(module_fqp, relative_to).collect()
}),
None => {
// Associated items are handled differently with "jump to def". The anchor is generated
// directly here whereas for intra-doc links, we have some extra computation being
// performed there.
let def_id_to_get = if root_path.is_some() { original_did } else { did };
if let Some(&(ref fqp, shortty)) = cache.external_paths.get(&def_id_to_get) {
let module_fqp = to_module_fqp(shortty, fqp);
(fqp, shortty, url_parts(cache, did, module_fqp, relative_to, &mut is_remote)?)
} else if matches!(def_kind, DefKind::Macro(_)) {
return generate_macro_def_id_path(did, cx, root_path);
} else if did.is_local() {
return Err(HrefError::Private);
} else {
return generate_item_def_id_path(did, original_did, cx, root_path, def_kind);
}
}
};
make_href(root_path, shortty, url_parts, fqp, is_remote)
}
pub(crate) fn href(
did: DefId,
cx: &Context<'_>,

View file

@ -94,7 +94,7 @@ impl<'tcx> SpanMapVisitor<'tcx> {
/// Used to generate links on items' definition to go to their documentation page.
pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) {
if let Some(Node::Item(item)) = self.tcx.opt_hir_node(hir_id) {
if let Node::Item(item) = self.tcx.hir_node(hir_id) {
if let Some(span) = self.tcx.def_ident_span(item.owner_id) {
let cspan = clean::Span::new(span);
// If the span isn't from the current crate, we ignore it.
@ -199,7 +199,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
if !span.overlaps(m.spans.inner_span) {
// Now that we confirmed it's a file import, we want to get the span for the module
// name only and not all the "mod foo;".
if let Some(Node::Item(item)) = self.tcx.opt_hir_node(id) {
if let Node::Item(item) = self.tcx.hir_node(id) {
self.matches.insert(
item.ident.span,
LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)),

View file

@ -18,7 +18,9 @@
#![recursion_limit = "256"]
#![warn(rustc::internal)]
#![allow(clippy::collapsible_if, clippy::collapsible_else_if)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::potential_query_instability)]
#![allow(rustc::untranslatable_diagnostic)]
extern crate thin_vec;
#[macro_use]

View file

@ -7,6 +7,7 @@ use rustc_hir::def::{DefKind, DocLinkResMap, Namespace, Res};
use rustc_hir::HirId;
use rustc_lint_defs::Applicability;
use rustc_resolve::rustdoc::source_span_for_markdown_range;
use rustc_span::def_id::DefId;
use rustc_span::Symbol;
use crate::clean::utils::find_nearest_parent_module;
@ -33,17 +34,22 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
return;
}
if item.link_names(&cx.cache).is_empty() {
// If there's no link names in this item,
// then we skip resolution querying to
// avoid from panicking.
return;
if let Some(item_id) = item.def_id() {
check_redundant_explicit_link_for_did(cx, item, item_id, hir_id, &doc);
}
if let Some(item_id) = item.inline_stmt_id {
check_redundant_explicit_link_for_did(cx, item, item_id, hir_id, &doc);
}
}
let Some(item_id) = item.def_id() else {
return;
};
let Some(local_item_id) = item_id.as_local() else {
fn check_redundant_explicit_link_for_did<'md>(
cx: &DocContext<'_>,
item: &Item,
did: DefId,
hir_id: HirId,
doc: &'md str,
) {
let Some(local_item_id) = did.as_local() else {
return;
};
@ -53,12 +59,26 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
return;
}
let is_private = !cx.render_options.document_private
&& !cx.cache.effective_visibilities.is_directly_public(cx.tcx, item_id);
&& !cx.cache.effective_visibilities.is_directly_public(cx.tcx, did);
if is_private {
return;
}
check_redundant_explicit_link(cx, item, hir_id, &doc);
let module_id = match cx.tcx.def_kind(did) {
DefKind::Mod if item.inner_docs(cx.tcx) => did,
_ => find_nearest_parent_module(cx.tcx, did).unwrap(),
};
let Some(resolutions) =
cx.tcx.resolutions(()).doc_link_resolutions.get(&module_id.expect_local())
else {
// If there's no resolutions in this module,
// then we skip resolution querying to
// avoid from panicking.
return;
};
check_redundant_explicit_link(cx, item, hir_id, &doc, &resolutions);
}
fn check_redundant_explicit_link<'md>(
@ -66,6 +86,7 @@ fn check_redundant_explicit_link<'md>(
item: &Item,
hir_id: HirId,
doc: &'md str,
resolutions: &DocLinkResMap,
) -> Option<()> {
let mut broken_line_callback = |link: BrokenLink<'md>| Some((link.reference, "".into()));
let mut offset_iter = Parser::new_with_broken_link_callback(
@ -74,12 +95,6 @@ fn check_redundant_explicit_link<'md>(
Some(&mut broken_line_callback),
)
.into_offset_iter();
let item_id = item.def_id()?;
let module_id = match cx.tcx.def_kind(item_id) {
DefKind::Mod if item.inner_docs(cx.tcx) => item_id,
_ => find_nearest_parent_module(cx.tcx, item_id).unwrap(),
};
let resolutions = cx.tcx.doc_link_resolutions(module_id);
while let Some((event, link_range)) = offset_iter.next() {
match event {

View file

@ -18,423 +18,423 @@
"tool is executed."
],
"compiler": {
"date": "2023-12-22",
"date": "2024-02-04",
"version": "beta"
},
"rustfmt": {
"date": "2023-12-22",
"date": "2024-02-04",
"version": "nightly"
},
"checksums_sha256": {
"dist/2023-12-22/cargo-beta-aarch64-apple-darwin.tar.gz": "80a4c4d72f7f436105084047a5806c5665749ecb84ff06bb25e759b56049e610",
"dist/2023-12-22/cargo-beta-aarch64-apple-darwin.tar.xz": "0290ccea9da40123cb5ce9d8c22721e015de77525e267003faaca4a161179da0",
"dist/2023-12-22/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "85c79d51b2d8480343546a6164fea3f1992a4b8de3c6a45a4952b0eb2ee467ab",
"dist/2023-12-22/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "f9174eac9ee6dcd60c24ce5ac5341f16ebb5d704f79bef585e963576a7c7c624",
"dist/2023-12-22/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "76fdafa72f31538fe1747da8ff63a16af91affddc0564a8a3bc1d96bed242466",
"dist/2023-12-22/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "22ae3c0460073037beee67f0bd9d86af0b72c90d9ee6bf14bb6f09e9cbdf2471",
"dist/2023-12-22/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "8731388fe7335a9c31b33ed3bbd5a4e29402e0bfd0ee4b0842974a9416859c8b",
"dist/2023-12-22/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "38f8907aab9795465b8be1d0e38ad3b812ea6ea6e3672773b43e4312677916ea",
"dist/2023-12-22/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "19e329bd134d01c73dd74a10ee63e35782692cb54ee9dd81556b3920fc055b3b",
"dist/2023-12-22/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "b3f4fab444cb5bd462a36f8fb3d90a20042389a5f809bf431dc51645430b6dfa",
"dist/2023-12-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "cdc61bec25e556c6d0ef1150c1a01225eae4e325bce94bd49d43ff1d2b2f4049",
"dist/2023-12-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "082ed52b5bc4e8b4ac16e9a7af81ad774827e41af63532599ee41724b6907378",
"dist/2023-12-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "7624915c4adfb8af8d294f581a3ca4796d53a76f7ccb6546c858e0f785adb252",
"dist/2023-12-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "c224a28f4ffec2b820ac26e21e4bf1e6ecc67f47598e91d34a4e922c21cd967a",
"dist/2023-12-22/cargo-beta-i686-pc-windows-gnu.tar.gz": "d936b84681f2b5fd7da75c99eab6c40ae5464b1ac97733cf5774ae7783fad941",
"dist/2023-12-22/cargo-beta-i686-pc-windows-gnu.tar.xz": "fa2864c6cbbe940a81a497fcb307afbd7c6c0551346676daf2fa0b488dc72489",
"dist/2023-12-22/cargo-beta-i686-pc-windows-msvc.tar.gz": "1b6ed32c7f3b3c0b2f09e43ab04ecf62aa11c778911b860ee0a82cd22fa8ef0c",
"dist/2023-12-22/cargo-beta-i686-pc-windows-msvc.tar.xz": "35cf7cf47a49af4b68171264943adcee5c907d8d4fbb021a0716e10ba946655c",
"dist/2023-12-22/cargo-beta-i686-unknown-linux-gnu.tar.gz": "cc993cf80d125d5ac25210dee1706bd23aa94f949fb94aa22409f434bafe3c35",
"dist/2023-12-22/cargo-beta-i686-unknown-linux-gnu.tar.xz": "60e2bcf98f9969bae7f61987bc30e2358c832033ea98be6f8e08e8b95e8b2409",
"dist/2023-12-22/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "08dbad235465958534802c1609f881561767a63a3373033678caa29b7384e1af",
"dist/2023-12-22/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "cbb79d6e06e12b7bc278d6b3a220380e1d4e863c60eed3462ca4f310b25bf247",
"dist/2023-12-22/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "f25b99291e3d7ed8891ec1196a3bd747cfc755b3c0bb27cbef0fb1aabeecd950",
"dist/2023-12-22/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "0c496d22b1f641ea4bef847a1efe7b69737b0c1d7ca2920ae0a1e87ca99c00e1",
"dist/2023-12-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "9d9800913636d33b9976416fa128d6e734c98978c91fdb846a16c9f2b014a77e",
"dist/2023-12-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "668dda14116c4d54f43653efccdd2a4d211dfea1a08ae5fe02fd69d21b6d9783",
"dist/2023-12-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "ec8b813a83d0999a2181c3e026cc43c0004bcdef621ef07c9741b71ed60858a7",
"dist/2023-12-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "dda9fac6999682ad9bfbeca1cc26b4b083c99558c531e2137bca4b22331527a1",
"dist/2023-12-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "ff1153a92dbdf499e6cbcea37d6be513e1c844d303032f9f1f2c9af45dd43b26",
"dist/2023-12-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "3b8247891ac28674ff4d647da93e267e2400f948b60c870227683463466bc983",
"dist/2023-12-22/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "239486637406a61f1aa25925f82131a31d133972e7926dfa54152285ed83917f",
"dist/2023-12-22/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "7e9d66d61387aa45a1141187806bc181251b1164bbc48e6b52d8770d746507b6",
"dist/2023-12-22/cargo-beta-x86_64-apple-darwin.tar.gz": "3d47e067fedaa2f96cbb33b23315d52d7f5a3379cccca560db312e6cfbbcab39",
"dist/2023-12-22/cargo-beta-x86_64-apple-darwin.tar.xz": "7d7b2239cdf1e946ee97ee81ce69f2fe2f3695a82c0434a4a853218547ee58b3",
"dist/2023-12-22/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "34b195423b12f4253dbcb47fe9bd55e1bdb302c86096ee9f8248e65c218c5ebc",
"dist/2023-12-22/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "d7ebbe5c54ee55ee320e7a57e323d7277afe7c56ec31465fb8012cd436412ef4",
"dist/2023-12-22/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "41c1b391e8f132d8bb18d79e52cf2c7e0443417854943608383073cbb977b1ce",
"dist/2023-12-22/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "f75987c83543c4994dffc7dfb0bfb57390fbbdf79165360d94fd6513b3bf8abd",
"dist/2023-12-22/cargo-beta-x86_64-unknown-freebsd.tar.gz": "56d4ada9b370a6fb3b1a654aebd710194eab8e6a2f7f46df9f191a4ae2d75d9e",
"dist/2023-12-22/cargo-beta-x86_64-unknown-freebsd.tar.xz": "5337096841f04ba7337e8b35df5197fe078832fc417cbe7b4de454c45ae797bc",
"dist/2023-12-22/cargo-beta-x86_64-unknown-illumos.tar.gz": "e1ad1e2044a8b3329349a33a70400491cb79f5e7c847a626c96415f240e6720a",
"dist/2023-12-22/cargo-beta-x86_64-unknown-illumos.tar.xz": "f3546d9d207dc59c67dc8e13ccb0abc3fba14ca5feed4f75e0f3c28e31c9ad5f",
"dist/2023-12-22/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "0497f21e775ab847657c6815275d2a8cf03e4d9b4e75975eaa5eeef7fa84b62e",
"dist/2023-12-22/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "5fc2c06ff83063e7c992729f2dc5dc62771c5e0adeb04b0fb4e12f73b166d29c",
"dist/2023-12-22/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "ce5cdea30636dcb14385ead3ca2d31ded9d3f243234c82b3326551c0cf03d599",
"dist/2023-12-22/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "086662482440baad1b5cb738301a186de41ba6512bae1d77369d65e37c56d818",
"dist/2023-12-22/cargo-beta-x86_64-unknown-netbsd.tar.gz": "b59d49075a3a3fa2aaa8264d3a0c4444400dffe4780bb5efb350d9d558dfe5a9",
"dist/2023-12-22/cargo-beta-x86_64-unknown-netbsd.tar.xz": "bd940fc6505c603a2d0e4743af3aa1df6ef903676f31bf4f06083cf86ba0f4d4",
"dist/2023-12-22/clippy-beta-aarch64-apple-darwin.tar.gz": "42e4c7e85b516b54bc9a92fdcbaf31a280121a6264ffc00bc4330bb3f3d1ef09",
"dist/2023-12-22/clippy-beta-aarch64-apple-darwin.tar.xz": "1858bb5aa212dc68c694e044dd138f58a94ef236e29623b46c275cb9765d1433",
"dist/2023-12-22/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "8ec1c0c20dd3381bb2177e3ff28c777a7de6aff5fa557cf3b4e7ebc6aee7de84",
"dist/2023-12-22/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "cfa8fd15c5b0ff1570a99ea15004f88a8ddd50f6d367082cf6464523355666c1",
"dist/2023-12-22/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "eb81038f1cc56601719a6165da2ba71f357f00ea3380e46f0a1283174efaa9d2",
"dist/2023-12-22/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "dc4c69b81fd186e40b6df3900d0c555214b999f3c1ca5a2697d93503357c7194",
"dist/2023-12-22/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "e2fde1d65c46011d3ce80e1e46e13dcf7b5673009398296cd4126b1e4a9b2cb0",
"dist/2023-12-22/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "b6a422245e574c149b984655f023ca3721c1b5d5a08245292872d86e4b77980d",
"dist/2023-12-22/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "4b3ece564b22857b0741080ce20f190dedbd72fa8c7a284921e4c3c481fdd264",
"dist/2023-12-22/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "bab8dbbf290576dd9f77c9685f5f1bab114215c85c83512d87839a08a3adce6e",
"dist/2023-12-22/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "732adcc6849929efa239a8f5c638fd68324d8f05330b518b8b0804351ae6889a",
"dist/2023-12-22/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "5d726d8da3909f1ca58e1b5b50067205b90bf1a7689c516abce66a14b68fd524",
"dist/2023-12-22/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "c939f4d6675dfbe0ed0d0353fd9a26b0f96f53c0118257d306eb46c883438b8d",
"dist/2023-12-22/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "fa1a7abcdaa6f0347811849dd4dbdcd438d0e47824541b22b1c64fba8c6c1482",
"dist/2023-12-22/clippy-beta-i686-pc-windows-gnu.tar.gz": "c1b16be465960d03658eb10c6d65ba363ecb75d17eee49e2da0d055a97d1ebfc",
"dist/2023-12-22/clippy-beta-i686-pc-windows-gnu.tar.xz": "e5997892281f08da9445b53c564edd678b7b768624bd29ef55a0bfa6a2022cc6",
"dist/2023-12-22/clippy-beta-i686-pc-windows-msvc.tar.gz": "92400c8693ba05a186c6913f69e838cd6668eec60864e5ff857e1da2cd8469dd",
"dist/2023-12-22/clippy-beta-i686-pc-windows-msvc.tar.xz": "550430a61f5e17fc30207b843f99a0f56d6fa07c6c458ab560149027b69599cf",
"dist/2023-12-22/clippy-beta-i686-unknown-linux-gnu.tar.gz": "a99bd3961497a6266e3fc9d4109a0c1304a6759f6d7062a5175afb5459658346",
"dist/2023-12-22/clippy-beta-i686-unknown-linux-gnu.tar.xz": "b8471bfaaf94b61523ac88db9c91c20f67bf24a16367795b2c925abff783fab7",
"dist/2023-12-22/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "601760057229682f332e4b005441111eb1573c7c9a9e286f0699019df3b2d4fa",
"dist/2023-12-22/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "45b7f4d75ed4838d3de0ed8c70d2ce6a248881c609bc4b883a549f11d12067fa",
"dist/2023-12-22/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "6c4fd05f37c0e95046dc87c24734820920a3ec62f3507643f42691ba349f2418",
"dist/2023-12-22/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "0aab738f846ad507138c0a5d40823a0db7d89ff130f24e550f337e085dc3ea8e",
"dist/2023-12-22/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "007d761b7eb5d5ed5911090ac55af2288e9a97cc4affc5ca488ebde7cc3ab0e6",
"dist/2023-12-22/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "ba9ecc14573a882641685cd6570e515a31fa9f3a9973dcef58f3db809b932fa0",
"dist/2023-12-22/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "efcf9a7bc03f8e984c6ab3fa2bc269fa5387168992c9fd2b8ab09bbd7111c6c9",
"dist/2023-12-22/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "1df14e1f3cf785c9cf5477b584fdf11f1f7e12431a5092cc5cdf6c2878bf4275",
"dist/2023-12-22/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "8527bf2c96fba74c09d7b1051616631d0b4e6bace8fe44c8c76f295c9a4eb55e",
"dist/2023-12-22/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "cc58fbe8d4d7d0011045f64025bf75e2042b7967b7fb1f297cfe8a0175197258",
"dist/2023-12-22/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "c1e41ba2a77f6c0d33751b12522310bed37a032fc01947b9d78e8492a2c74ca2",
"dist/2023-12-22/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "a90903f78305533e5315b3dcb26218a91e1733cda5e2fadcada80fe06b3e1a17",
"dist/2023-12-22/clippy-beta-x86_64-apple-darwin.tar.gz": "73839c078dbc472a8c5d87686eb7e09db0030d567079359f9a750a52d1d300b8",
"dist/2023-12-22/clippy-beta-x86_64-apple-darwin.tar.xz": "fbc52b8be57b032d04e885b325deb3c2d61bce1773fdd68e7b0889a1ba9a167e",
"dist/2023-12-22/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "5a618cf8c09bec0e593449648bced16153b6783f98e41d685e5912418710fff6",
"dist/2023-12-22/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "f6a7c30cb183c8cecf22d95487250c121d5fe1cacf2bc4e64bc160b4c4cdd566",
"dist/2023-12-22/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "58b5ae0e2f46d4f7e64491a4ffcc9180e8616cc82b095526546942b0c6e43583",
"dist/2023-12-22/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "aa146f4c9357bd167e4aed6919a1dc780fb57ddb9e83a4332442cb779cc61e1c",
"dist/2023-12-22/clippy-beta-x86_64-unknown-freebsd.tar.gz": "56b1d7fbdc1e47e8a31243cbbac747b1980b61d45f2daf260d49362f1413f3e2",
"dist/2023-12-22/clippy-beta-x86_64-unknown-freebsd.tar.xz": "c0e5ca26067fbd0279a36c03f68e07757817aa2207a69250224f6cb44cb9711c",
"dist/2023-12-22/clippy-beta-x86_64-unknown-illumos.tar.gz": "404cb75b4ae6f2f0f456f77b4e639ddd692c3f47d6f32b168b275dcc999db4c3",
"dist/2023-12-22/clippy-beta-x86_64-unknown-illumos.tar.xz": "b6c156a01ce3f64fd781669c351df169c0c0485b0282ec33d1c541e7990e1ef7",
"dist/2023-12-22/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "6a2e75e81a2678cb97a47e695b74dbbf0737cf615bb94d1679318bcbe77a0fff",
"dist/2023-12-22/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "6273b5b834766a93c2f65a3cf2283bf1669c1dd9b9f1cbbab497ea250532ef43",
"dist/2023-12-22/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "bf4ec57ca170ccb4ab3fc4d42907418011e5dce9ff3fbbfc341e70744e9f0c8e",
"dist/2023-12-22/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "d875bfbdc53bcca521707e3d08fe3b2c2c2dfeab81634c285228ca91278fd659",
"dist/2023-12-22/clippy-beta-x86_64-unknown-netbsd.tar.gz": "43ae50703b81f0fdf726b4790afd539f2d5a1dc56507df2726bee693f121550b",
"dist/2023-12-22/clippy-beta-x86_64-unknown-netbsd.tar.xz": "894acb6cf32ef66d2b79f24ebdbf37dc8d51f36d9ec326a294cbf4be3128ce77",
"dist/2023-12-22/rust-std-beta-aarch64-apple-darwin.tar.gz": "81e9bbeea89702fa3843a5e6bed8b5d3d5bb035d94adb335dfa91d084842fe17",
"dist/2023-12-22/rust-std-beta-aarch64-apple-darwin.tar.xz": "1457fbc52b8e8e6c751b69b6b5b3401bbac86f5aed500885fd86128963e6f8ca",
"dist/2023-12-22/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "e2574432b2b7e8b056f8d9864142be20fb83ec516bd27f7f937c04c2d9648218",
"dist/2023-12-22/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "91fb8193d61c741ee39e1429c8c6e7dc51cb10d5ed1d5f63c4572dd1941f26e1",
"dist/2023-12-22/rust-std-beta-aarch64-apple-ios.tar.gz": "6a1b2b7d583e105daca8294fbd4e3f17bcf345ab536eb4e74962a2efc65c9eef",
"dist/2023-12-22/rust-std-beta-aarch64-apple-ios.tar.xz": "3c54c2a8b24186c5100898a33837141119d77cfd5363acbb8508630752198208",
"dist/2023-12-22/rust-std-beta-aarch64-linux-android.tar.gz": "c9534e00a3b99390a80f23fe580bcca0eb17b8bf5c0731158e8e719ab17bef74",
"dist/2023-12-22/rust-std-beta-aarch64-linux-android.tar.xz": "bbb5bdcd5c698d2b089cf57dc071814aa91e51e76fae5a321b0f3bee837dcbc1",
"dist/2023-12-22/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "c862de6118465dbc356c69c23d1a755243d86945522cb6a87bd25321a5cf1346",
"dist/2023-12-22/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "f8fe6f868c007b3a32b2e20fa397d2aeaa18c1af52bfbf90d181b0dede6235cb",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "3ef167b633f128d5e8b28480169fdaa559c742db7091445b33b7225dd0ab6b17",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "d6027f6826ee84962b4f516204c5e48c4d11a738349d20071d71eb249ab19294",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "2885ebe19250cc078804941bd33d71ac0ba52c8f55c03db0a9d2f7b4b86501b4",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "fe587aec91d8586f5ea93783541b3b1dc005cc9fa92d07a42e93c6cf3570224e",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "b2278c605233768efdbf272b6c1c64b5770330603f0d6ad2e9fc725790c65593",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "40cfe524fc6a97a894d8fab0bcab8a00b72781ed1f8c3273d26e784162959d1f",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "77d9010f59baee9e88fc883cc085f04282b731cdabaf2e3eeb4ccbb8e950c526",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "4b633e678448b03b868dcd038a2a2c4dc78cb600324283b38ed942ee439174cc",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-none.tar.gz": "901d032bf3dac71e52c727264daf42c923adcb12c771f135aef0aaa7784a9c63",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-none.tar.xz": "dd7856ab1d91d92c09f65c8e6fdcada0ffaf63890c656e9bf5e7fe1c5f83cf32",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-uefi.tar.gz": "c64dbbdd967193c3ed53c58e0545a93411e63c83bf0274d40691d1c5e5c58a2c",
"dist/2023-12-22/rust-std-beta-aarch64-unknown-uefi.tar.xz": "bf28490141ed88753548a96615742e7dd13efb6bf7ed98e7cc548409a79100df",
"dist/2023-12-22/rust-std-beta-arm-linux-androideabi.tar.gz": "aa84489eaaf4ae64a56f64a4f7e2240d41ae77e6532bdaf35eb2163632afd051",
"dist/2023-12-22/rust-std-beta-arm-linux-androideabi.tar.xz": "a3cf5b44498c85fbd8f66a776e5947e9b552a8b8110b19b4611ff042d040294f",
"dist/2023-12-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "aa4f3fa1994f51228853c8abd1080ac0804d7fe782a2c9a533427555c1ed5db7",
"dist/2023-12-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "72340fd4f0110ef21cea8e7a54182cf65b616e6c4834624b7971ad8a9c00b4b2",
"dist/2023-12-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "5b0b9392fcf9673e69954141470bd4eca00867a303b4f24354f27cf09da1cb8c",
"dist/2023-12-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "326ea10b82742012a648cf5eb9eb7b6e09087a324e3ff9955df5031233f45d6d",
"dist/2023-12-22/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "a7b7a2cde45cfc3d4d74031c36dcb8ea8214f4517e96b5a09bc46f898faf967e",
"dist/2023-12-22/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "b178e41c2ad6089e3448209cab7808e93aba7700aa3571f062dcdab74e4753b9",
"dist/2023-12-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "0de36da3bec6c34a6e56162b92f88b42ed76e596459a6d1416748b9fa8e8225e",
"dist/2023-12-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "381006c411b222254b5bc55302096678a47fd085de06615558dce5085da47f22",
"dist/2023-12-22/rust-std-beta-armebv7r-none-eabi.tar.gz": "464271fe1c2fe699167afbfe9cdb2ed2bb3a38671d616f6f28d6b7fd4fc72cf4",
"dist/2023-12-22/rust-std-beta-armebv7r-none-eabi.tar.xz": "13dc946ac5dd45104c51010bc8a0bf5af64d549cf6b59f8b8b0ac9b06dc5d0f1",
"dist/2023-12-22/rust-std-beta-armebv7r-none-eabihf.tar.gz": "2e01997df04b9635d840ca177e4ef379232955cc586e2196c26ea1e18b66f883",
"dist/2023-12-22/rust-std-beta-armebv7r-none-eabihf.tar.xz": "a11c1e8c52ba653e5c58baf886b6b1383c622632959d09321ba1dddc2a91caf2",
"dist/2023-12-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "b036abe1c19e3f86b80ee670196194ccddf0bfa5261d4ba9fc7994aecb5a487d",
"dist/2023-12-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "a9b90e4b43353feba58dfab424ae36441077fbb6b8469bc071c058f0bd85aa81",
"dist/2023-12-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "0faac13a81d60fd9315c6ea6c929b1fcb9366b23119b658dc05f10a0b4b2e2b6",
"dist/2023-12-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "62023710833973795681275bf34c45a309327f6e76934603c58b07f204e67a20",
"dist/2023-12-22/rust-std-beta-armv7-linux-androideabi.tar.gz": "f48e6eb32ae56fb09a9860f529cb65ca4168d068b6bfa6b1b3164590628ef635",
"dist/2023-12-22/rust-std-beta-armv7-linux-androideabi.tar.xz": "dad3d32a6314f7c9de8003476f9667d19f452a331e6363bf25c2ed255a8b0063",
"dist/2023-12-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "b8d045889b709783387752e6275c6818c353431bb7b9599e9aa88c6e373072c8",
"dist/2023-12-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "4750a55e19b27b34e59daa2d1b0f6655ba9d8c491780c785a7adbcc160eda425",
"dist/2023-12-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "829c608b0f7f4f6bf73688a30e51d69228b69a9487137751e0bf641f7e8e227a",
"dist/2023-12-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "4e4d1b1d10b1b7931e2a801cc3d3edb68c91d5f58baaf99fa2f88b9174f2b294",
"dist/2023-12-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "cab9b7f30fd074005c59ab5dd4d59c498367671373f5662047c8e16c19236141",
"dist/2023-12-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "b281e7c3a32523de34c2f7ed646d19f4f32b1db905a222aa1301f8bc57e312f2",
"dist/2023-12-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "ebed7143f8cbbf5eb2b99328c6246ecdc51905a90c4c832a13d76f6467e2014a",
"dist/2023-12-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "6c06418750cabc38f46e434890c2422df9be5177ed1f4b04dc7f67e45cad307b",
"dist/2023-12-22/rust-std-beta-armv7a-none-eabi.tar.gz": "06d20a34ef000ab381025c0458bd327d3a2bb13a77f3485334cdb63e51a7354f",
"dist/2023-12-22/rust-std-beta-armv7a-none-eabi.tar.xz": "741edc509d401328adcf462aba08744614ad655fa42f89c9818aa1dc715e2d3e",
"dist/2023-12-22/rust-std-beta-armv7r-none-eabi.tar.gz": "0a5c38d1a7a9d653e32750a5f600f1887422d4e90360b6f1d98df45084436822",
"dist/2023-12-22/rust-std-beta-armv7r-none-eabi.tar.xz": "ae960df5549284a7976129da79916287d84f1d9dece2bb8ada6a3f3cc3246509",
"dist/2023-12-22/rust-std-beta-armv7r-none-eabihf.tar.gz": "9280fff8012234559ad644edbe9827c2ef6931d95fa96b5f6a4aa7321215f5d2",
"dist/2023-12-22/rust-std-beta-armv7r-none-eabihf.tar.xz": "3bed6d2a89baf609089c431e73d36b73417541f63c8f2bbb190bdf706cd85e93",
"dist/2023-12-22/rust-std-beta-i586-pc-windows-msvc.tar.gz": "b8bb7b950134f5e3ba3257ffc55d2b0e4b483955e74f6a146017c1c818359ab4",
"dist/2023-12-22/rust-std-beta-i586-pc-windows-msvc.tar.xz": "3c3b4771cd51159d35cf5de21e9bf625453972a53207ca3e6a027901b3eeb7c8",
"dist/2023-12-22/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "ed89e574db830d882f1f12f9b570bbc5f4c89776808ec05cbfcb498eb947e6d2",
"dist/2023-12-22/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "8c32678710cec0971aa6f740cbb525c0c174f6552d181466b7d49d5822d671c5",
"dist/2023-12-22/rust-std-beta-i586-unknown-linux-musl.tar.gz": "2ebc2381b980637844cca7be78a01d204472328897bb02c28b8b5c32bd8d20bc",
"dist/2023-12-22/rust-std-beta-i586-unknown-linux-musl.tar.xz": "df48e6af6cc9df2fba7af56b4cccd07e53a0030de964c11e83b7cdaff1bff4f1",
"dist/2023-12-22/rust-std-beta-i686-linux-android.tar.gz": "25e6cadd083ba7f02525e411677ebf8470bebae19c0f5fdba453140ddf97a3d1",
"dist/2023-12-22/rust-std-beta-i686-linux-android.tar.xz": "bdc722479c73b6fcc6ba401d6f747acbfbdebb074e911bd44a20c8c3ce8192b3",
"dist/2023-12-22/rust-std-beta-i686-pc-windows-gnu.tar.gz": "6a8b46606ecb46d16f2d45ae82faaf155ad617b1b81259eed93b77a267b5265c",
"dist/2023-12-22/rust-std-beta-i686-pc-windows-gnu.tar.xz": "97c58f4e4cee06dd38ad9e3a56ce505434ee77f0f0db30432d04739d301a194b",
"dist/2023-12-22/rust-std-beta-i686-pc-windows-msvc.tar.gz": "1012704d42aaaddbf0679013ea578245e88200afd55d1d510dbe58bdd14b8ef9",
"dist/2023-12-22/rust-std-beta-i686-pc-windows-msvc.tar.xz": "cdb291df9fc41e038b38a3a421b791a2c39be3bc9686c5d6e93cbaef95c2ff6b",
"dist/2023-12-22/rust-std-beta-i686-unknown-freebsd.tar.gz": "20df3466ef1a82ca986a3239efba9d984535c64d5663f2b3b92b9d6ec2972b25",
"dist/2023-12-22/rust-std-beta-i686-unknown-freebsd.tar.xz": "6a63dcb9f7312432c6bf290dc3fea10d56a17472cab65c7d82fde30c800d8b5e",
"dist/2023-12-22/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "8d3ae5e37ab866b93bee661773301956d8e6e2294910d0ff04f782f2c7271dd6",
"dist/2023-12-22/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "9963bba2883125aded9c6639dda498c3effd574fa032d2268455948df3243979",
"dist/2023-12-22/rust-std-beta-i686-unknown-linux-musl.tar.gz": "64e13948dc71571be5c3a4e367d961bcc0bc38167680e86a55b2d1357a45b7ba",
"dist/2023-12-22/rust-std-beta-i686-unknown-linux-musl.tar.xz": "ca54983531703de8f7350e00bad2cde13dc996d9de1c0ca1728b50a015dcb344",
"dist/2023-12-22/rust-std-beta-i686-unknown-uefi.tar.gz": "a4e3c395607d9ca189c130e371c49ba0a08d1974c56c656a23870d0ca08f0cf7",
"dist/2023-12-22/rust-std-beta-i686-unknown-uefi.tar.xz": "20e6ceea5246322840b3fc76b01b16ef32d829ae4e587a052512c39c3c3babca",
"dist/2023-12-22/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "6e4dd7fa56112a879917ea24bfbd45dca625ee812908867e427f23d56deb910b",
"dist/2023-12-22/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "23862a72211645d29557d3a1dda63948335d15a9796c139a0676124905e72906",
"dist/2023-12-22/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "6abd7c64f58bbcbf04b643a9787f0fef1fe80b89b82143b6251b57afa560cff0",
"dist/2023-12-22/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "53fa4d33241b73653523810e441bed53dcac8c3fb7b7de88c125cb8ab8eb66df",
"dist/2023-12-22/rust-std-beta-loongarch64-unknown-none.tar.gz": "bb94b1d2391e11f268c0e4c127c06b356e9d79aaa6c68862dd7f97a8fd756e61",
"dist/2023-12-22/rust-std-beta-loongarch64-unknown-none.tar.xz": "663d531002d8be8e61fe4b9353a53b3a44056056b18bbd76749762a40416f7fa",
"dist/2023-12-22/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "3a25dd389b4501e9fe76057b70cb120e1d1d3caacdce82abc834297c487e50ce",
"dist/2023-12-22/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "6be12fd4e79600805cd6d04a5bd1d236dd7f12832d4407d3fcd72ce6bd84101f",
"dist/2023-12-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "6edc5d7fb15d71cbd097a09eb264b92f5b1e55f7ef0426c5c8399731f4ebb70d",
"dist/2023-12-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "beb17c9ca9e789ced8c4046135cde5b613a0b41c9b5aeefb3b7ee5d25701add6",
"dist/2023-12-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "6f13eb2dac5f4d59dbe44a4d862f94f763fce0bf4ea0f128c0006c04b922f294",
"dist/2023-12-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "75e629ca2f90c7e8a78fc16d13cab337816feba3e30564e26b3d38f13b7dffd0",
"dist/2023-12-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "e2ffac9803e2c604c56649096e734cff0a53632883c05cb9f1fd79f6ce420162",
"dist/2023-12-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "85e0193a7bfa284ac4dae84f4079605ba5c2f7c7c2e4f57ac74721aff44d05b8",
"dist/2023-12-22/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "41c57fa6eafdc2bc4389da8257b57e48af4250377b02760d06ebc38c83086534",
"dist/2023-12-22/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "02d46a445f52d078982866ee9430f8020e15d82f58d8f1edfedcd2f0ade51f36",
"dist/2023-12-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "6fdfd4e5ce8dc13cbce7cfb1543dafb54e80ffee0ed40935c3734787519a9673",
"dist/2023-12-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "5a645c8703ba10256605770ffdbb8abbef62746171f19edbbc069d02be501529",
"dist/2023-12-22/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz": "0cdefa18bc524ef66ddabf83fa2efceced02ad1a5271c9d95f91ec01178055e7",
"dist/2023-12-22/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz": "388dc6fba431953f581388d95cd860224e2d1203811ec86e66aca391650ce053",
"dist/2023-12-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "b3f756e69c0c1f257869cfa6ef239368a512c81b59c18a69851b2e5a73ec484d",
"dist/2023-12-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "61d020bea165d8abc361335e393c2c3bb1e59b6fdb0f6f65326392ec7dc3ea35",
"dist/2023-12-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "94e83a4ba2d141e9fc0d824a6f5e077796fd53b7b32578a1bf6e63cda1f9ee4d",
"dist/2023-12-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "9679bfb1664e6d14882e68940fe8960773f56f4867904a3259189f9eb96952ca",
"dist/2023-12-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "807b24b0568e83cc807e29ae6062a766f72ef48e12f9f257d78f6db4b9ee5621",
"dist/2023-12-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "d3898d851c5f728a9894e7755d0b6ff06133823b1773e5c80b29155f6e1152a6",
"dist/2023-12-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "9ecdd32e65c85130f8a1c82c8fd9d613a4c59b1e4fafd01771089a052d4a481c",
"dist/2023-12-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "a6b5ef2065cd5cef17e48791dae08090b755c00caca4efc1aa5eac9c2783e92e",
"dist/2023-12-22/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "df756fb3868a3ed347a92df37fc4aac696560d645696d5d86a15d84bde257546",
"dist/2023-12-22/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "777dac6ecbefe1e266c7bfd04644f428ae25318e80137a36d404009442ea208e",
"dist/2023-12-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "6802baa472bbf3f766346f24cf7b001cf87ea7f974bd1e1abdcc56b4c2b39bdd",
"dist/2023-12-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "5db8e7c4904c55a5d362669375bf72482e27042b7a156bd8b9d1c322b2bf521a",
"dist/2023-12-22/rust-std-beta-sparcv9-sun-solaris.tar.gz": "0ddd12279d34cc6190e0b1e163cee51d94be809fefa4adf801fea0f217a3519a",
"dist/2023-12-22/rust-std-beta-sparcv9-sun-solaris.tar.xz": "96ed998c6f254c9a5fe560474480db553cd7428cca65ba9a7732136bce191e48",
"dist/2023-12-22/rust-std-beta-thumbv6m-none-eabi.tar.gz": "aa36baeedb2b567f75a0fa550f2ebb507f135d4fe784343a576216237a87d643",
"dist/2023-12-22/rust-std-beta-thumbv6m-none-eabi.tar.xz": "0792a2de23b8c8e552565bcf691ca604760d5201ae247ec14122df11d3819f30",
"dist/2023-12-22/rust-std-beta-thumbv7em-none-eabi.tar.gz": "93a045ef6b38b1de7347880d299dcaf6f721af301fc811e47388b0b94c6290a6",
"dist/2023-12-22/rust-std-beta-thumbv7em-none-eabi.tar.xz": "c6f13b394ad21bd6058fae6845543d5f265e8124fd43ce16885800c4bd62a370",
"dist/2023-12-22/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "8ee5dc194cfd20626671d6b7924b68246d4cc820ca669d8fa9778086b043c3dc",
"dist/2023-12-22/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "f702b3ece0c74a4391e4ce954456babba8d170a1ffff438222a9bfd22df139a3",
"dist/2023-12-22/rust-std-beta-thumbv7m-none-eabi.tar.gz": "3cd3bc99d559a56ac8795c3602c59652877bac85e0a847c981c9ec2b1a86039b",
"dist/2023-12-22/rust-std-beta-thumbv7m-none-eabi.tar.xz": "0d8132f6922844c017fa0c0c3ec463e4a55e3fed7603fb2e8374ecf5c1405e52",
"dist/2023-12-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "ab1bc71bd1b00c0d38a3a0a3be1e5fc5a494219d2d37181da53b042b3b896c67",
"dist/2023-12-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "5cd28af392967e42e43f51233637ff690a524d840c50a328d5d52c594977b316",
"dist/2023-12-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "647b9db01306e225ee1867e194531028215a9fdb02b3f8713c07c39dd41d0c85",
"dist/2023-12-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "9a6ee652c9e15708f2aab76a20918f414875a8a52323a49d727b58aacc22d1f0",
"dist/2023-12-22/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "c16e452e889c9d56d417c871ac4f9290275df11563d458e1abc52e4ac3db0414",
"dist/2023-12-22/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "23a74836c303dc91e6ed9fd2078e130184ac19ac230946bd95e59c53666534bf",
"dist/2023-12-22/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "c8d01ed9cfe9938ed078e3f14ef9f4fa5367534ebe115f243fee8095ef3c174f",
"dist/2023-12-22/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "a24e99a9d45b19db342d5c5f903ad90a27be9c996278b76823121fd09d5a298c",
"dist/2023-12-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "e417661f5c42593e75b09b4a3531965e46f5dbd631809d6364e59d47a894b1c3",
"dist/2023-12-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "081ec9d8504af85ce93bc60ae5f3eaad8bd06864b084a97911e126564720b3f7",
"dist/2023-12-22/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "1df5182c5103454eb69f05b3e6c9aefe1374e43659f3e4cf68f0ac07052670eb",
"dist/2023-12-22/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "863278bd1a5281e6b04232e35df48a1dac7e909d3b51922cb328304cb6db9af2",
"dist/2023-12-22/rust-std-beta-wasm32-unknown-unknown.tar.gz": "6d80b9f8875f677a8e472c431d6df15babba2a9af62622da5a073ca9da467f69",
"dist/2023-12-22/rust-std-beta-wasm32-unknown-unknown.tar.xz": "cc9bf2bd9db87859e17ffd0b9a3ffb8c073e521fc035b75639a7e77fd04a210b",
"dist/2023-12-22/rust-std-beta-wasm32-wasi-preview1-threads.tar.gz": "7b2db2cb1fb7b35cecee218780fdc223464522bf4e5ac0e3c3342396bea77755",
"dist/2023-12-22/rust-std-beta-wasm32-wasi-preview1-threads.tar.xz": "ed893747e7165c97b2a2abfe4793493056cda613040eb5783ba0c4a57560f42c",
"dist/2023-12-22/rust-std-beta-wasm32-wasi.tar.gz": "cfd98053e598d830055a35702de43866b6c94b48a36c63c1683a302482bc4cc4",
"dist/2023-12-22/rust-std-beta-wasm32-wasi.tar.xz": "f57bc02b197d8f4c0d119f4ecaed6c405cc85bac7d00a55f2dc39e97ebc8411b",
"dist/2023-12-22/rust-std-beta-x86_64-apple-darwin.tar.gz": "70405814aefa163d60eabc777b882233797d075ef5a3052285a6aa4acf7c9c0a",
"dist/2023-12-22/rust-std-beta-x86_64-apple-darwin.tar.xz": "c26043ff5bb98223083aa58f659f3ef069f5cc97e5f3c1a62664197e3d8bae66",
"dist/2023-12-22/rust-std-beta-x86_64-apple-ios.tar.gz": "37a2b083652163adfd848872c7b42570ad6fb365ec679a1c89a8248c517021a4",
"dist/2023-12-22/rust-std-beta-x86_64-apple-ios.tar.xz": "cbba44d048a5c48dd4162dced5414eca2416047f2387708e46a2045553a45fa4",
"dist/2023-12-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "17e93708f7c0b4328d24db2ad2a82c3001c1bc03def829b7e182e5407fe74b82",
"dist/2023-12-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "761b39d8ab6b9061c0afd4fa2faaa88c7cda6322d615e57863b51a5a2826d70e",
"dist/2023-12-22/rust-std-beta-x86_64-linux-android.tar.gz": "f45d09e9a6c383c6cf9cff99d0046639d26636be78e194354e951fa99388e479",
"dist/2023-12-22/rust-std-beta-x86_64-linux-android.tar.xz": "fe323b71cfbb300f881d05879d03491aca507a644b261c16f148690dbb20a01e",
"dist/2023-12-22/rust-std-beta-x86_64-pc-solaris.tar.gz": "0dce2b6572bde41461086c6394121de7b97329f8192562684954542baef1ff05",
"dist/2023-12-22/rust-std-beta-x86_64-pc-solaris.tar.xz": "164fa2c995df0d6446c218e037025de1b225d92a51155b5b54328f67493e8202",
"dist/2023-12-22/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "848e55f4583bd589ae457d37b8d7367adafc24b87c35a08065114b3acdd731f9",
"dist/2023-12-22/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "c900770454c026b80f9b80bb745a84381f91492d552fcc7ba013e5fd46b2a63d",
"dist/2023-12-22/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "577f8db6e8654e9f3d97c83bbfa2eaa89fb0fe8c9362b976b9796297d189b6a8",
"dist/2023-12-22/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "5d2523bb1b31b4b43c527b8307ac8e00ad7e957fa652fe0628cb8e6796404d20",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "5a185ac2058969ed6aedbd864cf7037fe999eacfb9e11eb21f89696d6341741c",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "7f6e73e0cc5fae9b9e9142427decf8c4d48289033412d452a40c1a345f4311a8",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "c1974528eeea3346e070192f3729fbcc4fc9d6bbdb0c0b9ba73763758a695124",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "b4da6ab7e3bef63c2f381f7506ff0f65f302e0ed14d4f78016968b0cff3a5f5f",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-illumos.tar.gz": "3f50aa342f03ad5235112560fe0f3c64f5139d09291e3ab6859d8169ff43d631",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-illumos.tar.xz": "799eeb21df5ff213c8ec1f6250497665924b865b34d9c1a5f914eed48255278c",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "ac88a7247dec36da73d30cb58c067cd1bd6c5bc70e5820d031963fced0907c28",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "3de39c55f71a295ff38bce9843965309a40dbfe1c888f13dbde3935d26ebdfc0",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "eeae5e12254e54c87ed818e8449c2489717d1c3c25858c6e8a1a7502e57172e0",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "0d54e6882ffce573f70954d98e1f0c9f0758c5d6262e546ed95c055798d26bef",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "da056f4b1d8544382b90cae7061be549b2e06e3e880feb9d788200c022ab297c",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "f340687b51519830a1e566c84c0114581c817ac32e80f90b8baf0fbe960fdd5d",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "6ea1fedb7db6f51b79164ad39246dc2c86f743346feb760f4835c870be3931b2",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "7fe78fc5dfcb2d85b521dba2c9640233615fab04a8a1b8b27a2e0efabc5b5b60",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-none.tar.gz": "8eb08022fd4b78b50784ab9671a81b69c899ff2e73d9ae08b6ea44ed018b2c8a",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-none.tar.xz": "6ab096ba0bad97de603be50a05e16a33bffbaf4a97853d9f838721075b18aab8",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-redox.tar.gz": "84632635271947ff93b1afdd35779e7c307182d964e3b2aff60e57c0ab02a9eb",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-redox.tar.xz": "b21150ef965377a699410a0350395e0daf57e3ab8a3d90654482b17960dfd26b",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-uefi.tar.gz": "7a703ac3b26a1ec21a64f6517f03938e458db5d46977f02f9359febe7e3e4a79",
"dist/2023-12-22/rust-std-beta-x86_64-unknown-uefi.tar.xz": "83607ae59dddf457d655a2e60ad6d7b500a144fec4d41a7f684555204754e2d2",
"dist/2023-12-22/rustc-beta-aarch64-apple-darwin.tar.gz": "4988d34a6c048ee278f0d675e05260a0ab7f635c09c8ac6964ea97dcd244b9a7",
"dist/2023-12-22/rustc-beta-aarch64-apple-darwin.tar.xz": "a5a218eea6a3edf9b8af70046525fa6259ebf391d6e91f0630f6ae441a227a82",
"dist/2023-12-22/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "0980f8dfdc522146433cab04f2b83378b0c5bdb632cd02e280469ddff02e8bbf",
"dist/2023-12-22/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "25cf2c04a79313040860831dcce67a123ee362e09bb185a16af171163ec8b087",
"dist/2023-12-22/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "e21656abc9b9111baf5fdf9aebbf29b4ac8123c163dfb979b5f047c530020f29",
"dist/2023-12-22/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "3087de6766ffa175dbf7c53153b24cbc29db1fccc06170fd70bd3dc3a97bae62",
"dist/2023-12-22/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "e2464b82f2e1c4450d4f9f6fca8c5d2315e6227651d7485cd487d39fbe7f940c",
"dist/2023-12-22/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "9d4909db94be068ef943eba3709195a028e3928198a87f38e72a6fe013e592db",
"dist/2023-12-22/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "9217ecb54faf8c2964476c3c7a9ec6955b276c4c5b89e5ff13d76fe4863ba8ef",
"dist/2023-12-22/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "fad7556560de459c4cbb59071a35746ee520ca15b5972e926039d46847a47888",
"dist/2023-12-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "69d94023fd5d8a48873ecde6892ee1be354fb56a91c9bc16b32d7b8bf090ad07",
"dist/2023-12-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "14ab98c13452b8b7e5ba8853b957355487c61f0a89d385c2ec8d16d8fec382aa",
"dist/2023-12-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "85190846421ade8edb5da369977598641bfac215754bdbdceccb181adf49d2b4",
"dist/2023-12-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "5b0de94607e7e1192463dd1c8615cf035040cf1a51ccf4d08459f659e14aebb4",
"dist/2023-12-22/rustc-beta-i686-pc-windows-gnu.tar.gz": "dfb48dd8d18099b63eab2e0f6e01dd520e6d137725596af611d68092f7d2228b",
"dist/2023-12-22/rustc-beta-i686-pc-windows-gnu.tar.xz": "f9bdb3dac14ded817c6f406767ef140838cedd74b9b2b6daed6419cf096245da",
"dist/2023-12-22/rustc-beta-i686-pc-windows-msvc.tar.gz": "a01af2a20955790992eb248a290161184429d43c8ddd65d8fd18dbb6499edd6f",
"dist/2023-12-22/rustc-beta-i686-pc-windows-msvc.tar.xz": "334b999f3e7c6c8deed7807e398338393f32c641989bd61c631a79a3a7441d67",
"dist/2023-12-22/rustc-beta-i686-unknown-linux-gnu.tar.gz": "334126bcfc14e8ffa5df43c4265b844db5a2b72458f5b3328f6863ea59580b12",
"dist/2023-12-22/rustc-beta-i686-unknown-linux-gnu.tar.xz": "aefe562ff063ab5eea83fdb58577e6ffbbf9cdf111e5390ee29640e5169c2c7c",
"dist/2023-12-22/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "1a9eea2e8fa598c438de05d33d0af4f7b648fc50ff25013b3926c6125dc75542",
"dist/2023-12-22/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "1f0d707a8d96071b1154ff1ffca518a9573d7c1d95835bd35bc3660a8a4d6cb8",
"dist/2023-12-22/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "6cf83e99462198dfd6fd4b7d5dc4ccffbbfc433d5e3b082028420ad7e2da6144",
"dist/2023-12-22/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "295e22e887c9b2d686628fc927d6560e0f71f2330517242d36d1d98159d43a6d",
"dist/2023-12-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "3b970b0cf7243e766a773c9f30557d8d20da668467b85c5cc60fd2f7e927cb09",
"dist/2023-12-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "dd4470357d4351081c9c1526c6a4c66642b11c88f8ac194ae7f0414593b2e561",
"dist/2023-12-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "7684ac7d4a96678d599bed67a11338531f09b500769d94b2b70cf1b1854a0e33",
"dist/2023-12-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "b9f98f6003605d179d298ca1080448784601f9648817e5c84371e54eaafcf36f",
"dist/2023-12-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "376b86e4cb259c5c85286203c00405570a77346441037e175c631b2753f4f421",
"dist/2023-12-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "d4d1b511f2ce2dd2dbbcdde760879b0ce87ac1c191f73d9b264403c328d3c505",
"dist/2023-12-22/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "b46bd2d835f98a293f259d90659334bd289cfff34d4fac544be2add0b4072014",
"dist/2023-12-22/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "6c3e19a3b0dd8deef825f9c6ecba405df6b8a390f6366991c1947f09401f7192",
"dist/2023-12-22/rustc-beta-x86_64-apple-darwin.tar.gz": "5c735a5d0ae69383db88bbc0d7ea5a6f2300c82ce81d1a4b4f987157ac03dd6f",
"dist/2023-12-22/rustc-beta-x86_64-apple-darwin.tar.xz": "5f483a58253a0d6fa58503bd5bf58f8a79c32e49228bb4645a7931c61465d27e",
"dist/2023-12-22/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "ef3db1dbcb14174dc39670810c417b6395e092a92622d49d9bcf4074a02bd32c",
"dist/2023-12-22/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "d73c50be69cc0a817273c75ca86ba094509c9168bd445cfe81690bac48a613a7",
"dist/2023-12-22/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "4476c15df06fdfaf90a426a438cc10e5c0afb4e15ff4394d501cd8f8202f95a5",
"dist/2023-12-22/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "8066766e26df9171bb66e07001c1f3d279f84f48e90ac7cd80ef0439e6de29bb",
"dist/2023-12-22/rustc-beta-x86_64-unknown-freebsd.tar.gz": "7128054459be36bf501225ef22c105edf599ed4732829bd35c20d6831278c799",
"dist/2023-12-22/rustc-beta-x86_64-unknown-freebsd.tar.xz": "a4d6429df3ea63c4f58af3311f3cb986546932a73ae363a768ea6cb630a9b59c",
"dist/2023-12-22/rustc-beta-x86_64-unknown-illumos.tar.gz": "adbb9d176605339353b9c84f53da7301c262966a43e9c25fb5dc408591a5e30e",
"dist/2023-12-22/rustc-beta-x86_64-unknown-illumos.tar.xz": "69bacc4bdb3466862ab86a524516e88e1af3e6379a6bd5b38a5d872534d7584b",
"dist/2023-12-22/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "49b58d45a5eeed663619b6976ef5a97d1d69ee6d1426046f5cf352ce2730aa81",
"dist/2023-12-22/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "9896fc9d8a363a1684abc892f70f71047f43a27eca362911cc39474582a3df7f",
"dist/2023-12-22/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "f5e9ea5090e1a1f1478c1b6c9f4c2975955630717d00304105e7c2b4d30b5793",
"dist/2023-12-22/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "121f57a07ac943c6d48d4519d863e873501edb57d04d8e2842c847510dff73e1",
"dist/2023-12-22/rustc-beta-x86_64-unknown-netbsd.tar.gz": "0ba119cb9e004e008daf53d6f2687ac48b5cadcea81c69f8b7a0f967be0939ae",
"dist/2023-12-22/rustc-beta-x86_64-unknown-netbsd.tar.xz": "81b8265afce99ba1fd7db811611da0f7296b066c2db0f4e65bababaad3f04ea6",
"dist/2023-12-22/rustc-nightly-aarch64-apple-darwin.tar.gz": "101130c9df70b39a6eb8b63ce1c457d8060c961d4ab845f4edb7b02e1b68e5e2",
"dist/2023-12-22/rustc-nightly-aarch64-apple-darwin.tar.xz": "ac84e13cc222d4bfc6670b2bec5407c77792ebf82c51e812ceb3bc972a9cfe24",
"dist/2023-12-22/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "8ca4faf6ccf792534c95b8091786d8b2b79ba99bfcd2537e2cb7fd97a3fc46ba",
"dist/2023-12-22/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "97db2f021e7aacdac1c81ab72264eede6cb72cd83f1c317ae84a3ff39b05584e",
"dist/2023-12-22/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "c274e2470c8cc801495f7a656a10250024173d5927b7ffa2e9251e0b776da5f4",
"dist/2023-12-22/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "024917a1f37a2db0bc8519dbcdecde7321c5d460886b76817791ea484595c44e",
"dist/2023-12-22/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "bcd861c8f6c7f7355f7d6196c405061e90a2907adbca52400b8dcea7bc9b42f1",
"dist/2023-12-22/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "19c52eecdf2dd4fb0b6a5c240c440c6d47148e7264d7efaa77ac484a8429802b",
"dist/2023-12-22/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "38fe3274425db7e9142530be734b473fb5742ea10d05deec24168730d8e65d0f",
"dist/2023-12-22/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "1fe18e92829eb2b87264dee5631329804a7da8177cb15043fcac27c1913a0b89",
"dist/2023-12-22/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "41a723fbfbcc9c003b59fe17e0bef28d69ed89f165c42afcd00e3617a7da6915",
"dist/2023-12-22/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "7f834044d638e8e15d8900c38b8ec1fc6e4ef98efddf3ab7342b24e59525c6a0",
"dist/2023-12-22/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "814402e50600573b6fd79ba3a84fb8c441d71eb2f3eff0257565fd514830ab10",
"dist/2023-12-22/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "2f2650f7ad3d86dd63bd887f6e5e5e5051ffdeef672ee8dbc96c738acde79e21",
"dist/2023-12-22/rustc-nightly-i686-pc-windows-gnu.tar.gz": "6cded96f43ea2aeb2c15ae5e58521301110d6a2f8e8870ff2d6e5e1d8d5d13ff",
"dist/2023-12-22/rustc-nightly-i686-pc-windows-gnu.tar.xz": "2682f11a1375b1b93a9f7110f121340a4994f736c263d37037fb29a5b6df69a1",
"dist/2023-12-22/rustc-nightly-i686-pc-windows-msvc.tar.gz": "9322ff47c86859ba405d6584407b3ad514e6ee1b7a47525a0e20a918875defca",
"dist/2023-12-22/rustc-nightly-i686-pc-windows-msvc.tar.xz": "1dd7be7fd7e51ee9e8c053b2c7c222031aa436497e591ad87a5ee2f2289022f5",
"dist/2023-12-22/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "35e96a4ff0436ed31bb62e06b8898e3048cf11d3ae85f1097741f6b6d2ac0304",
"dist/2023-12-22/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "a8d4be1c79031e6ae2ebf594929cc4cbdd2e0655110ce2a9983e1adee1474b3a",
"dist/2023-12-22/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "7a2b50a5309770784a47662b5616026e735cb12ebd785c578c3a16965167ca3b",
"dist/2023-12-22/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "8cf64de71cd3566683e487832c3f4143f306d4fe9658fa1e16b794d3ee25552b",
"dist/2023-12-22/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "f1890a35bb23fdc85736e18a7230eb4ac68f1d1772a8b1defde1c6fc53b547db",
"dist/2023-12-22/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "5a1cbf44eec83fe1172cef13a38c2f23c2cc2753847ad9577b4cbbc0793ba96b",
"dist/2023-12-22/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "b5e7b7d42a233010142806953ba10820f45be90574c885d9218d41865310d606",
"dist/2023-12-22/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "073c15e2528c30fc51e7964649cd84fc54ce7d6e71f32c4bd5e25028cfe66f01",
"dist/2023-12-22/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "0a579f70e0e6752e5ee257fcc2c77a4986d608262089427f3ae38ad1ff1d8864",
"dist/2023-12-22/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "d9491f667829d36df5db42ad40e0ee6bd0f5d53d854d8648462c357fcc709ca1",
"dist/2023-12-22/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "01bc45a98dc4791b14498d58681a894e3646ea0588fbaf23465dad1034cf7dc4",
"dist/2023-12-22/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "4eca6ca78604697090e48c262aab864a14cdd15607272699cfb9f93b0fb3b9e7",
"dist/2023-12-22/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "c77f35e12eb4e664c3f59575401c20071e3489de8a80e47601321823d1c79b09",
"dist/2023-12-22/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "61f3c129cfabbc5e814ea0ebb183d6674dafa593f56c017262aa60d241041983",
"dist/2023-12-22/rustc-nightly-x86_64-apple-darwin.tar.gz": "2ef95843d229f3b5d5efe1d2cd1cf9a5d2a5500b9f8d00a6ba5eef55a8689643",
"dist/2023-12-22/rustc-nightly-x86_64-apple-darwin.tar.xz": "ee3ac1b167da164384d1e3ac8b6fbde9668b68705afa1a047a1049e90b5bf66d",
"dist/2023-12-22/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "a98e2f3976a5b64f802616c045861571c61eef332c7206e0bfb10fca580c6bf6",
"dist/2023-12-22/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "549caf445a9b4886c47bdf82628e365afe8cea59739a3b41308c828c4eb9e7e0",
"dist/2023-12-22/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "db9bb6ae1770056cd787162ab24e54bad0dc2c8bd2861c8c3ded642f9e963643",
"dist/2023-12-22/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "bc410fb240404e3c193e39667485919660d58b7a5774301f9d0cb21ff744eaa1",
"dist/2023-12-22/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "e113660740b61a1e20d72813e7ef076b7a894f5db3576abae812f501eebec409",
"dist/2023-12-22/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "a0bacdf5523cbc5b59f49fbf99eaa571609faa4aa8765a09f9f091ba3f4f5686",
"dist/2023-12-22/rustc-nightly-x86_64-unknown-illumos.tar.gz": "29f8ee90239986050d96d1fbce42f0ec104653a44c49d050d5965ebbf8e94ff0",
"dist/2023-12-22/rustc-nightly-x86_64-unknown-illumos.tar.xz": "c4c04dc8d91f53db3420114a6020c76771b6dddf43f322ec0575c69a6bba7be8",
"dist/2023-12-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "f40e5ba829e2e731e44fa0452433cca7ca0f41d717f45809c32804d172ee3e7f",
"dist/2023-12-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "5ca6206e9c4c7274f988026dae50774cf0b197b016d81adf15ca29816f9177fc",
"dist/2023-12-22/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "40c913469dbe202d27fc4f3f9f8072c415d2d788d62773de486f0a429d17ac21",
"dist/2023-12-22/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "bde66e4076b615d14e3e799604c8904d4506854e03cf5ac2be39a5839721f1a1",
"dist/2023-12-22/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "5538e8852c23f7070af754e1b19b7c685857f57cf33ed9ec9263a92bf57a14f2",
"dist/2023-12-22/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "2d6558de20de87ce02de647115fee7bcce5f017baf2dc4593a1c91ae53281813",
"dist/2023-12-22/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "3d5878aac23fb995cb29aeaf2579b30ce96d5f3571f53e21e20094d4cad69800",
"dist/2023-12-22/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "80866c0ab8848d31a250c0904222ef0dd19ef45fd1f1a48ff381c914ef6c1ab6",
"dist/2023-12-22/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "4082f5613caab9091d4134dee83f5cfbe401d59a2a1b2000f28c7094584f08dc",
"dist/2023-12-22/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "94230b1d3582e83967306da3f869970d190fae1c22ce61fd5708f8591165d9c7",
"dist/2023-12-22/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "7d59a37a6fbf86c16376f593a54adcbbdf214aa8d49561fd7337d27f437e49dd",
"dist/2023-12-22/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "6c6be9be98fe01756c077cd3f6ef23104e681476e0a4de006223273f3f9a1fd3",
"dist/2023-12-22/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "706b95856289e67c29999ffa4e3afce266c017da8fc66db95695571ae4560ecc",
"dist/2023-12-22/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "9f768f3c40aa3f9d130c4725eff036e1503b372161f136878f4877db44e3600d",
"dist/2023-12-22/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "6e276261f45d28a2110d3de8ae3de4888d041c831d63960bc242e0b0b7765dd5",
"dist/2023-12-22/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "e9b4bfb081445a4506f10249c7441f2d0424778f3ac0fbf5b5ac3b87ba9ef66d",
"dist/2023-12-22/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "f1aec801b69d4b67a58ae93741ffa018d0a49943e593592139abb6b217561366",
"dist/2023-12-22/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "f23b01ec072adf8c29943846ff90f2a1ced0619dcf9c3d517f4cfad64d726e02",
"dist/2023-12-22/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "b61d903932f63625e4163f9a0b7e83606bfdfda4706e68d9387af62f611a32bc",
"dist/2023-12-22/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "21bbc61820a28141db13095dc778524dd4ba1981d6c66caee45b0b72f7267016",
"dist/2023-12-22/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "bf8307795424917a3975b1cf4b0b490cf80a17154d66df2a8d869d1a3291ca5e",
"dist/2023-12-22/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "b651f28f2dabc67abaf2ee7e17cac5508f400bab82f8267ef9ae2ce2399f5c5f",
"dist/2023-12-22/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "deacde8dd4f34e24d981a585061922708af11d4638733eb49dbc1087ffd901ea",
"dist/2023-12-22/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "cefc12a2fa8b66dd66265d159b3ee16cfc87a8c183d7a158e4e610fd747cecb7",
"dist/2023-12-22/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "4996bcacbf363fd93440ff18eaeb09081d1e9e510ddcebc5f84c2a3292d5d0fe",
"dist/2023-12-22/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "dd6b37586054ac9ab7714f0712e1cd833df33820fc661fa3ffa52cbcaa31073b",
"dist/2023-12-22/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "2fcfbc0448df994daa9a625bfc75e69054105a6c120beefa84c3843ab36dc4d7",
"dist/2023-12-22/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "94282e425b30fff90c9429e1f0d2aa5cc69094a147c8dd4521b30fa98eade494",
"dist/2023-12-22/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "25445ecbc332fd305e81075c18c27efdf2027fdb2d263f921eb716cc3ea60609",
"dist/2023-12-22/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "9a55fa07a1a9c3b0c31b00d9b33b0ff727046b4f322e6297ffa290e7741de015",
"dist/2023-12-22/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "01b05f33dbfd00aa3ae500db2204f08e5908a4833c3a26f0473bed9605003bb8",
"dist/2023-12-22/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "946bad6ff6d59ee175d7defcd1567b2aaf5c197bbca8985b04b91eb58f3e6277",
"dist/2023-12-22/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "bc2df359ed8ac189459139a0bcd3556484588bb053a4c2a0e1f7c8fedf39849f",
"dist/2023-12-22/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "a870d941baff83185c43bade890a8c87bfb16e0549fbc74cacfec561740a72c7",
"dist/2023-12-22/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "3fdd608ac91db883b2829f38bfbbb332ac327ab070570384d182e47f875bbecb",
"dist/2023-12-22/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "0a503de10365cc8eea4405e2db265e95d0d6a52556c95e3ca8e06735551ca0c6",
"dist/2023-12-22/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "82e85800015ada8c40c613eef01a4120feb60a35e069ace15d018dcd6603554b",
"dist/2023-12-22/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "21de46c078d31ac953cb41271b020817ef9c3cc55cde7b6b280f0425d8fc7400",
"dist/2023-12-22/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "5886fcf2485728376b7fe7c6a2cf9331f4bb0cab204efe5458ab2ef816e48b5c",
"dist/2023-12-22/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "6c775b5604ce3b3680d9cb6c074c97708d6804d40d44ab4d2abcaa8fd8fbc509",
"dist/2023-12-22/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "51bc618c6c7fa1086032655b6cf7c54b30c12ddf28949840e7695c0e65ff9f30",
"dist/2023-12-22/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "911b8becd12efbb1a46edaf55a383ab8c193e077aa08d1bec8c38a0168557dc2",
"dist/2023-12-22/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "27b84d5cfb60f11b03e26c882f20aa1e58fbba568cd6fc32f0970ab91cc9ed44",
"dist/2023-12-22/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "21f62ffdfd1497e5bd32cb43a9fd3c39672c429ef878e35c2019e167444afecd",
"dist/2023-12-22/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "1338e6d90b781578326816eda5b698ab38efa733387e1df84bb56c3ba5c9fdb4",
"dist/2023-12-22/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "9ce18c0e954100fedef63baceeac4a01fa0b0f810dd5175e5fe61070151c8161",
"dist/2023-12-22/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "8493b82ddec3ea06c8a1b9bb8357c47164ca85856ed538c96678cbaba3361afe",
"dist/2023-12-22/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "cf00b45f38ed847039f7c031e7c1a0a62cf7f00fad5acc05d47edb7e28a0e546",
"dist/2023-12-22/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "96480091ef8533959ba49e01922569a202c8fa2de174be553fab8478cb5c455c",
"dist/2023-12-22/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "c237e0c157dc09ef2c47583f34253ee92db92ead9f77fd8701ddee998acc0aee",
"dist/2023-12-22/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "73b731dbb70e872550e584fc4d3c67b6cbaa2d9a9a97b2ce11bcf6ab3ea5c5fa",
"dist/2023-12-22/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "141fe48890292de4d39547787f4ff44f672d3a5de35ed775cb80d7c3684bec73",
"dist/2023-12-22/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "52b2bab5830100dc4d4fc53ffcae560d7801382dcb4af19d2554e2551312fd0c",
"dist/2023-12-22/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "2071421241ed9e5e00fd5f877863a3a145616a8585db472b35ea902affaee4ee"
"dist/2024-02-04/cargo-beta-aarch64-apple-darwin.tar.gz": "f39e4ae0a2e69b1cc1bca0910287974025fa70398e278083d5be71a6397f6e7d",
"dist/2024-02-04/cargo-beta-aarch64-apple-darwin.tar.xz": "52f51e11e352d96e6350c0860576dc088681a135ded0bc04e943ba95421b52a4",
"dist/2024-02-04/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "60cd2c54379b2d0287072dfe7cff5b81bf51beb69ecb296d6f3036f2a2526f8b",
"dist/2024-02-04/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "cdc5d36196fa99c6c3641000e66ff68be9f2cc95bf00cafa87ae8386400b8ee0",
"dist/2024-02-04/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "e78c45f00e9a88647e8829fc248739aff1f0ed0ab6ec60a3da5ce6d2c1f02cbf",
"dist/2024-02-04/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "541754f83b39db95b62c5a0d2f9650b53212e0d6c2989429323c79a27d96d8c7",
"dist/2024-02-04/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "6ec7f1ee3284ae3e27da9667fe976d459262233bdf1a7692f8c72f467aeb5ff6",
"dist/2024-02-04/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "89c46d7e3826e6ca21cd2b992492c08e7a1d261ef347cf29f018480956fcaf98",
"dist/2024-02-04/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "9af1091ed9deee05e3c1b590dccc88e3834f47c43193acc29d5539ec7922a7f3",
"dist/2024-02-04/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "14a55b1aa26cc7ced03857a4848c91eb25bc1735b1e314b453efb8856b96105e",
"dist/2024-02-04/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "3104665d24262b8b7586777331e63ee1732fbf7656f05b7dd85a71534e7b47eb",
"dist/2024-02-04/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "610486cfcb5022c6f99494b9f58f3494438c7d9af4e0a949d0c5d366d13acd74",
"dist/2024-02-04/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "bdeeb3b50477fb57f5d02796af0543deeff9d274e6c12dcef1a11f7517dd2ceb",
"dist/2024-02-04/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "95a5beba76cf3ceb27378f1f2f9ab92359ff5627603ce2f6a8f86bed6ecf61d8",
"dist/2024-02-04/cargo-beta-i686-pc-windows-gnu.tar.gz": "65d4fecddca8b303f062fa119af9a7eb145c4c91adf5d5ec045325f2f48c906a",
"dist/2024-02-04/cargo-beta-i686-pc-windows-gnu.tar.xz": "38e766e4d90270c8a5f82cd4d0a50c1c143987201194c9132b86bf7a1a969036",
"dist/2024-02-04/cargo-beta-i686-pc-windows-msvc.tar.gz": "ed2ade2a28c469f9b488a675054494f4f26b4c3bde90c17eea34454562262d08",
"dist/2024-02-04/cargo-beta-i686-pc-windows-msvc.tar.xz": "05c6dcfe9e14bc2ede72863fef1814feceb063044af7a31baba5961e29aaf1d5",
"dist/2024-02-04/cargo-beta-i686-unknown-linux-gnu.tar.gz": "5954537bd942311649da6daf95ff60afc7e9b03fd3fae0d1a97244338309786e",
"dist/2024-02-04/cargo-beta-i686-unknown-linux-gnu.tar.xz": "9148aed468ae49b94b14786eaf58f963e2c58e2a99a93afa481be0a9244b86d4",
"dist/2024-02-04/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "213b7f752395db016555825664e3e4a3bd5da8943e8bd56ed5bd94380e92181a",
"dist/2024-02-04/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "8d146499b36f2d08389ff7888d74daa9f18a7e43cc2283c5410dd5c386c9caec",
"dist/2024-02-04/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "12a828172bb26f88c1a11a6d68aed6f87c3dc47961f74c8eeb6451b38c204b90",
"dist/2024-02-04/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "3905b493ee8ed0bd4961739b91a0dc14340082a811ec5be6e44dd8194ffaa38d",
"dist/2024-02-04/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "63eb2e4303af8f77ebd8d22c08fd7d6f209abec1dd9f19f5afd2c4b281e765cf",
"dist/2024-02-04/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "5be0627e2aeb33a7888c9a884e019d65d53a463e5b2dbb23a11ac5a89cc175c3",
"dist/2024-02-04/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "12bd938eab15063da78bda1b5f0918b567f55587c494c85fe8b11b36f305e397",
"dist/2024-02-04/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "0a6247ab66282beac406aa0c25affb51dc43a0b2a40fc71a1d98efc680a6f67b",
"dist/2024-02-04/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "6e9a6b49a58ef886bf668c9827c31d3f9beb2ee227b8c7a017071bff7e1efb6a",
"dist/2024-02-04/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "f56cab3cbbf6dc2e605124b8edd6c9a7d7592d001e9b2f4ea04af890b6fe6335",
"dist/2024-02-04/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "be35d6d6923da0a5c8599760a72b584cf9e131bf16effa184d79786e9613f8a6",
"dist/2024-02-04/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "81cd24ac13498570894a98a69ffc552ad282dfe4a076018841881f65ed387e09",
"dist/2024-02-04/cargo-beta-x86_64-apple-darwin.tar.gz": "e828aeffa6c832ff7a1e71ae12d275f75df9c3087aa08959dc0b93d0f37f9f76",
"dist/2024-02-04/cargo-beta-x86_64-apple-darwin.tar.xz": "546c56de1500061d5a133e05662d2659e3e96619f20757750ae8865498b71eb6",
"dist/2024-02-04/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "c10b9f15a31a05ba6f865d1a853ca3f9b178a3c886ab73b9577f8db0b870c592",
"dist/2024-02-04/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "65c5941965768e31abcba7c57e660cd6fcf909157b6aca1bf2ea0983e5a844da",
"dist/2024-02-04/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "14bf2ac915ba94f172bd2a569bb669101d877fbce5262071b5ebb8f8d81752a9",
"dist/2024-02-04/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "b2ce5dce49edc9a872ec63251b00ce4bc7c232984fee8b8ee534d8bc04f2084d",
"dist/2024-02-04/cargo-beta-x86_64-unknown-freebsd.tar.gz": "d408172c12e290bf27828a2e806670c750428182d0caa5f1aa88b9a4d3fe1bc9",
"dist/2024-02-04/cargo-beta-x86_64-unknown-freebsd.tar.xz": "46a7ce49382615f896276eb1966b7815353d19927a9e54feac902777fc7de10e",
"dist/2024-02-04/cargo-beta-x86_64-unknown-illumos.tar.gz": "a28eccf6cc23b580980fba900943c93a71594ed0a8120c239ce882e02c1f4a6e",
"dist/2024-02-04/cargo-beta-x86_64-unknown-illumos.tar.xz": "950a9a326bf80c65b0cb0073c5b712368a7358b993b8850cf4ae2bfc6644671c",
"dist/2024-02-04/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "0676c47123c0292b2e4f18592801383bf73ade1069cf6d160f27a39d86641b4c",
"dist/2024-02-04/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "a3dda924031f949cd7b5ada8e67b506efa94fbd4201e00d9c1e1e589223a039f",
"dist/2024-02-04/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "b00be1a9ea0d0ca1c81181d2e1263594c8654036d050e8417772bb10021a0018",
"dist/2024-02-04/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "bc464a4758ba8d585b2a6d7ba1f0f76c5bc8e21ffb699b4311cd54c702ab2295",
"dist/2024-02-04/cargo-beta-x86_64-unknown-netbsd.tar.gz": "4c165157f0fe6c96b3e54a73f795792cfc69aa979c71093eec918ddbce9a6c08",
"dist/2024-02-04/cargo-beta-x86_64-unknown-netbsd.tar.xz": "05cd0538b71c90f3e665b2feef453a0c4f4f6b1b68e4c8fe2339bd3d9c071af0",
"dist/2024-02-04/clippy-beta-aarch64-apple-darwin.tar.gz": "93cf112cfedead61356eb102bc55c811a23f67e13cf3933665de95f306c5a3ef",
"dist/2024-02-04/clippy-beta-aarch64-apple-darwin.tar.xz": "5389da6bb96c8928f18d018a25cd5d104d1c4ff9478ecf7c289434de3253d2cc",
"dist/2024-02-04/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "5403e94f79d7295bf565b061b6fa9e5d500068005a7012c47dd1f0422cadcc99",
"dist/2024-02-04/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "a285d22b4555524d94107292c45300129774448f2c1112e1744564e480ba07f1",
"dist/2024-02-04/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "4a6a2bc13f589b4de7a42d71517286740fc5670ad8247263338ebf13f021f5f1",
"dist/2024-02-04/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "6a007ff2a433dcd4a07efa6d55ae829cbbf4518dd5a5e52570bf70bee1876a22",
"dist/2024-02-04/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "b4ff74cdef7ddbaa97ce031fce580ef235dc890c08a65f334b7f9bd61fa7fae5",
"dist/2024-02-04/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "80bb641d57cd9077121640aa989a2a1b2c7ad802219b623d7b98527181061056",
"dist/2024-02-04/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "9f5a8c09e02bbfde36522f6b98ac19c6758f04a6fbb76cfafda357fabba20819",
"dist/2024-02-04/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "03aadb465c7761f000cb1515c98998afeb7557d1b20443c6b444949620290fc8",
"dist/2024-02-04/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "694c756a8df76057982652a6dd31406e52f46f1bb9af29e9e1221ee90b966713",
"dist/2024-02-04/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "224cdd5c675e68b5d0094a1b0d9cc08411b168dba5c3a8b6be15223ecce542e6",
"dist/2024-02-04/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "95c385adf93104d0ee31c59c10cdac2c7dbe073c40eec9a213d528109659e5e3",
"dist/2024-02-04/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "f649540bf91a48a9c8b58ed161b9665747a04054839bd21225d5d01d6abb6809",
"dist/2024-02-04/clippy-beta-i686-pc-windows-gnu.tar.gz": "b7597b2bf5e1a3b6041cc3e7773ef9385b3d1e0323411ee81eedad07ddec64a2",
"dist/2024-02-04/clippy-beta-i686-pc-windows-gnu.tar.xz": "a21cacbc47c6e9eb16e356e7724b1b71214a2b5fc513a50e8f4ce79060ddcd4d",
"dist/2024-02-04/clippy-beta-i686-pc-windows-msvc.tar.gz": "d71c3d482b328a01168f1cb8136f2ab76f5d55468984fad27039ea65f462fbfb",
"dist/2024-02-04/clippy-beta-i686-pc-windows-msvc.tar.xz": "e1f4ca9fa2dadc238126a995891da9bdb75dce196daf3f95a697653004fc2d4b",
"dist/2024-02-04/clippy-beta-i686-unknown-linux-gnu.tar.gz": "c2763fd5984be3105f649f5587cdb5af6ffd53fc3032ffce751730051a901e36",
"dist/2024-02-04/clippy-beta-i686-unknown-linux-gnu.tar.xz": "92a53f012b6770bf505082e27ccc182b20c0ae4954788c8ba51c140ec8981c8b",
"dist/2024-02-04/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "c39b59c5e347bbd169cd1c08c087db4f7ddf243416c9d0a144da620ffd99283e",
"dist/2024-02-04/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "1a973d60048b8a8541ab217cb00d5aa74fcb799b1f4f491666b07d4960aa8fa4",
"dist/2024-02-04/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "e40718072e3dde6e01bb9881a024a362057a8c22601d58273cbfa757999311e8",
"dist/2024-02-04/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "b47d5c9c7eb3351e7afc3648069e0e5d3eaf9f61b1ba2074f91f1b4a114cf6c0",
"dist/2024-02-04/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "ab30688d5eab3f7fdddf665ae00e23a168259da3bd9ef583e56c80800e20256c",
"dist/2024-02-04/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "4c08b61a36d8901e8c8fc397f7919b63264f9709b0b513683582da4378e4586c",
"dist/2024-02-04/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "88af713a59ad27e04a315a9887e0af3afaa118ef103b235a6874e7665e270f55",
"dist/2024-02-04/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "e6aac345a1a8c12168af05697379e885e896f1ecb51846a5183aff5f1efc321b",
"dist/2024-02-04/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "b57db645be80fe0ae5a8d3a496f4d00ff7af3bb0ff1032538a051da3b012cab7",
"dist/2024-02-04/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "be6d3d5cece8442b016be55ee46f4278797a7842d023af9d03edac6e528b6e8f",
"dist/2024-02-04/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "5f58a7aec4c2b9311cba0c11c88879e60fa9bdf541324f08b203ad739d4dc8a7",
"dist/2024-02-04/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "3b7e417060b91bd08e28d88f531947461c18a2aeeb3ceb7774171be7e55758c3",
"dist/2024-02-04/clippy-beta-x86_64-apple-darwin.tar.gz": "1806b225fd6b163ca5ff2fafe34b9fa085724f3c46133757b6a19fae3e253c69",
"dist/2024-02-04/clippy-beta-x86_64-apple-darwin.tar.xz": "bed30af2131873d94784ff69fedb51c80e0c0ffc5474c6ebb06d00292082d2b8",
"dist/2024-02-04/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "7a7c7e2b67105712265e776086c9dcb8fc84c1ad64c6cd3175b8235ea85f1287",
"dist/2024-02-04/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "9aa2a44e40c3221df88738db9fb9729989ce618c8a73e109f04ed758da044ef0",
"dist/2024-02-04/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "32f2acc1fb292a7f8af43e7eaf0e5cc57f21ce51ddb209ee5d9c4db50bedfa17",
"dist/2024-02-04/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "6e521228076657cdd451d924c3d0d48ae703f6a3ac1b6c64fc2b56553c924f11",
"dist/2024-02-04/clippy-beta-x86_64-unknown-freebsd.tar.gz": "cdf2ea498ea64ce119a861c4b4ed198f1971ff4562f239e1ae982a6bd50a8169",
"dist/2024-02-04/clippy-beta-x86_64-unknown-freebsd.tar.xz": "8716ccf9eb52a71fadfc177abd5dc75b1d9b1f14f7c523d12aefe5407d5380ee",
"dist/2024-02-04/clippy-beta-x86_64-unknown-illumos.tar.gz": "b845e1e8e0912abc1c165e757b28a569117ac7363282e691cad7dfbf2fbbebe9",
"dist/2024-02-04/clippy-beta-x86_64-unknown-illumos.tar.xz": "8a5577421bbcb6bf4ff052bfa0db9e22d65eeed578be3fb14946bddcf78aaf8d",
"dist/2024-02-04/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "730dced7639da52fe031ea9142012cd1c6f4a195312d99ce08f8b948ac317f78",
"dist/2024-02-04/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "4de9e4acf49f34cf7e99bee718d15081ea7e5b3cce56b1d180e125832126934e",
"dist/2024-02-04/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "b5ce09b95d2a77ba605d2083573c1d4832fe42c8ff6b5bd8507f1ccddf87a10a",
"dist/2024-02-04/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "fcf7c128a344f7b55481b82223b971fd5565db4023d443b315349a5ac5f5937d",
"dist/2024-02-04/clippy-beta-x86_64-unknown-netbsd.tar.gz": "8abaefeaf4d884e3214f657d8896bb440d93b3cd5f4e355fb8ae728d84713f40",
"dist/2024-02-04/clippy-beta-x86_64-unknown-netbsd.tar.xz": "a4b5e4b73c7a613f34ed592af4a73e50c4fe6f0f841f9749cab57530dea6033d",
"dist/2024-02-04/rust-std-beta-aarch64-apple-darwin.tar.gz": "54c24b06cf7b1cce6d74d0cf2ef38c0df0296e9b417116ef6bb340cf9a864f20",
"dist/2024-02-04/rust-std-beta-aarch64-apple-darwin.tar.xz": "17034b0eae96813fcfd0d8883fb7f4805b713404e15169e8c3de32801e4ca3bc",
"dist/2024-02-04/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "477879218f052b6f20b40d34b72a9fdb900a64fcd4a1392faa187eac44576456",
"dist/2024-02-04/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "5fae8e638f4c6b61683db07c0de485a1cb677e4384c593f32c089d77ea5dfbd9",
"dist/2024-02-04/rust-std-beta-aarch64-apple-ios.tar.gz": "4cc45742a06693a713d72820c6ee830ed8bd4f6f5ddd3be1e32bca4f5f88fd4d",
"dist/2024-02-04/rust-std-beta-aarch64-apple-ios.tar.xz": "7d9adce8808f0f5f7b9c65091791107afd63f26de02fe156821a6125486f2255",
"dist/2024-02-04/rust-std-beta-aarch64-linux-android.tar.gz": "893a0befa7f506cf3a07712d7a731ce551209c97708cd7f0ab12fa6ff3f1da39",
"dist/2024-02-04/rust-std-beta-aarch64-linux-android.tar.xz": "b647047d64f2fded2e393f226a7d131c96e84f2cb0ea6ed8259f25648b56bc6f",
"dist/2024-02-04/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "74917077da50bff4ceaad96a8acd1e90f9ccef32aea2b2f5f48406ebafff4c35",
"dist/2024-02-04/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "08210e2b802cda619854608e361a08388b51b9fce1551c13e5068ddc22d0773c",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "a51887dde95a5102eba99a754016900dd679e2cc6f65b7173a3d31c8d0f0148a",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "57f7120e830dcbe8c95be39f00342f2fbbd8ccdb20f431e8bc940eccc4002864",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "6a79090eae406437761523e43e5a72b0ed040deb97db82da62718ee502573770",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "00f3df2addefb8968d668200a890593481587536d0628e4d8def08b77e79caaa",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "42f0afcf90ffe70388c53d7642b035700af71b99e8382c5e95a94c6aec166e99",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "337984596f0d3cfc5776830cf7cb36ec8d564041761666fe340ecb0a62332348",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "913e2255837674cd672c4959d567ccd786242acdbe78fa76119ceb8ede9b9846",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "660f879a8a3e19686cb944766b0e70b19d0a9fd344047ceaf5e8959bc019f36c",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-none.tar.gz": "4a210eefe84dbfe4e75fbc3a5475e58d86983e1f5c195e7c8b9f096e46ebfaeb",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-none.tar.xz": "ad03045b5fe2b25806b4b44f5920e75008234954318cdc9cac8159782f6fc314",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-uefi.tar.gz": "0c2988780468ff39ffe65cae5443bbdbb441aad18bf88312c14df76fefc748fd",
"dist/2024-02-04/rust-std-beta-aarch64-unknown-uefi.tar.xz": "0e4efbb711bd74cb280535ca424be4519f8e273b482eff4b5c4cfb7f0c142a74",
"dist/2024-02-04/rust-std-beta-arm-linux-androideabi.tar.gz": "6e6a0140c52670d962db55be6aa607618fbd4094828f27129cc94540ac94d893",
"dist/2024-02-04/rust-std-beta-arm-linux-androideabi.tar.xz": "fae70ac3c0be0a83c98eeac49e651c392c5962e10b4876120959d95209cff4ac",
"dist/2024-02-04/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "48f73e51726a7685cee917fbf42464c13b77e3c4c36730477ce8a5213d0c8068",
"dist/2024-02-04/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "03c4fdb9ab6737d48e9d1573188badf126acdfb96c4dd88c36d45fd7d61845c6",
"dist/2024-02-04/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "d17985406a6d241ae2e1f5c5571795ab712cc47fc2434fe78d69d3e581a768c8",
"dist/2024-02-04/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "ef29cc16781ad2422b78708634684f9310cf7783c2c88fef6cc378c1b21f86d1",
"dist/2024-02-04/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "df8bf07f5270c91bcdda1568fc870c128594a558d5fd26ebd8f4e9e1c7c026c8",
"dist/2024-02-04/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "114b42345f30ff26ac42044825209f7d1ae4b8b9a59c535ad199a78e8e2be1b8",
"dist/2024-02-04/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "5b05057ef84727d0d62a575b1a4d8f87ea7b06cf242d294912bf97b52137a0ca",
"dist/2024-02-04/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "a87b55c984fef378be2f50db63c0a66f715949e4365d467211b5c13839320cc3",
"dist/2024-02-04/rust-std-beta-armebv7r-none-eabi.tar.gz": "e8ac0f9c5f699c88a8da799b08111bee35719426ce6c0e2f53d0db14fb9b96d7",
"dist/2024-02-04/rust-std-beta-armebv7r-none-eabi.tar.xz": "7875d407748e983536bc0d3a385313a124de94390b780557d48fce9564a3754e",
"dist/2024-02-04/rust-std-beta-armebv7r-none-eabihf.tar.gz": "70415c0c7c4e9e53b12b1cbb0101398addb6b4aec59235011c2d73c059d0336e",
"dist/2024-02-04/rust-std-beta-armebv7r-none-eabihf.tar.xz": "2c9f18fc935938d5b9f9cb7915dab5aa6ca96032abf5a9e3313a63136c4cb11f",
"dist/2024-02-04/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "b00b34a021c2d80574bbb764b08e291ffd8db0f346b8c3486789c86f008b5d98",
"dist/2024-02-04/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "b47a6f55b44add99ca66d06fa910259c809c5f4f01feb809e2a6b8513626e3fb",
"dist/2024-02-04/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "caa8182c95035b62ba22e23d3989ba2733b90f599276a7c1f79b911e19d97850",
"dist/2024-02-04/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "1dd6c111f945d727eb28c9005efaa367ee2de8b15c771d27cbcb9709202f85b2",
"dist/2024-02-04/rust-std-beta-armv7-linux-androideabi.tar.gz": "b4176be56ab844c0f3d652d5023b927b672173f96319f685a85e57742b713102",
"dist/2024-02-04/rust-std-beta-armv7-linux-androideabi.tar.xz": "3d3d96f5cec355401e3eee94e5a9b68e070f441090f691f1de15a13d6194154e",
"dist/2024-02-04/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "ee5fcd9e0a661d08a1cb752cbfdce62b01faa4c4bbc607d09bb0d39a2c598899",
"dist/2024-02-04/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "a2e7ab719dee92b6c2132a902045c0bb2688851243fc530eed6b1fbe1a053333",
"dist/2024-02-04/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "59ca2bacdca9b46e6e0b1803813d4021b685f676e53393e18b4497853a452d85",
"dist/2024-02-04/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "f1b5b8843f804aef664a96896235384b1389de7084ba30be234c770dc9ab0517",
"dist/2024-02-04/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "3825bb169e5d7abc0981f6a5179b143e2a695e395d0baa7cf181e8b752988ac7",
"dist/2024-02-04/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "9aca61705d683d384e1d7e2392bdece52791d77edde6f45e2772bae766765434",
"dist/2024-02-04/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "46162ba65beed4d4ff70695870d02a39dba5ea4e1a71887140077e12847a3206",
"dist/2024-02-04/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "70841fa160053edb31d440eb47c54c58f4635bf4a95eac5624861b9d1e5dbbfe",
"dist/2024-02-04/rust-std-beta-armv7a-none-eabi.tar.gz": "ebc2f71d8486401144a193768cee0fdda3d43ec4ba7cb57434d3ec0ca9ee64dd",
"dist/2024-02-04/rust-std-beta-armv7a-none-eabi.tar.xz": "c8d54ac916b6c0651e8289deeee3dec76a06db7086957bca8c6039f4d10aef2a",
"dist/2024-02-04/rust-std-beta-armv7r-none-eabi.tar.gz": "b25ff694d355fafb41aaa7021c09c359b0af43a0217e1ee9d897f8f2e6ece91b",
"dist/2024-02-04/rust-std-beta-armv7r-none-eabi.tar.xz": "c22f40104c14a127d8df29f87fdb63db7aa919e11507c0bb8907dccd2d254f17",
"dist/2024-02-04/rust-std-beta-armv7r-none-eabihf.tar.gz": "3f73a17c6685760c30baed31cb746389b4b228704786a3a386ab432e933daae4",
"dist/2024-02-04/rust-std-beta-armv7r-none-eabihf.tar.xz": "fd8470f854538c8314d15d35b9a5159cf9b431ad7ccb79ea0542ba39d6e8a8dd",
"dist/2024-02-04/rust-std-beta-i586-pc-windows-msvc.tar.gz": "1377b2c1bc7a7066d7ae96316bc0a0339489cb71ef7f9f055731465df97ba8a0",
"dist/2024-02-04/rust-std-beta-i586-pc-windows-msvc.tar.xz": "77b22f2e94a3e1cefd057f051e568a6c8f4b17845272924dfbc193d8a290d96d",
"dist/2024-02-04/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "222337a479e3d680d95c5189026890bdb3cae7eca78000f231e6747b9b403f22",
"dist/2024-02-04/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "91447a0543f07bb36c71822ac4e8148e2e5982d1dd98fce7ba4171d7f418ff16",
"dist/2024-02-04/rust-std-beta-i586-unknown-linux-musl.tar.gz": "e2aa15ebd2a903f754fc9a46584b444b3fbbb9e42f2647ebe615f68711a0a27c",
"dist/2024-02-04/rust-std-beta-i586-unknown-linux-musl.tar.xz": "65f6975a8c06967f734bbd15589b14c5eb23951f10a79097f262083975654dd4",
"dist/2024-02-04/rust-std-beta-i686-linux-android.tar.gz": "073d7697a80e99cda4625f0bf1205744af9cab1a10456e44050fa8e6987007ab",
"dist/2024-02-04/rust-std-beta-i686-linux-android.tar.xz": "f142ffc490821bfc4bec5d69fb82c94aece9e379168f86b494b13289a597f23e",
"dist/2024-02-04/rust-std-beta-i686-pc-windows-gnu.tar.gz": "aaad81222f76855ffe5d2f6c5eadfe95562e9dfdf72a92531dd85b38568420f5",
"dist/2024-02-04/rust-std-beta-i686-pc-windows-gnu.tar.xz": "69923e0455f7b8f2cd28ef812118e359ce64789059d45e91ca5f8e382f1de1b8",
"dist/2024-02-04/rust-std-beta-i686-pc-windows-msvc.tar.gz": "1d66564ac675d5ca8c97ea7feb2b8e2fe606a560d27a137d996ce9814338cbba",
"dist/2024-02-04/rust-std-beta-i686-pc-windows-msvc.tar.xz": "8badfa48e9a654a48095026903e17392f7b4cae3501362579d345c541ddeb6bb",
"dist/2024-02-04/rust-std-beta-i686-unknown-freebsd.tar.gz": "3d45f7e407668cae7fae8cd8dc4e8ff8ca5f5a01baa4eb9401b81255d1e8947b",
"dist/2024-02-04/rust-std-beta-i686-unknown-freebsd.tar.xz": "c1788c7bbf8f4ee61c2d4623ed4efa8a8d15acc2963f3c146b48ed7d6f6010b7",
"dist/2024-02-04/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "2e4434cad302be51543916055c8ba76b8c0c072476f6c491754b1a750aac8800",
"dist/2024-02-04/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "5ac0bb47b9b6349a34ac1526f16714cdd580bd3aafcc3811001c69d8be21d0c4",
"dist/2024-02-04/rust-std-beta-i686-unknown-linux-musl.tar.gz": "21b1323043707f685bedd699a169e8acb189ca7431c1a3dc0ec7f56b27c2fec2",
"dist/2024-02-04/rust-std-beta-i686-unknown-linux-musl.tar.xz": "8fe2e260084c960bd29bede4be32371a34b1f801447628bbc32e7dae2d603784",
"dist/2024-02-04/rust-std-beta-i686-unknown-uefi.tar.gz": "4fc958f2c26ed27bd4537a31d2eee9a5b02bb5b0433402151e84756f470aebdc",
"dist/2024-02-04/rust-std-beta-i686-unknown-uefi.tar.xz": "a2c8235767448796d80f5408694d8ebbd6fa3b67d7c4fa03b7074836b4966114",
"dist/2024-02-04/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "a8689d5d7454dfe00acb84535813b47065cc09e17cc8006d5fc02da5f02f1cb0",
"dist/2024-02-04/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "d0eb4684222b53cac2eb84242a4e145f3f31ca855c296836b75340a0d432391e",
"dist/2024-02-04/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "6ee4ad6d9022bc69120709064dd93ff70cd3beb14ea28e82f3d4fed24ab07426",
"dist/2024-02-04/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "57ad740ec9ebf9b5bd3f082d89d63ff388523cb4d38e2cdf0b601bc7f07c6820",
"dist/2024-02-04/rust-std-beta-loongarch64-unknown-none.tar.gz": "a7400a7bbb873aac5c92339c8242966d1fa9553054f922193a2a8023b98a97ef",
"dist/2024-02-04/rust-std-beta-loongarch64-unknown-none.tar.xz": "7cd77b7c8a8b7c7c53d2ed454515766da3e02c7d6c63d880de9bc1c313f396a8",
"dist/2024-02-04/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "3b65431258133a690c976db006ad7b545cc980ff0352dcd03304741f5e82881e",
"dist/2024-02-04/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "87eaf905c3c189e9fca5a3f1dea6a0b53b7c4a84aa22c1ecf8b782c54c360a80",
"dist/2024-02-04/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "97c12900755f780e32facd9ee3641394a3a7e32fe6e6a1cadd342ee367c95b6d",
"dist/2024-02-04/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "a7c482e83c0ce07164921cc8ae48d02db9b795a5ea2e82c2948f598f68519289",
"dist/2024-02-04/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "9c1018fcdf362d891b6b1a63c36d5123917b2478bf010a0b32691c44480abcc7",
"dist/2024-02-04/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "fb93344ade418630bf610f9555babb0356ebbd369db73ea3edd88e96a48171f0",
"dist/2024-02-04/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "4c24f19b83a528af2ad0935d775106415708a03212092ba86bb271db38bd604e",
"dist/2024-02-04/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "804bc2c1c51570cdc102c80c1514b773d0a05a8f2fdeff9f789b525b042a5071",
"dist/2024-02-04/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "8ef9ed0ff32193e46617bf2aab368bbc4b268175acae604e26db8a1a92c15983",
"dist/2024-02-04/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "3b0450f332e258d1bbeee5c78628349cb1a6fad9d7058e0f2137709c46d90713",
"dist/2024-02-04/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "47cba66e90e6310139a511083eeac727a6c55e66533157a662cd613730df7123",
"dist/2024-02-04/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "ce19df99deffaf9002272d8c8b8c51f6d1dda93fc2babe8d786494add2607b27",
"dist/2024-02-04/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz": "fb8842df07fe5d0c782c9a4b260de7cf71835f7c4ca18f5241c9dc245c75bc7e",
"dist/2024-02-04/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz": "5b14d80923b4561c3147d5a6a45ad73f0c187f8ff38ce51c7f54a95f17d0e3f0",
"dist/2024-02-04/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "19f2c43070c2cd477a07d9ab2e0a9fe8e3d41aaff75e09b5bcb89e6dbf8d0d12",
"dist/2024-02-04/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "f5d413c8763e72aea96ca97a71927fd81fcd6341a8d7cacd070898b255f6d8ea",
"dist/2024-02-04/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "227a42a01e2bfe5089afb478f3c78385ee989fe70199110ae8e5fb8f7d9c899a",
"dist/2024-02-04/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "9a09c50ae0773469186754b6d14638a0d2d170f3cbac9dc36f4911a248480ea3",
"dist/2024-02-04/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "70b168b86fb960124e9b4ed510848f5420647dcb82d36cce887aacbb7bf2783e",
"dist/2024-02-04/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "db3a0c4e36a182926360317694053b9ee7e24d6f77f3c15eb9ff79482b3d129a",
"dist/2024-02-04/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "127cb67bac139a8621b87a475be07dda3fc92616f15068145ebebd7087230815",
"dist/2024-02-04/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "07e2ca92ade33338a800f3b9c0b8aad2ddc1c699247a3144bd70b3f2d93e84ec",
"dist/2024-02-04/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "6fc83881b97579aeb2c2873f18a5e63ac06a4b94889e0054a8515e2f23b8b1c7",
"dist/2024-02-04/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "b85f994c59b82db877fb42e2e06ac193de136e8b362284d211c66607a7272328",
"dist/2024-02-04/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "d3188ab7fc2cba5474cb6c1cb0edeffe20ab90beb05cb42e83c4eeaff3c66d9f",
"dist/2024-02-04/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "3e40bcf0c16e96fa81d814d81631e99069026d8b27b10c905ed22218d5842cbe",
"dist/2024-02-04/rust-std-beta-sparcv9-sun-solaris.tar.gz": "cde8e5c30725da66f9c6d6c67283e2d55cb22c1b65c4a0ac8157e3b7c79ae567",
"dist/2024-02-04/rust-std-beta-sparcv9-sun-solaris.tar.xz": "4832c0e385467bb0c5276971d5ecf4bf0e77247e54f90480be635a6a4a43ddb6",
"dist/2024-02-04/rust-std-beta-thumbv6m-none-eabi.tar.gz": "5ee43f29701f44060770a8be635708ace9143eb77926f6a6c946a3e02c56bf92",
"dist/2024-02-04/rust-std-beta-thumbv6m-none-eabi.tar.xz": "0af4c3a0270c53648b88a915466b592ab6a29aa959a014748fa95b9f511140e8",
"dist/2024-02-04/rust-std-beta-thumbv7em-none-eabi.tar.gz": "e57337af619b9e2de45d5268944d9ba3ea7ef19d8413a3e13a72c9ce08fe252b",
"dist/2024-02-04/rust-std-beta-thumbv7em-none-eabi.tar.xz": "26bbe4aa8ea10b4dbdd21da2f62118d42adbb852bd01bedab9cff47d79ac3887",
"dist/2024-02-04/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "ac22acf98402d2091d60e4d6e934ef474d0ca40882121d595f7a809fa575264a",
"dist/2024-02-04/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "3f0623d888b00d6ef243888322f9ef1781927c304e1ebd93b0d68457e0a551db",
"dist/2024-02-04/rust-std-beta-thumbv7m-none-eabi.tar.gz": "c23866c57b3781b12fa372d8a1a98626be669dfc86eb568aeafc9bbefe5c2fd5",
"dist/2024-02-04/rust-std-beta-thumbv7m-none-eabi.tar.xz": "64d2e9a717e0d6dc1bcdb3ba76937ced9d941ed1aa367fd2ebc9d6056b527a26",
"dist/2024-02-04/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "864689308f8f72faad3b1812dbb67de254f4f0acbbc28302665b29f8e6aec9c8",
"dist/2024-02-04/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "737ca7c2c4f8a1ec87ab0819676926a7d13ee4c074359530e02fdaa11a51cace",
"dist/2024-02-04/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "68f0aee311b2fa12686249a4ace1f1f1fe254e4ee9aafbe6e7f429c98fd024c9",
"dist/2024-02-04/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "cfe3bdbf666576340a7a6ba22422b88389356c21bccce60f31540a1a18095e74",
"dist/2024-02-04/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "bb0a27b78f4c006c5e9d04f7446433e13908837d947c8c73ede878219a189a52",
"dist/2024-02-04/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "271d1471e2ec7901582911bd341896e07d38ac7a762ee3000964cf8cc9f3d73e",
"dist/2024-02-04/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "e875ae5276bcf3bf112815ddcb8320d9b3e67f7d65ffda9bf194f54c49b55758",
"dist/2024-02-04/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "4f38da22bce7fdfd9cf0b0f24cce08b298af54dd2c20d8a6a10b888b66a5f120",
"dist/2024-02-04/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "28ec4144e3ac2fd74fb5f59844b29623b6286173893d5b487157c7103d0e59b9",
"dist/2024-02-04/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "c870d0ab781cffbf6bf7d0d0484b0a484eb4c4102d36f32d823b9c20c2886078",
"dist/2024-02-04/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "23f8c320114c329109f081a868e5ec464d766883fe947538b26c31757b6305b9",
"dist/2024-02-04/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "41c3cf36b6dab93202e792c4da186f5aef0ef5499d425a33ebafd1b4a7c5ff3f",
"dist/2024-02-04/rust-std-beta-wasm32-unknown-unknown.tar.gz": "09670117cb42829fcd871ed702652744d0599f715db8f1dd82ed462f01de87c0",
"dist/2024-02-04/rust-std-beta-wasm32-unknown-unknown.tar.xz": "5c04dc908e258dfce00306b6b6bdc5b5ee48031a6b5d602e7326e670f594fbd2",
"dist/2024-02-04/rust-std-beta-wasm32-wasi-preview1-threads.tar.gz": "09b5f40f1a449bb7cb6ef868bb3998f3ae4bd4f85ca594cca8b934166931a549",
"dist/2024-02-04/rust-std-beta-wasm32-wasi-preview1-threads.tar.xz": "b4de2d6ca31aafaa24871d15f4e0297064da72db884609223462232571df6ec2",
"dist/2024-02-04/rust-std-beta-wasm32-wasi.tar.gz": "194999685f52e9c489bd7e46cc1ab24fa2e37559a987d4fd90453b30b7e8b152",
"dist/2024-02-04/rust-std-beta-wasm32-wasi.tar.xz": "6f251f32b9959e7a602d6d9ddb89647970c79f129911084756550697c9e93893",
"dist/2024-02-04/rust-std-beta-x86_64-apple-darwin.tar.gz": "bc4f9b694c886df968db188f4687281d701f6fc4e19a1b59abaea247097dcd9d",
"dist/2024-02-04/rust-std-beta-x86_64-apple-darwin.tar.xz": "18530dddf369372f1f3543f8f7f34200c278cffbb2de148ec4016b07b96ae683",
"dist/2024-02-04/rust-std-beta-x86_64-apple-ios.tar.gz": "ac0ed15c9d62aaf8ae298def444cd5cd06a1701564fab564d4a4c767c294c1a1",
"dist/2024-02-04/rust-std-beta-x86_64-apple-ios.tar.xz": "57171af9b001f9b0ebd66c7643cb0a93e752320f188b6948b261abf27179360d",
"dist/2024-02-04/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "29efc21fac21062e5a0af8f2431be998cd949b12e1f73b569967e9aee68bcefa",
"dist/2024-02-04/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "d1d290ac8ddf7ec133fe1de3e5307855a86dd5780a434091198294d18194869b",
"dist/2024-02-04/rust-std-beta-x86_64-linux-android.tar.gz": "1f3a99d4d9f9283e62d9922145b63bb6ca58744eca51d3ba28277b6ae2581fdf",
"dist/2024-02-04/rust-std-beta-x86_64-linux-android.tar.xz": "34f8d2ef07c40b34d8893f93f42d9f06bde8d56c146ec1b6518a497fd68e6ca0",
"dist/2024-02-04/rust-std-beta-x86_64-pc-solaris.tar.gz": "e15b87f78925ee15b3c71c6f3cdc0cff12dd06369be53402d7115300c07e316d",
"dist/2024-02-04/rust-std-beta-x86_64-pc-solaris.tar.xz": "4f5a353057ec31568f3403c01d30d1d3aa22721be942c61928634c5e10332ce0",
"dist/2024-02-04/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "898e9bacfd9fc7f34a7543066304f4f5dd3596ef37d4a3b3bac5524ffd6ef236",
"dist/2024-02-04/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "3a4cf02b56049bb998aea963651c0c26e8084bb4232c2efa8be14740836c4da1",
"dist/2024-02-04/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "3d2d2896d535374396e3cd5b71b4135baf5a5ae2aaecc591981127dcb7717555",
"dist/2024-02-04/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "2b3a4329cd34ae5d61f0ce8712e5e73cfa9e11a6b861f7e796a2055533f8e1a1",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "a89890d16282ba9c030e32c5904117be8317c69fce09611bf8ebff440d13a1fb",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "a02a5962c65cbe60667a45d5ad5ec28f1dc86d18344c619fba00f9afd96519e1",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "1dc8c719ac47a37c47993b75e1b1280579504bb01bf3feb39b30a10b947b75ff",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "106c9d4fd1072dfbacb67674a2b0753c9742fb87e83ff32cf3ad3ce1f8d94874",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-illumos.tar.gz": "a004aab7ce4f922afa7248af5fa17fd1966a9e79b472ae4ea9496e7915bbf0f3",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-illumos.tar.xz": "0f3df2ea274c6bf201617c5b385b0e7752077e6497a3dd49f45f2431e3f2af38",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "b929350cb8aef37ac3a32f06c144cbd75884f60b26ec9316c1f675a472f1c522",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "20fffbd0d4e5bb19a428c2c808aa47f6d7a285291df204fe73a45f7d3720c3a4",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "383746f4d90d7dbca5297928bf5705d50f974ac3c97fe4dadd6ec33b5aa65059",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "60372cc7f84c6727272360ae1fdc316376ec12f632365a8deb9420f953cece2f",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "2fb0649206c57187b216464d6db86cbb4385e061098348181d654976570f74c4",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "6a22fa944f66afdc4af68d25f37b88f80dec10211e808965e0f9a41f7a5e18b6",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "3700739a966b4e9e12088518d22ff535065f666c6f8c74fc8384fb183f4e8fe5",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "b6561834aa28caad3b68248863834e8320ee43916488336f575a6860efb1a509",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-none.tar.gz": "7a56f666a6b42b666afc12555f3b82c0877c2c3beedba53037d8a66ea0ab2c8e",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-none.tar.xz": "3f8a61eb7a7015b639769d9cee9b78653b0efe4da1333b315a67982e88ed2f54",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-redox.tar.gz": "4b3aebbaced9a09de3d2b1d745d53feec2b927e0ae15ee822cc57b003f4cdb6b",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-redox.tar.xz": "69d286adaba6f18daf052156cf88e994bee40b3e8a9c467d51b3f7264e8c5882",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-uefi.tar.gz": "0dc258a276435d1a689d1067913573a4454d5b0e54e90304338f07b0cb6b7c68",
"dist/2024-02-04/rust-std-beta-x86_64-unknown-uefi.tar.xz": "ca131284758bfd1defac4e95b68dba9bdb496b2a1ed4312b05ce996308d870b1",
"dist/2024-02-04/rustc-beta-aarch64-apple-darwin.tar.gz": "f874ba6539750fc510fa67749f6a341c80497a0ea7ace5b8366849fb3a304973",
"dist/2024-02-04/rustc-beta-aarch64-apple-darwin.tar.xz": "8a1a9359e59c7057a39eeaaa6bbb180b61e00993d534b63b52ac447b31345886",
"dist/2024-02-04/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "449e0a684783ba2ad04e4aa18761da9ee4144333426335b0503526d7d0c23f3e",
"dist/2024-02-04/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "4075cbd97eceae6ba41a2862a6149f72c33ddd351c6cdf8e401de19b485ae3e2",
"dist/2024-02-04/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "99a1c8fcc434905b80086d276dbb162105d7803f8594a44b518245877320e387",
"dist/2024-02-04/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "32ab0d6814abbb16724ea6d7d422fea587fa8d4fb7e49d04c418e9f58c380464",
"dist/2024-02-04/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "04dec9fdfa8429ed3b53aac9445a54a4a486d1c4439d91e3c5214c62207163c8",
"dist/2024-02-04/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "797f8ed5112414d258de8b28f0d1d85661fa35ae0699ad89a868d7f16123e5e0",
"dist/2024-02-04/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "31c3ad00fd019cdda335630da3791633f28b79a84d847404e877efa1d963b700",
"dist/2024-02-04/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "265de8a5d1317fd686497ddcbd47adc96270b9318333296edbe57247907cea87",
"dist/2024-02-04/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "080f20064ce64e26b35d15c0bcefd20edc37f0f4627eec997fefb99932635687",
"dist/2024-02-04/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "aa144f7121a29087a6b6e057a646fa091ec7af5b48b2701c7bb514c698d510e4",
"dist/2024-02-04/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "bf1f0a9764e04d9d07702ba7563c93ec17ae527332d72b4e21d8de9bd176c4c5",
"dist/2024-02-04/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "17ed4d2cac212fcfbe1c75c482f195100ee2fabcdd85cedf78b5ea8f1355148b",
"dist/2024-02-04/rustc-beta-i686-pc-windows-gnu.tar.gz": "fa0e1ad64cf3b59682df001192c91c26edf1d41fda8f0fb3a6c535fa1597098f",
"dist/2024-02-04/rustc-beta-i686-pc-windows-gnu.tar.xz": "3f5eb74282649ed398d8a60bda4098ea8ec10b81a00cc48c65976f68d064ba6a",
"dist/2024-02-04/rustc-beta-i686-pc-windows-msvc.tar.gz": "188f1c8c1b38ece4b50db74422ab7d4b8dc40d5ee2f9a10ad2a797ea748f4ce0",
"dist/2024-02-04/rustc-beta-i686-pc-windows-msvc.tar.xz": "b9768ef55563ba4008b5886e6b20b7dfb81668452f264cf4cf9809e6fa3e1d84",
"dist/2024-02-04/rustc-beta-i686-unknown-linux-gnu.tar.gz": "c369728545e027cdaf9b92243f98979e66684d79159192ee7a22a62603905942",
"dist/2024-02-04/rustc-beta-i686-unknown-linux-gnu.tar.xz": "ec946c31d336a69912f6f0effa0986532dbdd915a1b268c419e5ba68365671fe",
"dist/2024-02-04/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "f49cac3db11d02f6b197354b25e2181ae7afd13837df3bccca8cda135373ae6d",
"dist/2024-02-04/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "b4ffc655994a64dd5644a30363e0518a2958337f187da7e4a9285658c899ab6b",
"dist/2024-02-04/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "b29c64744cc8154e1eb89ec525fbc92187b666d1f7d013523d0f7e6c089b5be9",
"dist/2024-02-04/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "5534dba963a2ae299f16b85c1fb76bfd62e94e4c9da16a97aaec26572b61f217",
"dist/2024-02-04/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "a432e73044ffa25fb6c104a82156048519f79faa6e1845e5e0d5ef448d1d682d",
"dist/2024-02-04/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "aa1688326584956677dd76c0e3620e34a3287c077b882b5b159e0d756cbf189b",
"dist/2024-02-04/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "8534f8087cbbf9f4f44f43cc8c276dba304aa0b5f9ea437cfa162d667aef1774",
"dist/2024-02-04/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "12bcba399fbff493b114bb4726a6b3fe32936a1f42134b1496b6ce44baea52dc",
"dist/2024-02-04/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "5ca25bc3c268c3df4de1740fd62f5dfb62482833be38180aa34bf220b9ec3021",
"dist/2024-02-04/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "e7187288ac175404c2a3e78776324e70c2a0d3b6fb673366eac881a48f11ab74",
"dist/2024-02-04/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "31735567bd85a94325af81e5029c652c8b1b2e5824c4f65fa48f864aca65393e",
"dist/2024-02-04/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "916afb19bb784d80093a372fa6316c72d2fa1aee3aa038554a3335ae3f62f773",
"dist/2024-02-04/rustc-beta-x86_64-apple-darwin.tar.gz": "d1445ab2c427e1e504521047c5e1e8d43b43dc4bb9dcf859e3d8b0110a6de257",
"dist/2024-02-04/rustc-beta-x86_64-apple-darwin.tar.xz": "cafb899caeec207a7e2842f03210b85d50d09f152468ab9ec1e53fa8c7511da1",
"dist/2024-02-04/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "eab3692edecd9957cbd0e2f8fe148ee81600ddde9d07e7693859bd2943784b49",
"dist/2024-02-04/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "4b711b2375c16990d9f22ca32baedf8b0d57073d914ea392028944a019a7e4cb",
"dist/2024-02-04/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "80de1f677bbf1d1c51fcabe130b81dd97cc49fcacc96bc9dbda94da1acf4d504",
"dist/2024-02-04/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "912e3ab500ed82ecca7688bbb7c5c40555cbb4d5ea9ec059a9287f69ca7241ab",
"dist/2024-02-04/rustc-beta-x86_64-unknown-freebsd.tar.gz": "632ba8e019403eddde89653cd4bf1864fd0b274603399371871cd1ded296d1d9",
"dist/2024-02-04/rustc-beta-x86_64-unknown-freebsd.tar.xz": "b5de56f1f686befd7d225c4fc0636132119a28e6ed22e56300347e8c8fd4388b",
"dist/2024-02-04/rustc-beta-x86_64-unknown-illumos.tar.gz": "f906f3492094d609d8d5fb5a563a8f2201dc21c65228c7d214a57ea795e8bca5",
"dist/2024-02-04/rustc-beta-x86_64-unknown-illumos.tar.xz": "4f29c6a41a993794dfdca0502c33ef77a3a888281c3b9e368f1befdfecc643e2",
"dist/2024-02-04/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "ce323665ebe9bc3d96e7016af21e18788e42e94c647ff1c08cdeb6ad9acc3b1c",
"dist/2024-02-04/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "6db29020afc7fb486f305e3508ee978c2ce44ce9b844ec6fe0102a16c798dc13",
"dist/2024-02-04/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "b5b5dd243653e8f1073542774c918152eeb73020859dcc3229045b1980d50bae",
"dist/2024-02-04/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "f8127a732817b1d5c091f7a508c3d5367b33e57ea6be023161be1bcc35b3b62d",
"dist/2024-02-04/rustc-beta-x86_64-unknown-netbsd.tar.gz": "73b19bc4dc2f44a04cae327ddc4740915bffb0a2182ff94438c614dce3b5ddf2",
"dist/2024-02-04/rustc-beta-x86_64-unknown-netbsd.tar.xz": "d72e53f0a99a897d5f36999957fee251d67030fbf711b1b8d554011ad0a7e559",
"dist/2024-02-04/rustc-nightly-aarch64-apple-darwin.tar.gz": "f81993a7d1c0677779a6a44ec1f475abb03e8c79ec493cb22ff194b0d6edfc2b",
"dist/2024-02-04/rustc-nightly-aarch64-apple-darwin.tar.xz": "a6247fae04e79529097f2ff5b9c8110ce4f015ba5f9503fbcd0c15c8ba84eb9e",
"dist/2024-02-04/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "012a0b1eff9a277c8b7dc01204346922f64099450269716dafe8c7d257bdc043",
"dist/2024-02-04/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "d16d3c5da39586678fa34932f597294277d1949ff57b99e67ce5b4dcfda9ffc6",
"dist/2024-02-04/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "defca5334cffc68e2b79917455ac7e8e210870794f23189ac0a8fdab7cfd7364",
"dist/2024-02-04/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "2c0af5b6a06fc2e539ad0774b95f021dfbd75730d900d13567ea8ee757f9ecb1",
"dist/2024-02-04/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "93bebac9baaf10f90b535a46f8a33abe55b2d468d7ec27ae53ac6ff31afe2833",
"dist/2024-02-04/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "937f84bf311714bccc88ef1e982e3261e04e5fc5419de098fbc65df15df3975c",
"dist/2024-02-04/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "87d8a6dc5ad4103eea1cf5ee76858b4e78188302fbb6e0ac846f284b388f8e7a",
"dist/2024-02-04/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "74878a2b70a1476588a5638b953711bd62c25027a9555d10e6fd4e5218a7d817",
"dist/2024-02-04/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "1fb50fa12f3c412e30df241ac6215a19bb600a04a1fb3332434f9c73bc7d2b74",
"dist/2024-02-04/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "85807b419b6f45493c60f3ab3f5d00fe7ffaca6366e6a0ec57227a30ffae2f22",
"dist/2024-02-04/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "63d233d9ac741f842c21762032ec4f0139a9b46cc8a4785bfc1b9ad6b586a128",
"dist/2024-02-04/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "199b00d4bb829f9688cbc9e8fa065d80ef4d20c1723c39f4b1a61ebfc544bc88",
"dist/2024-02-04/rustc-nightly-i686-pc-windows-gnu.tar.gz": "e66c39fbd427b6cfd027095110c954035e5a3d117b848c7cc072ca93f41bcbcb",
"dist/2024-02-04/rustc-nightly-i686-pc-windows-gnu.tar.xz": "9974067580a9d77f4722914c0d60dcb2e451cdb9c059514982bbf4721bd62ce5",
"dist/2024-02-04/rustc-nightly-i686-pc-windows-msvc.tar.gz": "e8189dd6c054dc1cba690a9805593d173de64009166b4542c30cd902cb82537a",
"dist/2024-02-04/rustc-nightly-i686-pc-windows-msvc.tar.xz": "5b9bc862dbf5bf00accf769fd70b9915c4a0faad7fc8ca648789aeefbb7f5ba6",
"dist/2024-02-04/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "b0eebf6d08c9f730458f444afd15d405465adbf2dffe93bf9a042f28d11851e4",
"dist/2024-02-04/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "248c1ecddaddee7dbdf3eabcb4a1b645005103b0ee0659d1bc71b5a59c1c9e4b",
"dist/2024-02-04/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "ea139b005b21e1baed7f79944af6cb2d8f24ac8c7bb009474e3a578250c6a65a",
"dist/2024-02-04/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "a3601a3bdc6bb998fe8a6a9ade212179addbbb684c0c47c46cb1c0632ab9fe41",
"dist/2024-02-04/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "d64bffffff505541789ab0395187506c916f5b239ef3d0875dbb0f0c79c575e8",
"dist/2024-02-04/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "5e1c528da9fa9818e5f581342346fa30b99d073dbce2241b4ebecfb7cf9674a7",
"dist/2024-02-04/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "0603be408a0bc368f669eb193c115bca687d7d6d1026fca6de5d317acb3597da",
"dist/2024-02-04/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "f61303e16f16c61f89e8dda24a5706808ef79f5fce7da8ee36b7aa3ec70f66f1",
"dist/2024-02-04/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "288e7b6b31aff284f06b14f1eb4ea0b2547aa019e8865d05710a64fe9993ddb2",
"dist/2024-02-04/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "885ef5324a55e78557b290bdf10501e27763daec209ad56f2e1840435a6e944b",
"dist/2024-02-04/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "3ccf5a674d290e1ede918516002d0b626828299edb7fe87dfc128cc9afa9770c",
"dist/2024-02-04/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "374a74c1b950f4be741f69d7f2670ac0d037a2a657361b94cd1c32892481edec",
"dist/2024-02-04/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "f21d304ea482d889319f285b5246f44461acdf6dabe288962065441bea82186b",
"dist/2024-02-04/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "d617d2b45de255f4588c2a9dc9686be554113b2683b8d8b149d1ce128da2dcc3",
"dist/2024-02-04/rustc-nightly-x86_64-apple-darwin.tar.gz": "26c662009b90638796c48a72de57e64e994491754112c5d6af0a65d24f4ef149",
"dist/2024-02-04/rustc-nightly-x86_64-apple-darwin.tar.xz": "811acb173348408b59b1ad63e0d2f8cbeccb91a86f13b432a6b70e8d6ebae937",
"dist/2024-02-04/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "3cd84e215365e8eba1aec1c6ed630e8899b1dcb36d04d52f1fbb713150eb60cd",
"dist/2024-02-04/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "454f0b75e6dd0bd893413dc7e2f36170d3af041e1e2b7d4792cc61f7cd7f27e2",
"dist/2024-02-04/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "512a0922ee16c4d5264b7ea398788651d04910dcdb3edd87bd8fc3914855c29c",
"dist/2024-02-04/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "e5a43c30c0016728aaff405ef3e28eefd8b60eb878fc31a5038aa056ae8cfb1f",
"dist/2024-02-04/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "0330724ffe7c0d4b3ed38514c303b1cbed3deb0e074e8d36f7de96c469c0c51d",
"dist/2024-02-04/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "5159bb4b9e32f64ed4712ab52dcc373e4838cec0f8e5bc16b281481a828dc84e",
"dist/2024-02-04/rustc-nightly-x86_64-unknown-illumos.tar.gz": "d8bdb12e09d76f4b4ebe9f089a6bc11f501e994ef23aefe7574b5c5a583fd2fc",
"dist/2024-02-04/rustc-nightly-x86_64-unknown-illumos.tar.xz": "301584763ea946532eca1e5be8ff7b7587ac9066c8f047f90598158e1ae6f5cf",
"dist/2024-02-04/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "3f4d36a06c74d62bb097e4b94b4ab1caf3d8d63650e0e4ef038748dab13c4413",
"dist/2024-02-04/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "33446798bf2f60451e31376286da2ad62372ef5ec048453900f6e6b3c4f0f0ee",
"dist/2024-02-04/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "9a1fc786d418a927a63ceae0999e641767de5cc8821fc57dbe0546f495d21600",
"dist/2024-02-04/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "0a36838259d73d577126cdee909b6446d62730d0d13655442312fca9cd13ce84",
"dist/2024-02-04/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "30e91ca5a0389898d9eea8a063b52dc4dd5e7f8cafba1024fbbf1d80ab28c590",
"dist/2024-02-04/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "49238b11b1626dcfc8bebf02912935922585bfdce777c8eb7bf5abfabe664af0",
"dist/2024-02-04/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "4e7d77d6a66ff3bf1de608913429e78a87ff80d8260e078d7e866a09b6ed74cc",
"dist/2024-02-04/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "ebb64953e7919ff371b1625e48cd7c9063fc7fc72f085603831ed7a1eef371d3",
"dist/2024-02-04/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "44bb652d0268e03bc333ccc90f96107e249ee3d96a688aac1f3a27161c62a176",
"dist/2024-02-04/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "e272d2633828e00ebf0a1708b807fa958cac2673b162637c4983a40f191574e7",
"dist/2024-02-04/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "aa9b56b48fda4844f56bd7a0073c91b5aa79215f61444346e9849036ba003252",
"dist/2024-02-04/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "b23367c99e79d2db72b16d9d77addd3790ddf0889987beb24c917e4e54bcf511",
"dist/2024-02-04/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "c001dba171255113d25c2e2743ca2b4cb36aa0a628da333911b92474ae8e6603",
"dist/2024-02-04/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "14a2b8a352b1fc0c6c993c5a51cf4d23ed50b6b14b092f78917808861dc4ac49",
"dist/2024-02-04/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "ec2e8f55671b1d9643d338530263feb47f99d81ff7c862ac46ad32b8459b6435",
"dist/2024-02-04/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "10b957fc066da91fa81eeeca66e2f7c97c7e7fc9d496471fd22b086a9e2bb62e",
"dist/2024-02-04/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "1dd859841cea9ac9d09a1521c57ddbe042bdc693c7df60ff34c876a8faca3745",
"dist/2024-02-04/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "b11ca576f29df7c81496c4b379435853a0bfee8ff838d2c57e1e3cded6f889eb",
"dist/2024-02-04/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "e0c53737686587010f4fd299430a0d48e47ad0f3d12e29a5d6810dceabd09b09",
"dist/2024-02-04/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "f70dc356985081a43f19c2cc6e599f2967d9c0a60b2d9be0a3939a04a88b768a",
"dist/2024-02-04/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "159c4a6ebbce05142bf6e844c4e6cfc9a90eb298f581db7521ea5fb1fd303731",
"dist/2024-02-04/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "8cb69a4ff1207c0b7944dd71e1af666e12be5c8ec0d0ec244b2e4d9b99535f29",
"dist/2024-02-04/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "0eb4218c6d271c194282ca11af2436e2ed2e51ee3b62725a04a995afb3bc6ff9",
"dist/2024-02-04/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "2f9e4d03968cf07b950d188135d231d1183d92520c76a4ded3973acb374bdefc",
"dist/2024-02-04/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "b6648b637564ffe5cf79da7c7eb73df377a2d0e0e0c66a05806af4fc87f61afa",
"dist/2024-02-04/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "09e2aae1c73f874ce4dbdb84d532264cc21d99444e0b7b1e9239a002fe0c2466",
"dist/2024-02-04/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "87bfeb0da3af4ad9f341482325b81d13691e749b73627eabe7c73ac5bcd126e3",
"dist/2024-02-04/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "2bf074d90957c17e3d8962dd8ab68d0a76f4deaf86f1104cce56d2748fc21b3a",
"dist/2024-02-04/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "7fe5ee7ce30a1fbe5c5c0f20ef311f5840eebc9466e7c4bb2082a12bad2d987c",
"dist/2024-02-04/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "43c3d64ed01e56c1961dbcde4d9c2c14a799d141d6c00ac72500ac84aafaf696",
"dist/2024-02-04/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "d6a54980ef61acb4f2422f0f621a6168055df95720fd864b58748884606e8a6b",
"dist/2024-02-04/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "d0d9fa1a65ef6dcf0d1fa1496d1682ca627cb978a8bf4a68ab3f27060daa37ed",
"dist/2024-02-04/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "fcd0539279be6ee5f2ed11f1ae0879596a29804d2415398a016b26aa1683f08a",
"dist/2024-02-04/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "cfceea6563230c64b4e77110e98dc41208c6d50b3d4bce3133abd7f66db5ce29",
"dist/2024-02-04/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "6559653ef0a9b2d52baa94f6fd14433769b3001401daac03536ad0d1528418c1",
"dist/2024-02-04/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "ac1c4f99a801e853c175735338a5485de2ad21ff633da75ced8b11ccd86ecd68",
"dist/2024-02-04/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "33835f14d65e2c21c1b69a45c70c89939a37b4d5b07660ef2acbba033c7bc8a1",
"dist/2024-02-04/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "46b8eb78bc1842b66e14e1995359cd85349ad2fd30a5b5c3a369de346dad8fa1",
"dist/2024-02-04/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "d7f0bb3f2e4d6cd6c68817cd99ef7cdd95ca274e86866edb9b76bfad071ccf37",
"dist/2024-02-04/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "7d86a0aeba42a5571b01ca7008c38854e17c067c53794c34d18ebc1cad536ae8",
"dist/2024-02-04/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "5b788121f69bc0e16dabb014d7efaef4855d20016d2d710e6bf0e35dfc16d5b0",
"dist/2024-02-04/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "b4b4ad7ecd280001aff71cf264f465e47effe52260c95fb23c884ab5fe4d51a8",
"dist/2024-02-04/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "6075688bb91902af0c114fe9619a0102f57641bf88b8902eb950f9d324bf5a25",
"dist/2024-02-04/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "908068a7088b20c1dc52eaefb9aa4314233536c40520b491e55a555283b243ce",
"dist/2024-02-04/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "5a9af3515b1b142127a9686b4f41d4c8050a496e0387a2a2703fe092bffaeb68",
"dist/2024-02-04/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "6796dbdeadd39bc66686bbdf9966fc488684543f806c25315c3a682c4c989c58",
"dist/2024-02-04/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "4f763f33318529e1d400d2058b8ff8de6d29e37de0744a8e0ae17ae677465c81",
"dist/2024-02-04/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "18aa04c9e8d00593f11b5e593a64875197e3db7de752215882d247a39c71ef0d",
"dist/2024-02-04/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "5be7c353d1e1f8445936f1572b5d99ca190a914c71341bb855048c5003c0cda2",
"dist/2024-02-04/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "1342bf737bba2e9787203da78d859f40739af4c57e9ec5bc0e07966e91388813",
"dist/2024-02-04/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "0776b76ae5338f186f631a1f0e6f755d03612892399d96f3c2d9c59ba9f094c3",
"dist/2024-02-04/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "36d491cc2eb35250536d3b053d180835c8041d9f6ed96f243c04e9644d040c96",
"dist/2024-02-04/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "185e2dee21941bc4c3e8edcf5f12d334b2c339f3f388f182a8ae519928e907e4",
"dist/2024-02-04/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "d770b13ad43852d6e91bea1747b6e82b1cddc716307f8df4dd95941df76a1355"
}
}

15
src/tools/clippy/.github/driver.sh vendored Normal file → Executable file
View file

@ -11,9 +11,16 @@ if [[ ${OS} == "Windows" ]]; then
else
desired_sysroot=/tmp
fi
# Set --sysroot in command line
sysroot=$(./target/debug/clippy-driver --sysroot $desired_sysroot --print sysroot)
test "$sysroot" = $desired_sysroot
# Set --sysroot in arg_file.txt and pass @arg_file.txt to command line
echo "--sysroot=$desired_sysroot" > arg_file.txt
sysroot=$(./target/debug/clippy-driver @arg_file.txt --print sysroot)
test "$sysroot" = $desired_sysroot
# Setting SYSROOT in command line
sysroot=$(SYSROOT=$desired_sysroot ./target/debug/clippy-driver --print sysroot)
test "$sysroot" = $desired_sysroot
@ -24,6 +31,14 @@ test "$sysroot" = $desired_sysroot
SYSROOT=/tmp RUSTFLAGS="--sysroot=$(rustc --print sysroot)" ../target/debug/cargo-clippy clippy --verbose
)
# Check that the --sysroot argument is only passed once via arg_file.txt (SYSROOT is ignored)
(
echo "fn main() {}" > target/driver_test.rs
echo "--sysroot="$(./target/debug/clippy-driver --print sysroot)"" > arg_file.txt
echo "--verbose" >> arg_file.txt
SYSROOT=/tmp ./target/debug/clippy-driver @arg_file.txt ./target/driver_test.rs
)
# Make sure this isn't set - clippy-driver should cope without it
unset CARGO_MANIFEST_DIR

View file

@ -6,11 +6,65 @@ document.
## Unreleased / Beta / In Rust Nightly
[09ac14c9...master](https://github.com/rust-lang/rust-clippy/compare/09ac14c9...master)
[a859e5cc...master](https://github.com/rust-lang/rust-clippy/compare/a859e5cc...master)
## Rust 1.76
Current stable, released 2024-02-08
[View all 85 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-11-02T20%3A23%3A40Z..2023-12-16T13%3A11%3A08Z+base%3Amaster)
### New Lints
- [`infinite_loop`]
[#11829](https://github.com/rust-lang/rust-clippy/pull/11829)
- [`ineffective_open_options`]
[#11902](https://github.com/rust-lang/rust-clippy/pull/11902)
- [`uninhabited_references`]
[#11878](https://github.com/rust-lang/rust-clippy/pull/11878)
- [`repeat_vec_with_capacity`]
[#11597](https://github.com/rust-lang/rust-clippy/pull/11597)
- [`test_attr_in_doctest`]
[#11872](https://github.com/rust-lang/rust-clippy/pull/11872)
- [`option_map_or_err_ok`]
[#11864](https://github.com/rust-lang/rust-clippy/pull/11864)
- [`join_absolute_paths`]
[#11453](https://github.com/rust-lang/rust-clippy/pull/11453)
- [`impl_hash_borrow_with_str_and_bytes`]
[#11781](https://github.com/rust-lang/rust-clippy/pull/11781)
- [`iter_over_hash_type`]
[#11791](https://github.com/rust-lang/rust-clippy/pull/11791)
### Moves and Deprecations
- Renamed `blocks_in_if_conditions` to [`blocks_in_conditions`]
[#11853](https://github.com/rust-lang/rust-clippy/pull/11853)
- Moved [`implied_bounds_in_impls`] to `complexity` (Now warn-by-default)
[#11867](https://github.com/rust-lang/rust-clippy/pull/11867)
- Moved [`if_same_then_else`] to `style` (Now warn-by-default)
[#11809](https://github.com/rust-lang/rust-clippy/pull/11809)
### Enhancements
- [`missing_safety_doc`], [`unnecessary_safety_doc`], [`missing_panics_doc`], [`missing_errors_doc`]:
Added the [`check-private-items`] configuration to enable lints on private items
[#11842](https://github.com/rust-lang/rust-clippy/pull/11842)
### ICE Fixes
- [`impl_trait_in_params`]: No longer crashes when a function has generics but no function parameters
[#11804](https://github.com/rust-lang/rust-clippy/pull/11804)
- [`unused_enumerate_index`]: No longer crashes on empty tuples
[#11756](https://github.com/rust-lang/rust-clippy/pull/11756)
### Others
- Clippy now respects the `CARGO` environment value
[#11944](https://github.com/rust-lang/rust-clippy/pull/11944)
## Rust 1.75
Current stable, released 2023-12-28
Released 2023-12-28
[View all 69 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-09-25T11%3A47%3A47Z..2023-11-02T16%3A41%3A59Z+base%3Amaster)
@ -5198,6 +5252,7 @@ Released 2018-09-13
[`implied_bounds_in_impls`]: https://rust-lang.github.io/rust-clippy/master/index.html#implied_bounds_in_impls
[`impossible_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#impossible_comparisons
[`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#imprecise_flops
[`incompatible_msrv`]: https://rust-lang.github.io/rust-clippy/master/index.html#incompatible_msrv
[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping
[`inconsistent_struct_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor
[`incorrect_clone_impl_on_copy_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_clone_impl_on_copy_type
@ -5276,6 +5331,7 @@ Released 2018-09-13
[`let_with_type_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_with_type_underscore
[`lines_filter_map_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok
[`linkedlist`]: https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist
[`lint_groups_priority`]: https://rust-lang.github.io/rust-clippy/master/index.html#lint_groups_priority
[`little_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#little_endian_bytes
[`logic_bug`]: https://rust-lang.github.io/rust-clippy/master/index.html#logic_bug
[`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal
@ -5284,6 +5340,7 @@ Released 2018-09-13
[`manual_assert`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert
[`manual_async_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn
[`manual_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits
[`manual_c_str_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals
[`manual_clamp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp
[`manual_filter`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter
[`manual_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter_map
@ -5523,6 +5580,7 @@ Released 2018-09-13
[`redundant_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing
[`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes
[`redundant_type_annotations`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_type_annotations
[`ref_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_as_ptr
[`ref_binding_to_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_binding_to_reference
[`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref
[`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option_ref
@ -5622,6 +5680,7 @@ Released 2018-09-13
[`to_digit_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some
[`to_string_in_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_display
[`to_string_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_format_args
[`to_string_trait_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_trait_impl
[`todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo
[`too_many_arguments`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments
[`too_many_lines`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines
@ -5677,6 +5736,7 @@ Released 2018-09-13
[`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed
[`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation
[`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_owned_empty_strings
[`unnecessary_result_map_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_result_map_or_else
[`unnecessary_safety_comment`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_comment
[`unnecessary_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc
[`unnecessary_self_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_self_imports
@ -5819,4 +5879,6 @@ Released 2018-09-13
[`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
[`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
[`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
[`allow-comparison-to-zero`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-comparison-to-zero
[`allowed-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-wildcard-imports
<!-- end autogenerated links to configuration documentation -->

View file

@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.1.77"
version = "0.1.78"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"

View file

@ -151,6 +151,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
* [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold)
* [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one)
* [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map)
* [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals)
## `cognitive-complexity-threshold`
@ -828,3 +829,35 @@ exported visibility, or whether they are marked as "pub".
* [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields)
## `allow-comparison-to-zero`
Don't lint when comparing the result of a modulo operation to zero.
**Default Value:** `true`
---
**Affected lints:**
* [`modulo_arithmetic`](https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic)
## `allowed-wildcard-imports`
List of path segments allowed to have wildcard imports.
#### Example
```toml
allowed-wildcard-imports = [ "utils", "common" ]
```
#### Noteworthy
1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.
2. Paths with any segment that containing the word 'prelude'
are already allowed by default.
**Default Value:** `[]`
---
**Affected lints:**
* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports)

View file

@ -1,6 +1,6 @@
[package]
name = "clippy_config"
version = "0.1.77"
version = "0.1.78"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -260,7 +260,7 @@ define_Conf! {
///
/// Suppress lints whenever the suggested change would cause breakage for other crates.
(avoid_breaking_exported_api: bool = true),
/// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP.
/// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP, MANUAL_C_STR_LITERALS.
///
/// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
#[default_text = ""]
@ -567,6 +567,26 @@ define_Conf! {
/// Lint "public" fields in a struct that are prefixed with an underscore based on their
/// exported visibility, or whether they are marked as "pub".
(pub_underscore_fields_behavior: PubUnderscoreFieldsBehaviour = PubUnderscoreFieldsBehaviour::PubliclyExported),
/// Lint: MODULO_ARITHMETIC.
///
/// Don't lint when comparing the result of a modulo operation to zero.
(allow_comparison_to_zero: bool = true),
/// Lint: WILDCARD_IMPORTS.
///
/// List of path segments allowed to have wildcard imports.
///
/// #### Example
///
/// ```toml
/// allowed-wildcard-imports = [ "utils", "common" ]
/// ```
///
/// #### Noteworthy
///
/// 1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.
/// 2. Paths with any segment that containing the word 'prelude'
/// are already allowed by default.
(allowed_wildcard_imports: FxHashSet<String> = FxHashSet::default()),
}
/// Search for the configuration file.

View file

@ -4,7 +4,9 @@
#![allow(
clippy::must_use_candidate,
clippy::missing_panics_doc,
rustc::untranslatable_diagnostic_trivial
rustc::diagnostic_outside_of_impl,
rustc::untranslatable_diagnostic,
rustc::untranslatable_diagnostic_trivial,
)]
extern crate rustc_ast;

View file

@ -3,6 +3,7 @@ use rustc_semver::RustcVersion;
use rustc_session::Session;
use rustc_span::{sym, Symbol};
use serde::Deserialize;
use std::fmt;
macro_rules! msrv_aliases {
($($major:literal,$minor:literal,$patch:literal {
@ -16,6 +17,8 @@ macro_rules! msrv_aliases {
// names may refer to stabilized feature flags or library items
msrv_aliases! {
1,77,0 { C_STR_LITERALS }
1,76,0 { PTR_FROM_REF }
1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }
1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN }
1,68,0 { PATH_MAIN_SEPARATOR_STR }
@ -58,6 +61,16 @@ pub struct Msrv {
stack: Vec<RustcVersion>,
}
impl fmt::Display for Msrv {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(msrv) = self.current() {
write!(f, "{msrv}")
} else {
f.write_str("1.0.0")
}
}
}
impl<'de> Deserialize<'de> for Msrv {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where

View file

@ -1,6 +1,6 @@
[package]
name = "clippy_lints"
version = "0.1.77"
version = "0.1.78"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"

View file

@ -62,7 +62,7 @@ impl LateLintPass<'_> for AbsolutePaths {
} = self;
if !path.span.from_expansion()
&& let Some(node) = cx.tcx.opt_hir_node(hir_id)
&& let node = cx.tcx.hir_node(hir_id)
&& !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(_, _)))
&& let [first, rest @ ..] = path.segments
// Handle `::std`

View file

@ -499,6 +499,7 @@ struct NotSimplificationVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for NotSimplificationVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind
&& !expr.span.from_expansion()
&& !inner.span.from_expansion()
&& let Some(suggestion) = simplify_not(self.cx, inner)
&& self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow

View file

@ -0,0 +1,168 @@
use super::LINT_GROUPS_PRIORITY;
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_lint::{unerased_lint_store, LateContext};
use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::ops::Range;
use std::path::Path;
use toml::Spanned;
#[derive(Deserialize, Serialize, Debug)]
struct LintConfigTable {
level: String,
priority: Option<i64>,
}
#[derive(Deserialize, Debug)]
#[serde(untagged)]
enum LintConfig {
Level(String),
Table(LintConfigTable),
}
impl LintConfig {
fn level(&self) -> &str {
match self {
LintConfig::Level(level) => level,
LintConfig::Table(table) => &table.level,
}
}
fn priority(&self) -> i64 {
match self {
LintConfig::Level(_) => 0,
LintConfig::Table(table) => table.priority.unwrap_or(0),
}
}
fn is_implicit(&self) -> bool {
if let LintConfig::Table(table) = self {
table.priority.is_none()
} else {
true
}
}
}
type LintTable = BTreeMap<Spanned<String>, Spanned<LintConfig>>;
#[derive(Deserialize, Debug)]
struct Lints {
#[serde(default)]
rust: LintTable,
#[serde(default)]
clippy: LintTable,
}
#[derive(Deserialize, Debug)]
struct CargoToml {
lints: Lints,
}
#[derive(Default, Debug)]
struct LintsAndGroups {
lints: Vec<Spanned<String>>,
groups: Vec<(Spanned<String>, Spanned<LintConfig>)>,
}
fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
Span::new(
file.start_pos + BytePos::from_usize(range.start),
file.start_pos + BytePos::from_usize(range.end),
SyntaxContext::root(),
None,
)
}
fn check_table(cx: &LateContext<'_>, table: LintTable, groups: &FxHashSet<&str>, file: &SourceFile) {
let mut by_priority = BTreeMap::<_, LintsAndGroups>::new();
for (name, config) in table {
let lints_and_groups = by_priority.entry(config.as_ref().priority()).or_default();
if groups.contains(name.get_ref().as_str()) {
lints_and_groups.groups.push((name, config));
} else {
lints_and_groups.lints.push(name);
}
}
let low_priority = by_priority
.iter()
.find(|(_, lints_and_groups)| !lints_and_groups.lints.is_empty())
.map_or(-1, |(&lowest_lint_priority, _)| lowest_lint_priority - 1);
for (priority, LintsAndGroups { lints, groups }) in by_priority {
let Some(last_lint_alphabetically) = lints.last() else {
continue;
};
for (group, config) in groups {
span_lint_and_then(
cx,
LINT_GROUPS_PRIORITY,
toml_span(group.span(), file),
&format!(
"lint group `{}` has the same priority ({priority}) as a lint",
group.as_ref()
),
|diag| {
let config_span = toml_span(config.span(), file);
if config.as_ref().is_implicit() {
diag.span_label(config_span, "has an implicit priority of 0");
}
// add the label to next lint after this group that has the same priority
let lint = lints
.iter()
.filter(|lint| lint.span().start > group.span().start)
.min_by_key(|lint| lint.span().start)
.unwrap_or(last_lint_alphabetically);
diag.span_label(toml_span(lint.span(), file), "has the same priority as this lint");
diag.note("the order of the lints in the table is ignored by Cargo");
let mut suggestion = String::new();
Serialize::serialize(
&LintConfigTable {
level: config.as_ref().level().into(),
priority: Some(low_priority),
},
toml::ser::ValueSerializer::new(&mut suggestion),
)
.unwrap();
diag.span_suggestion_verbose(
config_span,
format!(
"to have lints override the group set `{}` to a lower priority",
group.as_ref()
),
suggestion,
Applicability::MaybeIncorrect,
);
},
);
}
}
}
pub fn check(cx: &LateContext<'_>) {
if let Ok(file) = cx.tcx.sess.source_map().load_file(Path::new("Cargo.toml"))
&& let Some(src) = file.src.as_deref()
&& let Ok(cargo_toml) = toml::from_str::<CargoToml>(src)
{
let mut rustc_groups = FxHashSet::default();
let mut clippy_groups = FxHashSet::default();
for (group, ..) in unerased_lint_store(cx.tcx.sess).get_lint_groups() {
match group.split_once("::") {
None => {
rustc_groups.insert(group);
},
Some(("clippy", group)) => {
clippy_groups.insert(group);
},
_ => {},
}
}
check_table(cx, cargo_toml.lints.rust, &rustc_groups, &file);
check_table(cx, cargo_toml.lints.clippy, &clippy_groups, &file);
}
}

View file

@ -1,5 +1,6 @@
mod common_metadata;
mod feature_name;
mod lint_groups_priority;
mod multiple_crate_versions;
mod wildcard_dependencies;
@ -165,6 +166,43 @@ declare_clippy_lint! {
"wildcard dependencies being used"
}
declare_clippy_lint! {
/// ### What it does
/// Checks for lint groups with the same priority as lints in the `Cargo.toml`
/// [`[lints]` table](https://doc.rust-lang.org/cargo/reference/manifest.html#the-lints-section).
///
/// This lint will be removed once [cargo#12918](https://github.com/rust-lang/cargo/issues/12918)
/// is resolved.
///
/// ### Why is this bad?
/// The order of lints in the `[lints]` is ignored, to have a lint override a group the
/// `priority` field needs to be used, otherwise the sort order is undefined.
///
/// ### Known problems
/// Does not check lints inherited using `lints.workspace = true`
///
/// ### Example
/// ```toml
/// # Passed as `--allow=clippy::similar_names --warn=clippy::pedantic`
/// # which results in `similar_names` being `warn`
/// [lints.clippy]
/// pedantic = "warn"
/// similar_names = "allow"
/// ```
/// Use instead:
/// ```toml
/// # Passed as `--warn=clippy::pedantic --allow=clippy::similar_names`
/// # which results in `similar_names` being `allow`
/// [lints.clippy]
/// pedantic = { level = "warn", priority = -1 }
/// similar_names = "allow"
/// ```
#[clippy::version = "1.76.0"]
pub LINT_GROUPS_PRIORITY,
correctness,
"a lint group in `Cargo.toml` at the same priority as a lint"
}
pub struct Cargo {
pub allowed_duplicate_crates: FxHashSet<String>,
pub ignore_publish: bool,
@ -175,7 +213,8 @@ impl_lint_pass!(Cargo => [
REDUNDANT_FEATURE_NAMES,
NEGATIVE_FEATURE_NAMES,
MULTIPLE_CRATE_VERSIONS,
WILDCARD_DEPENDENCIES
WILDCARD_DEPENDENCIES,
LINT_GROUPS_PRIORITY,
]);
impl LateLintPass<'_> for Cargo {
@ -188,6 +227,8 @@ impl LateLintPass<'_> for Cargo {
];
static WITH_DEPS_LINTS: &[&Lint] = &[MULTIPLE_CRATE_VERSIONS];
lint_groups_priority::check(cx);
if !NO_DEPS_LINTS
.iter()
.all(|&lint| is_lint_allowed(cx, lint, CRATE_HIR_ID))

View file

@ -68,9 +68,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv
fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let map = cx.tcx.hir();
if let Some(parent_id) = map.opt_parent_id(expr.hir_id)
&& let Some(parent) = cx.tcx.opt_hir_node(parent_id)
{
if let Some(parent_id) = map.opt_parent_id(expr.hir_id) {
let parent = cx.tcx.hir_node(parent_id);
let expr = match parent {
Node::Block(block) => {
if let Some(parent_expr) = block.expr {

View file

@ -18,6 +18,7 @@ mod fn_to_numeric_cast_any;
mod fn_to_numeric_cast_with_truncation;
mod ptr_as_ptr;
mod ptr_cast_constness;
mod ref_as_ptr;
mod unnecessary_cast;
mod utils;
mod zero_ptr;
@ -689,6 +690,30 @@ declare_clippy_lint! {
"using `0 as *{const, mut} T`"
}
declare_clippy_lint! {
/// ### What it does
/// Checks for casts of references to pointer using `as`
/// and suggests `std::ptr::from_ref` and `std::ptr::from_mut` instead.
///
/// ### Why is this bad?
/// Using `as` casts may result in silently changing mutability or type.
///
/// ### Example
/// ```no_run
/// let a_ref = &1;
/// let a_ptr = a_ref as *const _;
/// ```
/// Use instead:
/// ```no_run
/// let a_ref = &1;
/// let a_ptr = std::ptr::from_ref(a_ref);
/// ```
#[clippy::version = "1.77.0"]
pub REF_AS_PTR,
pedantic,
"using `as` to cast a reference to pointer"
}
pub struct Casts {
msrv: Msrv,
}
@ -724,6 +749,7 @@ impl_lint_pass!(Casts => [
AS_PTR_CAST_MUT,
CAST_NAN_TO_INT,
ZERO_PTR,
REF_AS_PTR,
]);
impl<'tcx> LateLintPass<'tcx> for Casts {
@ -771,7 +797,9 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
as_underscore::check(cx, expr, cast_to_hir);
if self.msrv.meets(msrvs::BORROW_AS_PTR) {
if self.msrv.meets(msrvs::PTR_FROM_REF) {
ref_as_ptr::check(cx, expr, cast_expr, cast_to_hir);
} else if self.msrv.meets(msrvs::BORROW_AS_PTR) {
borrow_as_ptr::check(cx, expr, cast_expr, cast_to_hir);
}
}

View file

@ -0,0 +1,55 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_no_std_crate;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg::Sugg;
use rustc_errors::Applicability;
use rustc_hir::{Expr, Mutability, Ty, TyKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, TypeAndMut};
use super::REF_AS_PTR;
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to_hir_ty: &Ty<'_>) {
let (cast_from, cast_to) = (
cx.typeck_results().expr_ty(cast_expr),
cx.typeck_results().expr_ty(expr),
);
if matches!(cast_from.kind(), ty::Ref(..))
&& let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, .. }) = cast_to.kind()
{
let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
let fn_name = match to_mutbl {
Mutability::Not => "from_ref",
Mutability::Mut => "from_mut",
};
let mut app = Applicability::MachineApplicable;
let turbofish = match &cast_to_hir_ty.kind {
TyKind::Infer => String::new(),
TyKind::Ptr(mut_ty) => {
if matches!(mut_ty.ty.kind, TyKind::Infer) {
String::new()
} else {
format!(
"::<{}>",
snippet_with_applicability(cx, mut_ty.ty.span, "/* type */", &mut app)
)
}
},
_ => return,
};
let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app);
span_lint_and_sugg(
cx,
REF_AS_PTR,
expr.span,
"reference as raw pointer",
"try",
format!("{core_or_std}::ptr::{fn_name}{turbofish}({cast_expr_sugg})"),
app,
);
}
}

View file

@ -144,8 +144,7 @@ pub(super) fn check<'tcx>(
if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) {
if let Some(id) = path_to_local(cast_expr)
&& let Some(span) = cx.tcx.hir().opt_span(id)
&& !span.eq_ctxt(cast_expr.span)
&& !cx.tcx.hir().span(id).eq_ctxt(cast_expr.span)
{
// Binding context is different than the identifiers context.
// Weird macro wizardry could be involved here.

View file

@ -71,6 +71,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::borrow_deref_ref::BORROW_DEREF_REF_INFO,
crate::box_default::BOX_DEFAULT_INFO,
crate::cargo::CARGO_COMMON_METADATA_INFO,
crate::cargo::LINT_GROUPS_PRIORITY_INFO,
crate::cargo::MULTIPLE_CRATE_VERSIONS_INFO,
crate::cargo::NEGATIVE_FEATURE_NAMES_INFO,
crate::cargo::REDUNDANT_FEATURE_NAMES_INFO,
@ -96,6 +97,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO,
crate::casts::PTR_AS_PTR_INFO,
crate::casts::PTR_CAST_CONSTNESS_INFO,
crate::casts::REF_AS_PTR_INFO,
crate::casts::UNNECESSARY_CAST_INFO,
crate::casts::ZERO_PTR_INFO,
crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
@ -212,6 +214,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::implicit_saturating_add::IMPLICIT_SATURATING_ADD_INFO,
crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO,
crate::implied_bounds_in_impls::IMPLIED_BOUNDS_IN_IMPLS_INFO,
crate::incompatible_msrv::INCOMPATIBLE_MSRV_INFO,
crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO,
crate::index_refutable_slice::INDEX_REFUTABLE_SLICE_INFO,
crate::indexing_slicing::INDEXING_SLICING_INFO,
@ -384,6 +387,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::methods::ITER_SKIP_ZERO_INFO,
crate::methods::ITER_WITH_DRAIN_INFO,
crate::methods::JOIN_ABSOLUTE_PATHS_INFO,
crate::methods::MANUAL_C_STR_LITERALS_INFO,
crate::methods::MANUAL_FILTER_MAP_INFO,
crate::methods::MANUAL_FIND_MAP_INFO,
crate::methods::MANUAL_IS_VARIANT_AND_INFO,
@ -452,6 +456,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::methods::UNNECESSARY_JOIN_INFO,
crate::methods::UNNECESSARY_LAZY_EVALUATIONS_INFO,
crate::methods::UNNECESSARY_LITERAL_UNWRAP_INFO,
crate::methods::UNNECESSARY_RESULT_MAP_OR_ELSE_INFO,
crate::methods::UNNECESSARY_SORT_BY_INFO,
crate::methods::UNNECESSARY_TO_OWNED_INFO,
crate::methods::UNWRAP_OR_DEFAULT_INFO,
@ -656,6 +661,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::tests_outside_test_module::TESTS_OUTSIDE_TEST_MODULE_INFO,
crate::thread_local_initializer_can_be_made_const::THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST_INFO,
crate::to_digit_is_some::TO_DIGIT_IS_SOME_INFO,
crate::to_string_trait_impl::TO_STRING_TRAIT_IMPL_INFO,
crate::trailing_empty_array::TRAILING_EMPTY_ARRAY_INFO,
crate::trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS_INFO,
crate::trait_bounds::TYPE_REPETITION_IN_BOUNDS_INFO,

View file

@ -195,7 +195,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
&& let Some(def_id) = trait_ref.trait_def_id()
&& cx.tcx.is_diagnostic_item(sym::Default, def_id)
&& let impl_item_hir = child.id.hir_id()
&& let Some(Node::ImplItem(impl_item)) = cx.tcx.opt_hir_node(impl_item_hir)
&& let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)
&& let ImplItemKind::Fn(_, b) = &impl_item.kind
&& let Body { value: func_expr, .. } = cx.tcx.hir().body(*b)
&& let &Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()

View file

@ -226,7 +226,7 @@ declare_clippy_lint! {
/// unimplemented!();
/// }
/// ```
#[clippy::version = "1.40.0"]
#[clippy::version = "1.76.0"]
pub TEST_ATTR_IN_DOCTEST,
suspicious,
"presence of `#[test]` in code examples"

View file

@ -42,7 +42,7 @@ impl LateLintPass<'_> for EmptyDrop {
}) = item.kind
&& trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait()
&& let impl_item_hir = child.id.hir_id()
&& let Some(Node::ImplItem(impl_item)) = cx.tcx.opt_hir_node(impl_item_hir)
&& let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)
&& let ImplItemKind::Fn(_, b) = &impl_item.kind
&& let Body { value: func_expr, .. } = cx.tcx.hir().body(*b)
&& let func_expr = peel_blocks(func_expr)

View file

@ -123,11 +123,11 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
// TODO: Replace with Map::is_argument(..) when it's fixed
fn is_argument(tcx: TyCtxt<'_>, id: HirId) -> bool {
match tcx.opt_hir_node(id) {
Some(Node::Pat(Pat {
match tcx.hir_node(id) {
Node::Pat(Pat {
kind: PatKind::Binding(..),
..
})) => (),
}) => (),
_ => return false,
}

View file

@ -3,15 +3,14 @@ use clippy_utils::higher::VecArgs;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::type_diagnostic_name;
use clippy_utils::usage::{local_used_after_expr, local_used_in};
use clippy_utils::{higher, is_adjusted, path_to_local, path_to_local_id};
use clippy_utils::{get_path_from_caller_to_method_type, higher, is_adjusted, path_to_local, path_to_local_id};
use rustc_errors::Applicability;
use rustc_hir::def_id::DefId;
use rustc_hir::{BindingAnnotation, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, TyKind, Unsafety};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{
self, Binder, ClosureArgs, ClosureKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, GenericArgsRef,
ImplPolarity, List, Region, RegionKind, Ty, TypeVisitableExt, TypeckResults,
self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, ImplPolarity, List, Region, RegionKind,
Ty, TypeVisitableExt, TypeckResults,
};
use rustc_session::declare_lint_pass;
use rustc_span::symbol::sym;
@ -21,8 +20,8 @@ use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
declare_clippy_lint! {
/// ### What it does
/// Checks for closures which just call another function where
/// the function can be called directly. `unsafe` functions or calls where types
/// get adjusted are ignored.
/// the function can be called directly. `unsafe` functions, calls where types
/// get adjusted or where the callee is marked `#[track_caller]` are ignored.
///
/// ### Why is this bad?
/// Needlessly creating a closure adds code for no benefit
@ -136,7 +135,14 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
.map_or(callee_ty, |a| a.target.peel_refs());
let sig = match callee_ty_adjusted.kind() {
ty::FnDef(def, _) => cx.tcx.fn_sig(def).skip_binder().skip_binder(),
ty::FnDef(def, _) => {
// Rewriting `x(|| f())` to `x(f)` where f is marked `#[track_caller]` moves the `Location`
if cx.tcx.has_attr(*def, sym::track_caller) {
return;
}
cx.tcx.fn_sig(def).skip_binder().skip_binder()
},
ty::FnPtr(sig) => sig.skip_binder(),
ty::Closure(_, subs) => cx
.tcx
@ -186,6 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
},
ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => {
if let Some(method_def_id) = typeck.type_dependent_def_id(body.value.hir_id)
&& !cx.tcx.has_attr(method_def_id, sym::track_caller)
&& check_sig(cx, closure, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder())
{
span_lint_and_then(
@ -195,11 +202,12 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
"redundant closure",
|diag| {
let args = typeck.node_args(body.value.hir_id);
let name = get_ufcs_type_name(cx, method_def_id, args);
let caller = self_.hir_id.owner.def_id;
let type_name = get_path_from_caller_to_method_type(cx.tcx, caller, method_def_id, args);
diag.span_suggestion(
expr.span,
"replace the closure with the method itself",
format!("{}::{}", name, path.ident.name),
format!("{}::{}", type_name, path.ident.name),
Applicability::MachineApplicable,
);
},
@ -301,27 +309,3 @@ fn has_late_bound_to_non_late_bound_regions(from_sig: FnSig<'_>, to_sig: FnSig<'
.zip(to_sig.inputs_and_output)
.any(|(from_ty, to_ty)| check_ty(from_ty, to_ty))
}
fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, args: GenericArgsRef<'tcx>) -> String {
let assoc_item = cx.tcx.associated_item(method_def_id);
let def_id = assoc_item.container_id(cx.tcx);
match assoc_item.container {
ty::TraitContainer => cx.tcx.def_path_str(def_id),
ty::ImplContainer => {
let ty = cx.tcx.type_of(def_id).instantiate_identity();
match ty.kind() {
ty::Adt(adt, _) => cx.tcx.def_path_str(adt.did()),
ty::Array(..)
| ty::Dynamic(..)
| ty::Never
| ty::RawPtr(_)
| ty::Ref(..)
| ty::Slice(_)
| ty::Tuple(_) => {
format!("<{}>", EarlyBinder::bind(ty).instantiate(cx.tcx, args))
},
_ => ty.to_string(),
}
},
}
}

View file

@ -111,7 +111,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>)
// Find id of the local that expr_end_of_block resolves to
&& let ExprKind::Path(QPath::Resolved(None, expr_path)) = expr_end_of_block.kind
&& let Res::Local(expr_res) = expr_path.res
&& let Some(Node::Pat(res_pat)) = cx.tcx.opt_hir_node(expr_res)
&& let Node::Pat(res_pat) = cx.tcx.hir_node(expr_res)
// Find id of the local we found in the block
&& let PatKind::Binding(BindingAnnotation::NONE, local_hir_id, _ident, None) = local.pat.kind

View file

@ -0,0 +1,133 @@
use clippy_config::msrvs::Msrv;
use clippy_utils::diagnostics::span_lint;
use rustc_attr::{StabilityLevel, StableSince};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyCtxt;
use rustc_semver::RustcVersion;
use rustc_session::impl_lint_pass;
use rustc_span::def_id::DefId;
use rustc_span::Span;
declare_clippy_lint! {
/// ### What it does
///
/// This lint checks that no function newer than the defined MSRV (minimum
/// supported rust version) is used in the crate.
///
/// ### Why is this bad?
///
/// It would prevent the crate to be actually used with the specified MSRV.
///
/// ### Example
/// ```no_run
/// // MSRV of 1.3.0
/// use std::thread::sleep;
/// use std::time::Duration;
///
/// // Sleep was defined in `1.4.0`.
/// sleep(Duration::new(1, 0));
/// ```
///
/// To fix this problem, either increase your MSRV or use another item
/// available in your current MSRV.
#[clippy::version = "1.77.0"]
pub INCOMPATIBLE_MSRV,
suspicious,
"ensures that all items used in the crate are available for the current MSRV"
}
pub struct IncompatibleMsrv {
msrv: Msrv,
is_above_msrv: FxHashMap<DefId, RustcVersion>,
}
impl_lint_pass!(IncompatibleMsrv => [INCOMPATIBLE_MSRV]);
impl IncompatibleMsrv {
pub fn new(msrv: Msrv) -> Self {
Self {
msrv,
is_above_msrv: FxHashMap::default(),
}
}
#[allow(clippy::cast_lossless)]
fn get_def_id_version(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> RustcVersion {
if let Some(version) = self.is_above_msrv.get(&def_id) {
return *version;
}
let version = if let Some(version) = tcx
.lookup_stability(def_id)
.and_then(|stability| match stability.level {
StabilityLevel::Stable {
since: StableSince::Version(version),
..
} => Some(RustcVersion::new(
version.major as _,
version.minor as _,
version.patch as _,
)),
_ => None,
}) {
version
} else if let Some(parent_def_id) = tcx.opt_parent(def_id) {
self.get_def_id_version(tcx, parent_def_id)
} else {
RustcVersion::new(1, 0, 0)
};
self.is_above_msrv.insert(def_id, version);
version
}
fn emit_lint_if_under_msrv(&mut self, cx: &LateContext<'_>, def_id: DefId, span: Span) {
if def_id.is_local() {
// We don't check local items since their MSRV is supposed to always be valid.
return;
}
let version = self.get_def_id_version(cx.tcx, def_id);
if self.msrv.meets(version) {
return;
}
self.emit_lint_for(cx, span, version);
}
fn emit_lint_for(&self, cx: &LateContext<'_>, span: Span, version: RustcVersion) {
span_lint(
cx,
INCOMPATIBLE_MSRV,
span,
&format!(
"current MSRV (Minimum Supported Rust Version) is `{}` but this item is stable since `{version}`",
self.msrv
),
);
}
}
impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv {
extract_msrv_attr!(LateContext);
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if self.msrv.current().is_none() {
// If there is no MSRV, then no need to check anything...
return;
}
match expr.kind {
ExprKind::MethodCall(_, _, _, span) => {
if let Some(method_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
self.emit_lint_if_under_msrv(cx, method_did, span);
}
},
ExprKind::Call(call, [_]) => {
if let ExprKind::Path(qpath) = call.kind
&& let Some(path_def_id) = cx.qpath_res(&qpath, call.hir_id).opt_def_id()
{
self.emit_lint_if_under_msrv(cx, path_def_id, call.span);
}
},
_ => {},
}
}
}

View file

@ -248,7 +248,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
// Checking for slice indexing
&& let parent_id = map.parent_id(expr.hir_id)
&& let Some(hir::Node::Expr(parent_expr)) = cx.tcx.opt_hir_node(parent_id)
&& let hir::Node::Expr(parent_expr) = cx.tcx.hir_node(parent_id)
&& let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind
&& let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr)
&& let Ok(index_value) = index_value.try_into()
@ -256,7 +256,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
// Make sure that this slice index is read only
&& let maybe_addrof_id = map.parent_id(parent_id)
&& let Some(hir::Node::Expr(maybe_addrof_expr)) = cx.tcx.opt_hir_node(maybe_addrof_id)
&& let hir::Node::Expr(maybe_addrof_expr) = cx.tcx.hir_node(maybe_addrof_id)
&& let hir::ExprKind::AddrOf(_kind, hir::Mutability::Not, _inner_expr) = maybe_addrof_expr.kind
{
use_info.index_use.push((index_value, map.span(parent_expr.hir_id)));

View file

@ -34,7 +34,7 @@ declare_clippy_lint! {
/// let value = &my_map[key];
/// }
/// ```
#[clippy::version = "1.75.0"]
#[clippy::version = "1.76.0"]
pub ITER_OVER_HASH_TYPE,
restriction,
"iterating over unordered hash-based types (`HashMap` and `HashSet`)"

View file

@ -147,9 +147,9 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
&& let Some(output) =
parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder())
{
let (name, kind) = match cx.tcx.opt_hir_node(ty_hir_id) {
Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"),
Some(Node::Item(x)) => match x.kind {
let (name, kind) = match cx.tcx.hir_node(ty_hir_id) {
Node::ForeignItem(x) => (x.ident.name, "extern type"),
Node::Item(x) => match x.kind {
ItemKind::Struct(..) => (x.ident.name, "struct"),
ItemKind::Enum(..) => (x.ident.name, "enum"),
ItemKind::Union(..) => (x.ident.name, "union"),

View file

@ -10,7 +10,12 @@
#![feature(stmt_expr_attributes)]
#![recursion_limit = "512"]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![allow(clippy::missing_docs_in_private_items, clippy::must_use_candidate)]
#![allow(
clippy::missing_docs_in_private_items,
clippy::must_use_candidate,
rustc::diagnostic_outside_of_impl,
rustc::untranslatable_diagnostic,
)]
#![warn(trivial_casts, trivial_numeric_casts)]
// warn on lints, that are included in `rust-lang/rust`s bootstrap
#![warn(rust_2018_idioms, unused_lifetimes)]
@ -26,6 +31,7 @@ extern crate rustc_abi;
extern crate rustc_arena;
extern crate rustc_ast;
extern crate rustc_ast_pretty;
extern crate rustc_attr;
extern crate rustc_data_structures;
extern crate rustc_driver;
extern crate rustc_errors;
@ -153,6 +159,7 @@ mod implicit_return;
mod implicit_saturating_add;
mod implicit_saturating_sub;
mod implied_bounds_in_impls;
mod incompatible_msrv;
mod inconsistent_struct_constructor;
mod index_refutable_slice;
mod indexing_slicing;
@ -325,6 +332,7 @@ mod temporary_assignment;
mod tests_outside_test_module;
mod thread_local_initializer_can_be_made_const;
mod to_digit_is_some;
mod to_string_trait_impl;
mod trailing_empty_array;
mod trait_bounds;
mod transmute;
@ -521,6 +529,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
ref allowed_dotfiles,
ref allowed_idents_below_min_chars,
ref allowed_scripts,
ref allowed_wildcard_imports,
ref arithmetic_side_effects_allowed_binary,
ref arithmetic_side_effects_allowed_unary,
ref arithmetic_side_effects_allowed,
@ -575,6 +584,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
check_private_items,
pub_underscore_fields_behavior,
ref allowed_duplicate_crates,
allow_comparison_to_zero,
blacklisted_names: _,
cyclomatic_complexity_threshold: _,
@ -872,7 +882,12 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
))
});
store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap));
store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
store.register_late_pass(move |_| {
Box::new(wildcard_imports::WildcardImports::new(
warn_on_all_wildcard_imports,
allowed_wildcard_imports.clone(),
))
});
store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default());
store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default());
@ -968,7 +983,12 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(|_| Box::new(default_instead_of_iter_empty::DefaultIterEmpty));
store.register_late_pass(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv())));
store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(msrv())));
store.register_late_pass(move |_| Box::new(operators::Operators::new(verbose_bit_mask_threshold)));
store.register_late_pass(move |_| {
Box::new(operators::Operators::new(
verbose_bit_mask_threshold,
allow_comparison_to_zero,
))
});
store.register_late_pass(|_| Box::<std_instead_of_core::StdReexports>::default());
store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(msrv())));
store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));
@ -1094,6 +1114,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(move |_| {
Box::new(thread_local_initializer_can_be_made_const::ThreadLocalInitializerCanBeMadeConst::new(msrv()))
});
store.register_late_pass(move |_| Box::new(incompatible_msrv::IncompatibleMsrv::new(msrv())));
store.register_late_pass(|_| Box::new(to_string_trait_impl::ToStringTraitImpl));
// add lints here, do not remove this comment, it's used in `new_lint`
}

View file

@ -176,7 +176,7 @@ fn check_fn_inner<'tcx>(
_ => None,
});
for bound in lifetimes {
if !bound.is_static() && !bound.is_elided() {
if bound.res != LifetimeName::Static && !bound.is_elided() {
return;
}
}

View file

@ -672,7 +672,7 @@ declare_clippy_lint! {
/// }
/// }
/// ```
#[clippy::version = "1.75.0"]
#[clippy::version = "1.76.0"]
pub INFINITE_LOOP,
restriction,
"possibly unintended infinite loop"

View file

@ -201,12 +201,12 @@ fn never_loop_expr<'tcx>(
})
})
},
ExprKind::Block(b, l) => {
if l.is_some() {
ExprKind::Block(b, _) => {
if b.targeted_by_break {
local_labels.push((b.hir_id, false));
}
let ret = never_loop_block(cx, b, local_labels, main_loop_id);
let jumped_to = l.is_some() && local_labels.pop().unwrap().1;
let jumped_to = b.targeted_by_break && local_labels.pop().unwrap().1;
match ret {
NeverLoopResult::Diverging if jumped_to => NeverLoopResult::Normal,
_ => ret,

View file

@ -63,7 +63,7 @@ pub(super) fn check<'tcx>(
&& let PatKind::Binding(bind_ann, ..) = pat.kind
&& !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut))
&& let parent_node = cx.tcx.hir().parent_id(hir_id)
&& let Some(Node::Local(parent_let_expr)) = cx.tcx.opt_hir_node(parent_node)
&& let Node::Local(parent_let_expr) = cx.tcx.hir_node(parent_node)
&& let Some(init) = parent_let_expr.init
{
match init.kind {

View file

@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
// Also ensures the const is nonzero since zero can't be a divisor
&& const1 == const2 && const2 == const3
&& let Some(hir_id) = path_to_local(expr3)
&& let Some(Node::Pat(_)) = cx.tcx.opt_hir_node(hir_id)
&& let Node::Pat(_) = cx.tcx.hir_node(hir_id)
{
// Apply only to params or locals with annotated types
match cx.tcx.hir().find_parent(hir_id) {

View file

@ -11,6 +11,7 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_semver::RustcVersion;
use rustc_session::impl_lint_pass;
use rustc_span::symbol::sym;
use rustc_span::Span;
const ACCEPTABLE_METHODS: [&[&str]; 5] = [
&paths::BINARYHEAP_ITER,
@ -28,6 +29,7 @@ const ACCEPTABLE_TYPES: [(rustc_span::Symbol, Option<RustcVersion>); 7] = [
(sym::Vec, None),
(sym::VecDeque, None),
];
const MAP_TYPES: [rustc_span::Symbol; 2] = [sym::BTreeMap, sym::HashMap];
declare_clippy_lint! {
/// ### What it does
@ -44,6 +46,7 @@ declare_clippy_lint! {
/// ```no_run
/// let mut vec = vec![0, 1, 2];
/// vec.retain(|x| x % 2 == 0);
/// vec.retain(|x| x % 2 == 0);
/// ```
#[clippy::version = "1.64.0"]
pub MANUAL_RETAIN,
@ -74,9 +77,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRetain {
&& let Some(collect_def_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id)
&& cx.tcx.is_diagnostic_item(sym::iterator_collect_fn, collect_def_id)
{
check_into_iter(cx, parent_expr, left_expr, target_expr, &self.msrv);
check_iter(cx, parent_expr, left_expr, target_expr, &self.msrv);
check_to_owned(cx, parent_expr, left_expr, target_expr, &self.msrv);
check_into_iter(cx, left_expr, target_expr, parent_expr.span, &self.msrv);
check_iter(cx, left_expr, target_expr, parent_expr.span, &self.msrv);
check_to_owned(cx, left_expr, target_expr, parent_expr.span, &self.msrv);
}
}
@ -85,9 +88,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRetain {
fn check_into_iter(
cx: &LateContext<'_>,
parent_expr: &hir::Expr<'_>,
left_expr: &hir::Expr<'_>,
target_expr: &hir::Expr<'_>,
parent_expr_span: Span,
msrv: &Msrv,
) {
if let hir::ExprKind::MethodCall(_, into_iter_expr, [_], _) = &target_expr.kind
@ -98,16 +101,39 @@ fn check_into_iter(
&& Some(into_iter_def_id) == cx.tcx.lang_items().into_iter_fn()
&& match_acceptable_type(cx, left_expr, msrv)
&& SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)
&& let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = target_expr.kind
&& let hir::ExprKind::Closure(closure) = closure_expr.kind
&& let filter_body = cx.tcx.hir().body(closure.body)
&& let [filter_params] = filter_body.params
{
suggest(cx, parent_expr, left_expr, target_expr);
if match_map_type(cx, left_expr) {
if let hir::PatKind::Tuple([key_pat, value_pat], _) = filter_params.pat.kind {
if let Some(sugg) = make_sugg(cx, key_pat, value_pat, left_expr, filter_body) {
make_span_lint_and_sugg(cx, parent_expr_span, sugg);
}
}
// Cannot lint other cases because `retain` requires two parameters
} else {
// Can always move because `retain` and `filter` have the same bound on the predicate
// for other types
make_span_lint_and_sugg(
cx,
parent_expr_span,
format!(
"{}.retain({})",
snippet(cx, left_expr.span, ".."),
snippet(cx, closure_expr.span, "..")
),
);
}
}
}
fn check_iter(
cx: &LateContext<'_>,
parent_expr: &hir::Expr<'_>,
left_expr: &hir::Expr<'_>,
target_expr: &hir::Expr<'_>,
parent_expr_span: Span,
msrv: &Msrv,
) {
if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
@ -122,16 +148,50 @@ fn check_iter(
&& match_acceptable_def_path(cx, iter_expr_def_id)
&& match_acceptable_type(cx, left_expr, msrv)
&& SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)
&& let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind
&& let hir::ExprKind::Closure(closure) = closure_expr.kind
&& let filter_body = cx.tcx.hir().body(closure.body)
&& let [filter_params] = filter_body.params
{
suggest(cx, parent_expr, left_expr, filter_expr);
match filter_params.pat.kind {
// hir::PatKind::Binding(_, _, _, None) => {
// // Be conservative now. Do nothing here.
// // TODO: Ideally, we can rewrite the lambda by stripping one level of reference
// },
hir::PatKind::Tuple([_, _], _) => {
// the `&&` reference for the `filter` method will be auto derefed to `ref`
// so, we can directly use the lambda
// https://doc.rust-lang.org/reference/patterns.html#binding-modes
make_span_lint_and_sugg(
cx,
parent_expr_span,
format!(
"{}.retain({})",
snippet(cx, left_expr.span, ".."),
snippet(cx, closure_expr.span, "..")
),
);
},
hir::PatKind::Ref(pat, _) => make_span_lint_and_sugg(
cx,
parent_expr_span,
format!(
"{}.retain(|{}| {})",
snippet(cx, left_expr.span, ".."),
snippet(cx, pat.span, ".."),
snippet(cx, filter_body.value.span, "..")
),
),
_ => {},
}
}
}
fn check_to_owned(
cx: &LateContext<'_>,
parent_expr: &hir::Expr<'_>,
left_expr: &hir::Expr<'_>,
target_expr: &hir::Expr<'_>,
parent_expr_span: Span,
msrv: &Msrv,
) {
if msrv.meets(msrvs::STRING_RETAIN)
@ -147,43 +207,25 @@ fn check_to_owned(
&& let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
&& is_type_lang_item(cx, ty, hir::LangItem::String)
&& SpanlessEq::new(cx).eq_expr(left_expr, str_expr)
{
suggest(cx, parent_expr, left_expr, filter_expr);
}
}
fn suggest(cx: &LateContext<'_>, parent_expr: &hir::Expr<'_>, left_expr: &hir::Expr<'_>, filter_expr: &hir::Expr<'_>) {
if let hir::ExprKind::MethodCall(_, _, [closure], _) = filter_expr.kind
&& let hir::ExprKind::Closure(&hir::Closure { body, .. }) = closure.kind
&& let filter_body = cx.tcx.hir().body(body)
&& let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind
&& let hir::ExprKind::Closure(closure) = closure_expr.kind
&& let filter_body = cx.tcx.hir().body(closure.body)
&& let [filter_params] = filter_body.params
&& let Some(sugg) = match filter_params.pat.kind {
hir::PatKind::Binding(_, _, filter_param_ident, None) => Some(format!(
"{}.retain(|{filter_param_ident}| {})",
snippet(cx, left_expr.span, ".."),
snippet(cx, filter_body.value.span, "..")
)),
hir::PatKind::Tuple([key_pat, value_pat], _) => make_sugg(cx, key_pat, value_pat, left_expr, filter_body),
hir::PatKind::Ref(pat, _) => match pat.kind {
hir::PatKind::Binding(_, _, filter_param_ident, None) => Some(format!(
"{}.retain(|{filter_param_ident}| {})",
snippet(cx, left_expr.span, ".."),
snippet(cx, filter_body.value.span, "..")
)),
_ => None,
},
_ => None,
}
{
span_lint_and_sugg(
cx,
MANUAL_RETAIN,
parent_expr.span,
"this expression can be written more simply using `.retain()`",
"consider calling `.retain()` instead",
sugg,
Applicability::MachineApplicable,
);
if let hir::PatKind::Ref(pat, _) = filter_params.pat.kind {
make_span_lint_and_sugg(
cx,
parent_expr_span,
format!(
"{}.retain(|{}| {})",
snippet(cx, left_expr.span, ".."),
snippet(cx, pat.span, ".."),
snippet(cx, filter_body.value.span, "..")
),
);
}
// Be conservative now. Do nothing for the `Binding` case.
// TODO: Ideally, we can rewrite the lambda by stripping one level of reference
}
}
@ -229,3 +271,20 @@ fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv
&& acceptable_msrv.map_or(true, |acceptable_msrv| msrv.meets(acceptable_msrv))
})
}
fn match_map_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();
MAP_TYPES.iter().any(|ty| is_type_diagnostic_item(cx, expr_ty, *ty))
}
fn make_span_lint_and_sugg(cx: &LateContext<'_>, span: Span, sugg: String) {
span_lint_and_sugg(
cx,
MANUAL_RETAIN,
span,
"this expression can be written more simply using `.retain()`",
"consider calling `.retain()` instead",
sugg,
Applicability::MachineApplicable,
);
}

View file

@ -44,7 +44,7 @@ pub(super) fn check<'tcx>(
// add note if not multi-line
span_lint_and_then(cx, FILTER_NEXT, expr.span, msg, |diag| {
let (applicability, pat) = if let Some(id) = path_to_local(recv)
&& let Some(hir::Node::Pat(pat)) = cx.tcx.opt_hir_node(id)
&& let hir::Node::Pat(pat) = cx.tcx.hir_node(id)
&& let hir::PatKind::Binding(BindingAnnotation(_, Mutability::Not), _, ident, _) = pat.kind
{
(Applicability::Unspecified, Some((pat.span, ident)))

View file

@ -0,0 +1,197 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::get_parent_expr;
use clippy_utils::source::snippet;
use rustc_ast::{LitKind, StrStyle};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Node, QPath, TyKind};
use rustc_lint::LateContext;
use rustc_span::{sym, Span, Symbol};
use super::MANUAL_C_STR_LITERALS;
/// Checks:
/// - `b"...".as_ptr()`
/// - `b"...".as_ptr().cast()`
/// - `"...".as_ptr()`
/// - `"...".as_ptr().cast()`
///
/// Iff the parent call of `.cast()` isn't `CStr::from_ptr`, to avoid linting twice.
pub(super) fn check_as_ptr<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx Expr<'tcx>,
receiver: &'tcx Expr<'tcx>,
msrv: &Msrv,
) {
if let ExprKind::Lit(lit) = receiver.kind
&& let LitKind::ByteStr(_, StrStyle::Cooked) | LitKind::Str(_, StrStyle::Cooked) = lit.node
&& let casts_removed = peel_ptr_cast_ancestors(cx, expr)
&& !get_parent_expr(cx, casts_removed).is_some_and(
|parent| matches!(parent.kind, ExprKind::Call(func, _) if is_c_str_function(cx, func).is_some()),
)
&& let Some(sugg) = rewrite_as_cstr(cx, lit.span)
&& msrv.meets(msrvs::C_STR_LITERALS)
{
span_lint_and_sugg(
cx,
MANUAL_C_STR_LITERALS,
receiver.span,
"manually constructing a nul-terminated string",
r#"use a `c""` literal"#,
sugg,
// an additional cast may be needed, since the type of `CStr::as_ptr` and
// `"".as_ptr()` can differ and is platform dependent
Applicability::HasPlaceholders,
);
}
}
/// Checks if the callee is a "relevant" `CStr` function considered by this lint.
/// Returns the function name.
fn is_c_str_function(cx: &LateContext<'_>, func: &Expr<'_>) -> Option<Symbol> {
if let ExprKind::Path(QPath::TypeRelative(cstr, fn_name)) = &func.kind
&& let TyKind::Path(QPath::Resolved(_, ty_path)) = &cstr.kind
&& cx.tcx.lang_items().c_str() == ty_path.res.opt_def_id()
{
Some(fn_name.ident.name)
} else {
None
}
}
/// Checks calls to the `CStr` constructor functions:
/// - `CStr::from_bytes_with_nul(..)`
/// - `CStr::from_bytes_with_nul_unchecked(..)`
/// - `CStr::from_ptr(..)`
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>], msrv: &Msrv) {
if let Some(fn_name) = is_c_str_function(cx, func)
&& let [arg] = args
&& msrv.meets(msrvs::C_STR_LITERALS)
{
match fn_name.as_str() {
name @ ("from_bytes_with_nul" | "from_bytes_with_nul_unchecked")
if !arg.span.from_expansion()
&& let ExprKind::Lit(lit) = arg.kind
&& let LitKind::ByteStr(_, StrStyle::Cooked) | LitKind::Str(_, StrStyle::Cooked) = lit.node =>
{
check_from_bytes(cx, expr, arg, name);
},
"from_ptr" => check_from_ptr(cx, expr, arg),
_ => {},
}
}
}
/// Checks `CStr::from_ptr(b"foo\0".as_ptr().cast())`
fn check_from_ptr(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>) {
if let ExprKind::MethodCall(method, lit, ..) = peel_ptr_cast(arg).kind
&& method.ident.name == sym::as_ptr
&& !lit.span.from_expansion()
&& let ExprKind::Lit(lit) = lit.kind
&& let LitKind::ByteStr(_, StrStyle::Cooked) = lit.node
&& let Some(sugg) = rewrite_as_cstr(cx, lit.span)
{
span_lint_and_sugg(
cx,
MANUAL_C_STR_LITERALS,
expr.span,
"calling `CStr::from_ptr` with a byte string literal",
r#"use a `c""` literal"#,
sugg,
Applicability::MachineApplicable,
);
}
}
/// Checks `CStr::from_bytes_with_nul(b"foo\0")`
fn check_from_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, method: &str) {
let (span, applicability) = if let Some(parent) = get_parent_expr(cx, expr)
&& let ExprKind::MethodCall(method, ..) = parent.kind
&& [sym::unwrap, sym::expect].contains(&method.ident.name)
{
(parent.span, Applicability::MachineApplicable)
} else if method == "from_bytes_with_nul_unchecked" {
// `*_unchecked` returns `&CStr` directly, nothing needs to be changed
(expr.span, Applicability::MachineApplicable)
} else {
// User needs to remove error handling, can't be machine applicable
(expr.span, Applicability::HasPlaceholders)
};
let Some(sugg) = rewrite_as_cstr(cx, arg.span) else {
return;
};
span_lint_and_sugg(
cx,
MANUAL_C_STR_LITERALS,
span,
"calling `CStr::new` with a byte string literal",
r#"use a `c""` literal"#,
sugg,
applicability,
);
}
/// Rewrites a byte string literal to a c-str literal.
/// `b"foo\0"` -> `c"foo"`
///
/// Returns `None` if it doesn't end in a NUL byte.
fn rewrite_as_cstr(cx: &LateContext<'_>, span: Span) -> Option<String> {
let mut sugg = String::from("c") + snippet(cx, span.source_callsite(), "..").trim_start_matches('b');
// NUL byte should always be right before the closing quote.
if let Some(quote_pos) = sugg.rfind('"') {
// Possible values right before the quote:
// - literal NUL value
if sugg.as_bytes()[quote_pos - 1] == b'\0' {
sugg.remove(quote_pos - 1);
}
// - \x00
else if sugg[..quote_pos].ends_with("\\x00") {
sugg.replace_range(quote_pos - 4..quote_pos, "");
}
// - \0
else if sugg[..quote_pos].ends_with("\\0") {
sugg.replace_range(quote_pos - 2..quote_pos, "");
}
// No known suffix, so assume it's not a C-string.
else {
return None;
}
}
Some(sugg)
}
fn get_cast_target<'tcx>(e: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
match &e.kind {
ExprKind::MethodCall(method, receiver, [], _) if method.ident.as_str() == "cast" => Some(receiver),
ExprKind::Cast(expr, _) => Some(expr),
_ => None,
}
}
/// `x.cast()` -> `x`
/// `x as *const _` -> `x`
/// `x` -> `x` (returns the same expression for non-cast exprs)
fn peel_ptr_cast<'tcx>(e: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
get_cast_target(e).map_or(e, peel_ptr_cast)
}
/// Same as `peel_ptr_cast`, but the other way around, by walking up the ancestor cast expressions:
///
/// `foo(x.cast() as *const _)`
/// ^ given this `x` expression, returns the `foo(...)` expression
fn peel_ptr_cast_ancestors<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
let mut prev = e;
for (_, node) in cx.tcx.hir().parent_iter(e.hir_id) {
if let Node::Expr(e) = node
&& get_cast_target(e).is_some()
{
prev = e;
} else {
break;
}
}
prev
}

View file

@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
unwrap_arg: &'tcx hir::Expr<'_>,
msrv: &Msrv,
) -> bool {
// lint if the caller of `map()` is an `Option`
// lint if the caller of `map()` is an `Option` or a `Result`.
let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option);
let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);

View file

@ -51,6 +51,7 @@ mod iter_skip_zero;
mod iter_with_drain;
mod iterator_step_by_zero;
mod join_absolute_paths;
mod manual_c_str_literals;
mod manual_is_variant_and;
mod manual_next_back;
mod manual_ok_or;
@ -113,6 +114,7 @@ mod unnecessary_iter_cloned;
mod unnecessary_join;
mod unnecessary_lazy_eval;
mod unnecessary_literal_unwrap;
mod unnecessary_result_map_or_else;
mod unnecessary_sort_by;
mod unnecessary_to_owned;
mod unwrap_expect_used;
@ -3951,6 +3953,64 @@ declare_clippy_lint! {
"cloning an `Option` via `as_ref().cloned()`"
}
declare_clippy_lint! {
/// ### What it does
/// Checks for usage of `.map_or_else()` "map closure" for `Result` type.
///
/// ### Why is this bad?
/// This can be written more concisely by using `unwrap_or_else()`.
///
/// ### Example
/// ```no_run
/// # fn handle_error(_: ()) -> u32 { 0 }
/// let x: Result<u32, ()> = Ok(0);
/// let y = x.map_or_else(|err| handle_error(err), |n| n);
/// ```
/// Use instead:
/// ```no_run
/// # fn handle_error(_: ()) -> u32 { 0 }
/// let x: Result<u32, ()> = Ok(0);
/// let y = x.unwrap_or_else(|err| handle_error(err));
/// ```
#[clippy::version = "1.77.0"]
pub UNNECESSARY_RESULT_MAP_OR_ELSE,
suspicious,
"making no use of the \"map closure\" when calling `.map_or_else(|err| handle_error(err), |n| n)`"
}
declare_clippy_lint! {
/// Checks for the manual creation of C strings (a string with a `NUL` byte at the end), either
/// through one of the `CStr` constructor functions, or more plainly by calling `.as_ptr()`
/// on a (byte) string literal with a hardcoded `\0` byte at the end.
///
/// ### Why is this bad?
/// This can be written more concisely using `c"str"` literals and is also less error-prone,
/// because the compiler checks for interior `NUL` bytes and the terminating `NUL` byte is inserted automatically.
///
/// ### Example
/// ```no_run
/// # use std::ffi::CStr;
/// # mod libc { pub unsafe fn puts(_: *const i8) {} }
/// fn needs_cstr(_: &CStr) {}
///
/// needs_cstr(CStr::from_bytes_with_nul(b"Hello\0").unwrap());
/// unsafe { libc::puts("World\0".as_ptr().cast()) }
/// ```
/// Use instead:
/// ```no_run
/// # use std::ffi::CStr;
/// # mod libc { pub unsafe fn puts(_: *const i8) {} }
/// fn needs_cstr(_: &CStr) {}
///
/// needs_cstr(c"Hello");
/// unsafe { libc::puts(c"World".as_ptr()) }
/// ```
#[clippy::version = "1.76.0"]
pub MANUAL_C_STR_LITERALS,
pedantic,
r#"creating a `CStr` through functions when `c""` literals can be used"#
}
pub struct Methods {
avoid_breaking_exported_api: bool,
msrv: Msrv,
@ -4109,6 +4169,8 @@ impl_lint_pass!(Methods => [
MANUAL_IS_VARIANT_AND,
STR_SPLIT_AT_NEWLINE,
OPTION_AS_REF_CLONED,
UNNECESSARY_RESULT_MAP_OR_ELSE,
MANUAL_C_STR_LITERALS,
]);
/// Extracts a method call name, args, and `Span` of the method name.
@ -4136,6 +4198,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
hir::ExprKind::Call(func, args) => {
from_iter_instead_of_collect::check(cx, expr, args, func);
unnecessary_fallible_conversions::check_function(cx, expr, func);
manual_c_str_literals::check(cx, expr, func, args, &self.msrv);
},
hir::ExprKind::MethodCall(method_call, receiver, args, _) => {
let method_span = method_call.ident.span;
@ -4354,6 +4417,7 @@ impl Methods {
}
},
("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
("as_ptr", []) => manual_c_str_literals::check_as_ptr(cx, expr, recv, &self.msrv),
("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv),
("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
("cloned", []) => {
@ -4592,6 +4656,7 @@ impl Methods {
},
("map_or_else", [def, map]) => {
result_map_or_else_none::check(cx, expr, recv, def, map);
unnecessary_result_map_or_else::check(cx, expr, recv, def, map);
},
("next", []) => {
if let Some((name2, recv2, args2, _, _)) = method_call(recv) {

View file

@ -135,7 +135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> {
fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) {
if let Res::Local(local_id) = path.res
&& let Some(Node::Pat(pat)) = self.cx.tcx.opt_hir_node(local_id)
&& let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
&& let PatKind::Binding(_, local_id, ..) = pat.kind
{
self.identifiers.insert(local_id);
@ -166,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReferenceVisitor<'a, 'tcx> {
&& let ExprKind::Path(ref path) = expr.kind
&& let QPath::Resolved(_, path) = path
&& let Res::Local(local_id) = path.res
&& let Some(Node::Pat(pat)) = self.cx.tcx.opt_hir_node(local_id)
&& let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
&& let PatKind::Binding(_, local_id, ..) = pat.kind
&& self.identifiers.contains(&local_id)
{

View file

@ -99,7 +99,6 @@ fn check_fold_with_op(
cx,
UNNECESSARY_FOLD,
fold_span.with_hi(expr.span.hi()),
// TODO #2371 don't suggest e.g., .any(|x| f(x)) if we can suggest .any(f)
"this `.fold` can be written more succinctly using another method",
"try",
sugg,

View file

@ -0,0 +1,95 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::peel_blocks;
use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::{Closure, Expr, ExprKind, HirId, QPath, Stmt, StmtKind};
use rustc_lint::LateContext;
use rustc_span::symbol::sym;
use super::UNNECESSARY_RESULT_MAP_OR_ELSE;
fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, def_arg: &Expr<'_>) {
let msg = "unused \"map closure\" when calling `Result::map_or_else` value";
let self_snippet = snippet(cx, recv.span, "..");
let err_snippet = snippet(cx, def_arg.span, "..");
span_lint_and_sugg(
cx,
UNNECESSARY_RESULT_MAP_OR_ELSE,
expr.span,
msg,
"consider using `unwrap_or_else`",
format!("{self_snippet}.unwrap_or_else({err_snippet})"),
Applicability::MachineApplicable,
);
}
fn get_last_chain_binding_hir_id(mut hir_id: HirId, statements: &[Stmt<'_>]) -> Option<HirId> {
for stmt in statements {
if let StmtKind::Local(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::Path(QPath::Resolved(_, path)) = init.kind
&& let hir::def::Res::Local(local_hir_id) = path.res
&& local_hir_id == hir_id
{
hir_id = local.pat.hir_id;
} else {
return None;
}
}
Some(hir_id)
}
fn handle_qpath(
cx: &LateContext<'_>,
expr: &Expr<'_>,
recv: &Expr<'_>,
def_arg: &Expr<'_>,
expected_hir_id: HirId,
qpath: QPath<'_>,
) {
if let QPath::Resolved(_, path) = qpath
&& let hir::def::Res::Local(hir_id) = path.res
&& expected_hir_id == hir_id
{
emit_lint(cx, expr, recv, def_arg);
}
}
/// lint use of `_.map_or_else(|err| err, |n| n)` for `Result`s.
pub(super) fn check<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx Expr<'_>,
recv: &'tcx Expr<'_>,
def_arg: &'tcx Expr<'_>,
map_arg: &'tcx Expr<'_>,
) {
// lint if the caller of `map_or_else()` is a `Result`
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result)
&& let ExprKind::Closure(&Closure { body, .. }) = map_arg.kind
&& let body = cx.tcx.hir().body(body)
&& let Some(first_param) = body.params.first()
{
let body_expr = peel_blocks(body.value);
match body_expr.kind {
ExprKind::Path(qpath) => {
handle_qpath(cx, expr, recv, def_arg, first_param.pat.hir_id, qpath);
},
// If this is a block (that wasn't peeled off), then it means there are statements.
ExprKind::Block(block, _) => {
if let Some(block_expr) = block.expr
// First we ensure that this is a "binding chain" (each statement is a binding
// of the previous one) and that it is a binding of the closure argument.
&& let Some(last_chain_binding_id) =
get_last_chain_binding_hir_id(first_param.pat.hir_id, block.stmts)
&& let ExprKind::Path(qpath) = block_expr.kind
{
handle_qpath(cx, expr, recv, def_arg, last_chain_binding_id, qpath);
}
},
_ => {},
}
}
}

View file

@ -91,10 +91,10 @@ impl Visitor<'_> for IdentVisitor<'_, '_> {
let node = if hir_id.local_id == ItemLocalId::from_u32(0) {
// In this case, we can just use `find`, `Owner`'s `node` field is private anyway so we can't
// reimplement it even if we wanted to
cx.tcx.opt_hir_node(hir_id)
Some(cx.tcx.hir_node(hir_id))
} else {
let owner = cx.tcx.hir_owner_nodes(hir_id.owner);
owner.nodes.get(hir_id.local_id).copied().flatten().map(|p| p.node)
owner.nodes.get(hir_id.local_id).copied().map(|p| p.node)
};
let Some(node) = node else {
return;

View file

@ -213,11 +213,8 @@ fn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) {
if parent_id == cur_id {
break;
}
let Some(parent_node) = vis.cx.tcx.opt_hir_node(parent_id) else {
break;
};
let stop_early = match parent_node {
let stop_early = match vis.cx.tcx.hir_node(parent_id) {
Node::Expr(expr) => check_expr(vis, expr),
Node::Stmt(stmt) => check_stmt(vis, stmt),
Node::Item(_) => {

View file

@ -357,7 +357,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
}
},
ExprKind::Block(block, _) => {
if block.stmts.is_empty() {
if block.stmts.is_empty() && !block.targeted_by_break {
block.expr.as_ref().and_then(|e| {
match block.rules {
BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) => None,

View file

@ -453,7 +453,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
if parent_id == cur_expr.hir_id {
break;
}
if let Some(Node::Expr(parent_expr)) = cx.tcx.opt_hir_node(parent_id) {
if let Node::Expr(parent_expr) = cx.tcx.hir_node(parent_id) {
match &parent_expr.kind {
ExprKind::AddrOf(..) => {
// `&e` => `e` must be referenced.

View file

@ -252,7 +252,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
{
(
trait_item_id,
FnKind::ImplTraitFn(cx.tcx.erase_regions(trait_ref.args) as *const _ as usize),
FnKind::ImplTraitFn(std::ptr::from_ref(cx.tcx.erase_regions(trait_ref.args)) as usize),
usize::from(sig.decl.implicit_self.has_implicit_self()),
)
} else {
@ -390,7 +390,6 @@ fn has_matching_args(kind: FnKind, args: GenericArgsRef<'_>) -> bool {
GenericArgKind::Type(ty) => matches!(*ty.kind(), ty::Param(ty) if ty.index as usize == idx),
GenericArgKind::Const(c) => matches!(c.kind(), ConstKind::Param(c) if c.index as usize == idx),
}),
#[allow(trivial_casts)]
FnKind::ImplTraitFn(expected_args) => args as *const _ as usize == expected_args,
FnKind::ImplTraitFn(expected_args) => std::ptr::from_ref(args) as usize == expected_args,
}
}

View file

@ -771,6 +771,7 @@ declare_clippy_lint! {
pub struct Operators {
arithmetic_context: numeric_arithmetic::Context,
verbose_bit_mask_threshold: u64,
modulo_arithmetic_allow_comparison_to_zero: bool,
}
impl_lint_pass!(Operators => [
ABSURD_EXTREME_COMPARISONS,
@ -801,10 +802,11 @@ impl_lint_pass!(Operators => [
SELF_ASSIGNMENT,
]);
impl Operators {
pub fn new(verbose_bit_mask_threshold: u64) -> Self {
pub fn new(verbose_bit_mask_threshold: u64, modulo_arithmetic_allow_comparison_to_zero: bool) -> Self {
Self {
arithmetic_context: numeric_arithmetic::Context::default(),
verbose_bit_mask_threshold,
modulo_arithmetic_allow_comparison_to_zero,
}
}
}
@ -835,12 +837,19 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
cmp_owned::check(cx, op.node, lhs, rhs);
float_cmp::check(cx, e, op.node, lhs, rhs);
modulo_one::check(cx, e, op.node, rhs);
modulo_arithmetic::check(cx, e, op.node, lhs, rhs);
modulo_arithmetic::check(
cx,
e,
op.node,
lhs,
rhs,
self.modulo_arithmetic_allow_comparison_to_zero,
);
},
ExprKind::AssignOp(op, lhs, rhs) => {
self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);
misrefactored_assign_op::check(cx, e, op.node, lhs, rhs);
modulo_arithmetic::check(cx, e, op.node, lhs, rhs);
modulo_arithmetic::check(cx, e, op.node, lhs, rhs, false);
},
ExprKind::Assign(lhs, rhs, _) => {
assign_op_pattern::check(cx, e, lhs, rhs);

View file

@ -1,7 +1,7 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::sext;
use rustc_hir::{BinOpKind, Expr};
use rustc_hir::{BinOpKind, Expr, ExprKind, Node};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};
use std::fmt::Display;
@ -14,8 +14,13 @@ pub(super) fn check<'tcx>(
op: BinOpKind,
lhs: &'tcx Expr<'_>,
rhs: &'tcx Expr<'_>,
allow_comparison_to_zero: bool,
) {
if op == BinOpKind::Rem {
if allow_comparison_to_zero && used_in_comparison_with_zero(cx, e) {
return;
}
let lhs_operand = analyze_operand(lhs, cx, e);
let rhs_operand = analyze_operand(rhs, cx, e);
if let Some(lhs_operand) = lhs_operand
@ -28,6 +33,26 @@ pub(super) fn check<'tcx>(
};
}
fn used_in_comparison_with_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let Some(Node::Expr(parent_expr)) = cx.tcx.hir().find_parent(expr.hir_id) else {
return false;
};
let ExprKind::Binary(op, lhs, rhs) = parent_expr.kind else {
return false;
};
if op.node == BinOpKind::Eq || op.node == BinOpKind::Ne {
if let Some(Constant::Int(0)) = constant(cx, cx.typeck_results(), rhs) {
return true;
}
if let Some(Constant::Int(0)) = constant(cx, cx.typeck_results(), lhs) {
return true;
}
}
false
}
struct OperandInfo {
string_representation: Option<String>,
is_negative: bool,

View file

@ -2,6 +2,7 @@ use crate::rustc_lint::LintContext;
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
use clippy_utils::get_parent_expr;
use clippy_utils::sugg::Sugg;
use hir::Param;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
@ -13,6 +14,7 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_session::declare_lint_pass;
use rustc_span::ExpnKind;
declare_clippy_lint! {
/// ### What it does
@ -89,7 +91,12 @@ fn find_innermost_closure<'tcx>(
cx: &LateContext<'tcx>,
mut expr: &'tcx hir::Expr<'tcx>,
mut steps: usize,
) -> Option<(&'tcx hir::Expr<'tcx>, &'tcx hir::FnDecl<'tcx>, ty::Asyncness)> {
) -> Option<(
&'tcx hir::Expr<'tcx>,
&'tcx hir::FnDecl<'tcx>,
ty::Asyncness,
&'tcx [Param<'tcx>],
)> {
let mut data = None;
while let hir::ExprKind::Closure(closure) = expr.kind
@ -110,6 +117,7 @@ fn find_innermost_closure<'tcx>(
} else {
ty::Asyncness::No
},
body.params,
));
steps -= 1;
}
@ -152,7 +160,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
// without this check, we'd end up linting twice.
&& !matches!(recv.kind, hir::ExprKind::Call(..))
&& let (full_expr, call_depth) = get_parent_call_exprs(cx, expr)
&& let Some((body, fn_decl, coroutine_kind)) = find_innermost_closure(cx, recv, call_depth)
&& let Some((body, fn_decl, coroutine_kind, params)) = find_innermost_closure(cx, recv, call_depth)
// outside macros we lint properly. Inside macros, we lint only ||() style closures.
&& (!matches!(expr.span.ctxt().outer_expn_data().kind, ExpnKind::Macro(_, _)) || params.is_empty())
{
span_lint_and_then(
cx,

View file

@ -4,8 +4,10 @@ use clippy_utils::ty::needs_ordered_drop;
use rustc_ast::Mutability;
use rustc_hir::def::Res;
use rustc_hir::{BindingAnnotation, ByRef, ExprKind, HirId, Local, Node, Pat, PatKind, QPath};
use rustc_hir_typeck::expr_use_visitor::PlaceBase;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::UpvarCapture;
use rustc_session::declare_lint_pass;
use rustc_span::symbol::Ident;
use rustc_span::DesugaringKind;
@ -69,6 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
// the local is user-controlled
&& !in_external_macro(cx.sess(), local.span)
&& !is_from_proc_macro(cx, expr)
&& !is_by_value_closure_capture(cx, local.hir_id, binding_id)
{
span_lint_and_help(
cx,
@ -82,6 +85,29 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
}
}
/// Checks if the enclosing body is a closure and if the given local is captured by value.
///
/// In those cases, the redefinition may be necessary to force a move:
/// ```
/// fn assert_static<T: 'static>(_: T) {}
///
/// let v = String::new();
/// let closure = || {
/// let v = v; // <- removing this redefinition makes `closure` no longer `'static`
/// dbg!(&v);
/// };
/// assert_static(closure);
/// ```
fn is_by_value_closure_capture(cx: &LateContext<'_>, redefinition: HirId, root_variable: HirId) -> bool {
let closure_def_id = cx.tcx.hir().enclosing_body_owner(redefinition);
cx.tcx.is_closure_or_coroutine(closure_def_id.to_def_id())
&& cx.tcx.closure_captures(closure_def_id).iter().any(|c| {
matches!(c.info.capture_kind, UpvarCapture::ByValue)
&& matches!(c.place.base, PlaceBase::Upvar(upvar) if upvar.var_path.hir_id == root_variable)
})
}
/// Find the annotation of a binding introduced by a pattern, or `None` if it's not introduced.
fn find_binding(pat: &Pat<'_>, name: Ident) -> Option<BindingAnnotation> {
let mut ret = None;

View file

@ -188,7 +188,6 @@ impl LateLintPass<'_> for RedundantTypeAnnotations {
match init_lit.node {
// In these cases the annotation is redundant
LitKind::Str(..)
| LitKind::ByteStr(..)
| LitKind::Byte(..)
| LitKind::Char(..)
| LitKind::Bool(..)
@ -202,6 +201,16 @@ impl LateLintPass<'_> for RedundantTypeAnnotations {
}
},
LitKind::Err => (),
LitKind::ByteStr(..) => {
// We only lint if the type annotation is an array type (e.g. &[u8; 4]).
// If instead it is a slice (e.g. &[u8]) it may not be redundant, so we
// don't lint.
if let hir::TyKind::Ref(_, mut_ty) = ty.kind
&& matches!(mut_ty.ty.kind, hir::TyKind::Array(..))
{
span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation");
}
},
}
},
_ => (),

View file

@ -42,7 +42,7 @@ declare_clippy_lint! {
/// // ^^^ this closure executes 123 times
/// // and the vecs will have the expected capacity
/// ```
#[clippy::version = "1.74.0"]
#[clippy::version = "1.76.0"]
pub REPEAT_VEC_WITH_CAPACITY,
suspicious,
"repeating a `Vec::with_capacity` expression which does not retain capacity"

View file

@ -2,10 +2,14 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then, span_lin
use clippy_utils::source::{snippet_opt, snippet_with_context};
use clippy_utils::sugg::has_enclosing_paren;
use clippy_utils::visitors::{for_each_expr_with_closures, Descend};
use clippy_utils::{fn_def_id, is_from_proc_macro, is_inside_let_else, path_to_local_id, span_find_starting_semi};
use clippy_utils::{
fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res, path_to_local_id,
span_find_starting_semi,
};
use core::ops::ControlFlow;
use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
use rustc_hir::LangItem::ResultErr;
use rustc_hir::{
Block, Body, Expr, ExprKind, FnDecl, HirId, ItemKind, LangItem, MatchSource, Node, OwnerNode, PatKind, QPath, Stmt,
StmtKind,
@ -18,6 +22,7 @@ use rustc_session::declare_lint_pass;
use rustc_span::def_id::LocalDefId;
use rustc_span::{BytePos, Pos, Span};
use std::borrow::Cow;
use std::fmt::Display;
declare_clippy_lint! {
/// ### What it does
@ -146,14 +151,14 @@ impl<'tcx> RetReplacement<'tcx> {
}
}
impl<'tcx> ToString for RetReplacement<'tcx> {
fn to_string(&self) -> String {
impl<'tcx> Display for RetReplacement<'tcx> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Empty => String::new(),
Self::Block => "{}".to_string(),
Self::Unit => "()".to_string(),
Self::IfSequence(inner, _) => format!("({inner})"),
Self::Expr(inner, _) => inner.to_string(),
Self::Empty => write!(f, ""),
Self::Block => write!(f, "{{}}"),
Self::Unit => write!(f, "()"),
Self::IfSequence(inner, _) => write!(f, "({inner})"),
Self::Expr(inner, _) => write!(f, "{inner}"),
}
}
}
@ -181,7 +186,15 @@ impl<'tcx> LateLintPass<'tcx> for Return {
if !in_external_macro(cx.sess(), stmt.span)
&& let StmtKind::Semi(expr) = stmt.kind
&& let ExprKind::Ret(Some(ret)) = expr.kind
&& let ExprKind::Match(.., MatchSource::TryDesugar(_)) = ret.kind
// return Err(...)? desugars to a match
// over a Err(...).branch()
// which breaks down to a branch call, with the callee being
// the constructor of the Err variant
&& let ExprKind::Match(maybe_cons, _, MatchSource::TryDesugar(_)) = ret.kind
&& let ExprKind::Call(_, [maybe_result_err]) = maybe_cons.kind
&& let ExprKind::Call(maybe_constr, _) = maybe_result_err.kind
&& is_res_lang_ctor(cx, path_res(cx, maybe_constr), ResultErr)
// Ensure this is not the final stmt, otherwise removing it would cause a compile error
&& let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id))
&& let ItemKind::Fn(_, _, body) = item.kind

View file

@ -76,8 +76,8 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
match of_trait {
Some(trait_ref) => {
let mut methods_in_trait: BTreeSet<Symbol> =
if let Some(Node::TraitRef(TraitRef { path, .. })) =
cx.tcx.opt_hir_node(trait_ref.hir_ref_id)
if let Node::TraitRef(TraitRef { path, .. }) =
cx.tcx.hir_node(trait_ref.hir_ref_id)
&& let Res::Def(DefKind::Trait, did) = path.res
{
// FIXME: if

View file

@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
if let Some(self_def) = self_ty.ty_adt_def()
&& let Some(self_local_did) = self_def.did().as_local()
&& let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did)
&& let Some(Node::Item(x)) = cx.tcx.opt_hir_node(self_id)
&& let Node::Item(x) = cx.tcx.hir_node(self_id)
&& let type_name = x.ident.name.as_str().to_lowercase()
&& (impl_item.ident.name.as_str() == type_name
|| impl_item.ident.name.as_str().replace('_', "") == type_name)

View file

@ -0,0 +1,67 @@
use clippy_utils::diagnostics::span_lint_and_help;
use rustc_hir::{Impl, Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
/// Checks for direct implementations of `ToString`.
/// ### Why is this bad?
/// This trait is automatically implemented for any type which implements the `Display` trait.
/// As such, `ToString` shouldnt be implemented directly: `Display` should be implemented instead,
/// and you get the `ToString` implementation for free.
/// ### Example
/// ```no_run
/// struct Point {
/// x: usize,
/// y: usize,
/// }
///
/// impl ToString for Point {
/// fn to_string(&self) -> String {
/// format!("({}, {})", self.x, self.y)
/// }
/// }
/// ```
/// Use instead:
/// ```no_run
/// struct Point {
/// x: usize,
/// y: usize,
/// }
///
/// impl std::fmt::Display for Point {
/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// write!(f, "({}, {})", self.x, self.y)
/// }
/// }
/// ```
#[clippy::version = "1.77.0"]
pub TO_STRING_TRAIT_IMPL,
style,
"check for direct implementations of `ToString`"
}
declare_lint_pass!(ToStringTraitImpl => [TO_STRING_TRAIT_IMPL]);
impl<'tcx> LateLintPass<'tcx> for ToStringTraitImpl {
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'tcx>) {
if let ItemKind::Impl(Impl {
of_trait: Some(trait_ref),
..
}) = it.kind
&& let Some(trait_did) = trait_ref.trait_def_id()
&& cx.tcx.is_diagnostic_item(sym::ToString, trait_did)
{
span_lint_and_help(
cx,
TO_STRING_TRAIT_IMPL,
it.span,
"direct implementation of `ToString`",
None,
"prefer implementing `Display` instead",
);
}
}
}

View file

@ -69,14 +69,6 @@ fn span_error(cx: &LateContext<'_>, method_span: Span, expr: &Expr<'_>) {
);
}
fn get_ty_def_id(ty: Ty<'_>) -> Option<DefId> {
match ty.peel_refs().kind() {
ty::Adt(adt, _) => Some(adt.did()),
ty::Foreign(def_id) => Some(*def_id),
_ => None,
}
}
fn get_hir_ty_def_id<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: rustc_hir::Ty<'tcx>) -> Option<DefId> {
let TyKind::Path(qpath) = hir_ty.kind else { return None };
match qpath {
@ -131,21 +123,49 @@ fn get_impl_trait_def_id(cx: &LateContext<'_>, method_def_id: LocalDefId) -> Opt
}
}
#[allow(clippy::unnecessary_def_path)]
/// When we have `x == y` where `x = &T` and `y = &T`, then that resolves to
/// `<&T as PartialEq<&T>>::eq`, which is not the same as `<T as PartialEq<T>>::eq`,
/// however we still would want to treat it the same, because we know that it's a blanket impl
/// that simply delegates to the `PartialEq` impl with one reference removed.
///
/// Still, we can't just do `lty.peel_refs() == rty.peel_refs()` because when we have `x = &T` and
/// `y = &&T`, this is not necessarily the same as `<T as PartialEq<T>>::eq`
///
/// So to avoid these FNs and FPs, we keep removing a layer of references from *both* sides
/// until both sides match the expected LHS and RHS type (or they don't).
fn matches_ty<'tcx>(
mut left: Ty<'tcx>,
mut right: Ty<'tcx>,
expected_left: Ty<'tcx>,
expected_right: Ty<'tcx>,
) -> bool {
while let (&ty::Ref(_, lty, _), &ty::Ref(_, rty, _)) = (left.kind(), right.kind()) {
if lty == expected_left && rty == expected_right {
return true;
}
left = lty;
right = rty;
}
false
}
fn check_partial_eq(cx: &LateContext<'_>, method_span: Span, method_def_id: LocalDefId, name: Ident, expr: &Expr<'_>) {
let args = cx
.tcx
.instantiate_bound_regions_with_erased(cx.tcx.fn_sig(method_def_id).skip_binder())
.inputs();
let Some(sig) = cx
.typeck_results()
.liberated_fn_sigs()
.get(cx.tcx.local_def_id_to_hir_id(method_def_id))
else {
return;
};
// That has two arguments.
if let [self_arg, other_arg] = args
&& let Some(self_arg) = get_ty_def_id(*self_arg)
&& let Some(other_arg) = get_ty_def_id(*other_arg)
if let [self_arg, other_arg] = sig.inputs()
&& let &ty::Ref(_, self_arg, _) = self_arg.kind()
&& let &ty::Ref(_, other_arg, _) = other_arg.kind()
// The two arguments are of the same type.
&& self_arg == other_arg
&& let Some(trait_def_id) = get_impl_trait_def_id(cx, method_def_id)
// The trait is `PartialEq`.
&& Some(trait_def_id) == get_trait_def_id(cx, &["core", "cmp", "PartialEq"])
&& cx.tcx.is_diagnostic_item(sym::PartialEq, trait_def_id)
{
let to_check_op = if name.name == sym::eq {
BinOpKind::Eq
@ -154,31 +174,19 @@ fn check_partial_eq(cx: &LateContext<'_>, method_span: Span, method_def_id: Loca
};
let is_bad = match expr.kind {
ExprKind::Binary(op, left, right) if op.node == to_check_op => {
// Then we check if the left-hand element is of the same type as `self`.
if let Some(left_ty) = cx.typeck_results().expr_ty_opt(left)
&& let Some(left_id) = get_ty_def_id(left_ty)
&& self_arg == left_id
&& let Some(right_ty) = cx.typeck_results().expr_ty_opt(right)
&& let Some(right_id) = get_ty_def_id(right_ty)
&& other_arg == right_id
{
true
} else {
false
}
// Then we check if the LHS matches self_arg and RHS matches other_arg
let left_ty = cx.typeck_results().expr_ty_adjusted(left);
let right_ty = cx.typeck_results().expr_ty_adjusted(right);
matches_ty(left_ty, right_ty, self_arg, other_arg)
},
ExprKind::MethodCall(segment, receiver, &[_arg], _) if segment.ident.name == name.name => {
if let Some(ty) = cx.typeck_results().expr_ty_opt(receiver)
&& let Some(ty_id) = get_ty_def_id(ty)
&& self_arg != ty_id
{
// Since this called on a different type, the lint should not be
// triggered here.
return;
}
ExprKind::MethodCall(segment, receiver, [arg], _) if segment.ident.name == name.name => {
let receiver_ty = cx.typeck_results().expr_ty_adjusted(receiver);
let arg_ty = cx.typeck_results().expr_ty_adjusted(arg);
if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
&& let Some(trait_id) = cx.tcx.trait_of_item(fn_id)
&& trait_id == trait_def_id
&& matches_ty(receiver_ty, arg_ty, self_arg, other_arg)
{
true
} else {

View file

@ -1,5 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::{is_res_lang_ctor, is_trait_method, match_trait_method, paths};
use clippy_utils::macros::{is_panic, root_macro_call_first_node};
use clippy_utils::{is_res_lang_ctor, is_trait_method, match_trait_method, paths, peel_blocks};
use hir::{ExprKind, PatKind};
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass};
@ -82,37 +83,72 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
}
if let Some(exp) = block.expr
&& matches!(exp.kind, hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, _))
&& matches!(
exp.kind,
hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, hir::MatchSource::Normal)
)
{
check_expr(cx, exp);
}
}
}
fn non_consuming_err_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool {
// if there is a guard, we consider the result to be consumed
if arm.guard.is_some() {
return false;
}
if is_unreachable_or_panic(cx, arm.body) {
// if the body is unreachable or there is a panic,
// we consider the result to be consumed
return false;
}
if let PatKind::TupleStruct(ref path, [inner_pat], _) = arm.pat.kind {
return is_res_lang_ctor(cx, cx.qpath_res(path, inner_pat.hir_id), hir::LangItem::ResultErr);
}
false
}
fn non_consuming_ok_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool {
// if there is a guard, we consider the result to be consumed
if arm.guard.is_some() {
return false;
}
if is_unreachable_or_panic(cx, arm.body) {
// if the body is unreachable or there is a panic,
// we consider the result to be consumed
return false;
}
if is_ok_wild_or_dotdot_pattern(cx, arm.pat) {
return true;
}
false
}
fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
match expr.kind {
hir::ExprKind::If(cond, _, _)
if let ExprKind::Let(hir::Let { pat, init, .. }) = cond.kind
&& pattern_is_ignored_ok(cx, pat)
&& is_ok_wild_or_dotdot_pattern(cx, pat)
&& let Some(op) = should_lint(cx, init) =>
{
emit_lint(cx, cond.span, op, &[pat.span]);
},
hir::ExprKind::Match(expr, arms, hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => {
let found_arms: Vec<_> = arms
.iter()
.filter_map(|arm| {
if pattern_is_ignored_ok(cx, arm.pat) {
Some(arm.span)
} else {
None
}
})
.collect();
if !found_arms.is_empty() {
emit_lint(cx, expr.span, op, found_arms.as_slice());
// we will capture only the case where the match is Ok( ) or Err( )
// prefer to match the minimum possible, and expand later if needed
// to avoid false positives on something as used as this
hir::ExprKind::Match(expr, [arm1, arm2], hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => {
if non_consuming_ok_arm(cx, arm1) && non_consuming_err_arm(cx, arm2) {
emit_lint(cx, expr.span, op, &[arm1.pat.span]);
}
if non_consuming_ok_arm(cx, arm2) && non_consuming_err_arm(cx, arm1) {
emit_lint(cx, expr.span, op, &[arm2.pat.span]);
}
},
hir::ExprKind::Match(_, _, hir::MatchSource::Normal) => {},
_ if let Some(op) = should_lint(cx, expr) => {
emit_lint(cx, expr.span, op, &[]);
},
@ -130,25 +166,40 @@ fn should_lint<'a>(cx: &LateContext<'a>, mut inner: &'a hir::Expr<'a>) -> Option
check_io_mode(cx, inner)
}
fn pattern_is_ignored_ok(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> bool {
fn is_ok_wild_or_dotdot_pattern<'a>(cx: &LateContext<'a>, pat: &hir::Pat<'a>) -> bool {
// the if checks whether we are in a result Ok( ) pattern
// and the return checks whether it is unhandled
if let PatKind::TupleStruct(ref path, inner_pat, ddp) = pat.kind
if let PatKind::TupleStruct(ref path, inner_pat, _) = pat.kind
// we check against Result::Ok to avoid linting on Err(_) or something else.
&& is_res_lang_ctor(cx, cx.qpath_res(path, pat.hir_id), hir::LangItem::ResultOk)
{
return match (inner_pat, ddp.as_opt_usize()) {
// Ok(_) pattern
([inner_pat], None) if matches!(inner_pat.kind, PatKind::Wild) => true,
// Ok(..) pattern
([], Some(0)) => true,
_ => false,
};
if matches!(inner_pat, []) {
return true;
}
if let [cons_pat] = inner_pat
&& matches!(cons_pat.kind, PatKind::Wild)
{
return true;
}
return false;
}
false
}
// this is partially taken from panic_unimplemented
fn is_unreachable_or_panic(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
let expr = peel_blocks(expr);
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return false;
};
if is_panic(cx, macro_call.def_id) {
return !cx.tcx.hir().is_inside_const_context(expr.hir_id);
}
matches!(cx.tcx.item_name(macro_call.def_id).as_str(), "unreachable")
}
fn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
while let hir::ExprKind::MethodCall(path, receiver, ..) = expr.kind {
if matches!(

View file

@ -490,9 +490,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
format!("ClosureKind::Coroutine(CoroutineKind::Coroutine(Movability::{movability:?})")
},
},
ClosureKind::CoroutineClosure(desugaring) => format!(
"ClosureKind::CoroutineClosure(CoroutineDesugaring::{desugaring:?})"
),
ClosureKind::CoroutineClosure(desugaring) => {
format!("ClosureKind::CoroutineClosure(CoroutineDesugaring::{desugaring:?})")
},
};
let ret_ty = match fn_decl.output {

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_test_module_or_function;
use clippy_utils::source::{snippet, snippet_with_applicability};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Item, ItemKind, PathSegment, UseKind};
@ -100,13 +101,15 @@ declare_clippy_lint! {
pub struct WildcardImports {
warn_on_all: bool,
test_modules_deep: u32,
allowed_segments: FxHashSet<String>,
}
impl WildcardImports {
pub fn new(warn_on_all: bool) -> Self {
pub fn new(warn_on_all: bool, allowed_wildcard_imports: FxHashSet<String>) -> Self {
Self {
warn_on_all,
test_modules_deep: 0,
allowed_segments: allowed_wildcard_imports,
}
}
}
@ -190,6 +193,7 @@ impl WildcardImports {
item.span.from_expansion()
|| is_prelude_import(segments)
|| (is_super_only_import(segments) && self.test_modules_deep > 0)
|| is_allowed_via_config(segments, &self.allowed_segments)
}
}
@ -198,10 +202,18 @@ impl WildcardImports {
fn is_prelude_import(segments: &[PathSegment<'_>]) -> bool {
segments
.iter()
.any(|ps| ps.ident.name.as_str().contains(sym::prelude.as_str()))
.any(|ps| ps.ident.as_str().contains(sym::prelude.as_str()))
}
// Allow "super::*" imports in tests.
fn is_super_only_import(segments: &[PathSegment<'_>]) -> bool {
segments.len() == 1 && segments[0].ident.name == kw::Super
}
// Allow skipping imports containing user configured segments,
// i.e. "...::utils::...::*" if user put `allowed-wildcard-imports = ["utils"]` in `Clippy.toml`
fn is_allowed_via_config(segments: &[PathSegment<'_>], allowed_segments: &FxHashSet<String>) -> bool {
// segment matching need to be exact instead of using 'contains', in case user unintentionaly put
// a single character in the config thus skipping most of the warnings.
segments.iter().any(|seg| allowed_segments.contains(seg.ident.as_str()))
}

View file

@ -1,6 +1,6 @@
[package]
name = "clippy_utils"
version = "0.1.77"
version = "0.1.78"
edition = "2021"
publish = false

View file

@ -1,5 +1,6 @@
#![feature(array_chunks)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(lint_reasons)]
@ -8,7 +9,13 @@
#![feature(assert_matches)]
#![recursion_limit = "512"]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc, clippy::must_use_candidate)]
#![allow(
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::must_use_candidate,
rustc::diagnostic_outside_of_impl,
rustc::untranslatable_diagnostic,
)]
// warn on the same lints as `clippy_lints`
#![warn(trivial_casts, trivial_numeric_casts)]
// warn on lints, that are included in `rust-lang/rust`s bootstrap
@ -75,6 +82,7 @@ use core::mem;
use core::ops::ControlFlow;
use std::collections::hash_map::Entry;
use std::hash::BuildHasherDefault;
use std::iter::{once, repeat};
use std::sync::{Mutex, MutexGuard, OnceLock};
use itertools::Itertools;
@ -84,6 +92,7 @@ use rustc_data_structures::packed::Pu128;
use rustc_data_structures::unhash::UnhashMap;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, LOCAL_CRATE};
use rustc_hir::definitions::{DefPath, DefPathData};
use rustc_hir::hir_id::{HirIdMap, HirIdSet};
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
@ -102,8 +111,8 @@ use rustc_middle::ty::binding::BindingMode;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{
self as rustc_ty, Binder, BorrowKind, ClosureKind, FloatTy, IntTy, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeAndMut,
TypeVisitableExt, UintTy, UpvarCapture,
self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy, ParamEnv,
ParamEnvAnd, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, UintTy, UpvarCapture,
};
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::source_map::SourceMap;
@ -114,10 +123,7 @@ use visitors::Visitable;
use crate::consts::{constant, mir_to_const, Constant};
use crate::higher::Range;
use crate::ty::{
adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type,
ty_is_fn_once_param,
};
use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type};
use crate::visitors::for_each_expr;
use rustc_middle::hir::nested_filter;
@ -177,10 +183,10 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr
/// canonical binding `HirId`.
pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
let hir = cx.tcx.hir();
if let Some(Node::Pat(pat)) = cx.tcx.opt_hir_node(hir_id)
if let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
&& matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..))
&& let parent = hir.parent_id(hir_id)
&& let Some(Node::Local(local)) = cx.tcx.opt_hir_node(parent)
&& let Node::Local(local) = cx.tcx.hir_node(parent)
{
return local.init;
}
@ -1327,7 +1333,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio
let map = &cx.tcx.hir();
let enclosing_node = map
.get_enclosing_scope(hir_id)
.and_then(|enclosing_id| cx.tcx.opt_hir_node(enclosing_id));
.map(|enclosing_id| cx.tcx.hir_node(enclosing_id));
enclosing_node.and_then(|node| match node {
Node::Block(block) => Some(block),
Node::Item(&Item {
@ -1353,46 +1359,12 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>(
for (_, node) in cx.tcx.hir().parent_iter(expr.hir_id) {
match node {
Node::Expr(e) => match e.kind {
ExprKind::Closure { .. } => {
ExprKind::Closure { .. }
if let rustc_ty::Closure(_, subs) = cx.typeck_results().expr_ty(e).kind()
&& subs.as_closure().kind() == ClosureKind::FnOnce
{
continue;
}
let is_once = walk_to_expr_usage(cx, e, |node, id| {
let Node::Expr(e) = node else {
return None;
};
match e.kind {
ExprKind::Call(f, _) if f.hir_id == id => Some(()),
ExprKind::Call(f, args) => {
let i = args.iter().position(|arg| arg.hir_id == id)?;
let sig = expr_sig(cx, f)?;
let predicates = sig
.predicates_id()
.map_or(cx.param_env, |id| cx.tcx.param_env(id))
.caller_bounds();
sig.input(i).and_then(|ty| {
ty_is_fn_once_param(cx.tcx, ty.skip_binder(), predicates).then_some(())
})
},
ExprKind::MethodCall(_, receiver, args, _) => {
let i = std::iter::once(receiver)
.chain(args.iter())
.position(|arg| arg.hir_id == id)?;
let id = cx.typeck_results().type_dependent_def_id(e.hir_id)?;
let ty = cx.tcx.fn_sig(id).instantiate_identity().skip_binder().inputs()[i];
ty_is_fn_once_param(cx.tcx, ty, cx.tcx.param_env(id).caller_bounds()).then_some(())
},
_ => None,
}
})
.is_some();
if !is_once {
return Some(e);
}
},
ExprKind::Loop(..) => return Some(e),
&& subs.as_closure().kind() == ClosureKind::FnOnce => {},
// Note: A closure's kind is determined by how it's used, not it's captures.
ExprKind::Closure { .. } | ExprKind::Loop(..) => return Some(e),
_ => (),
},
Node::Stmt(_) | Node::Block(_) | Node::Local(_) | Node::Arm(_) => (),
@ -2590,26 +2562,30 @@ pub fn is_test_module_or_function(tcx: TyCtxt<'_>, item: &Item<'_>) -> bool {
&& item.ident.name.as_str().split('_').any(|a| a == "test" || a == "tests")
}
/// Walks the HIR tree from the given expression, up to the node where the value produced by the
/// expression is consumed. Calls the function for every node encountered this way until it returns
/// `Some`.
/// Walks up the HIR tree from the given expression in an attempt to find where the value is
/// consumed.
///
/// This allows walking through `if`, `match`, `break`, block expressions to find where the value
/// produced by the expression is consumed.
/// Termination has three conditions:
/// - The given function returns `Break`. This function will return the value.
/// - The consuming node is found. This function will return `Continue(use_node, child_id)`.
/// - No further parent nodes are found. This will trigger a debug assert or return `None`.
///
/// This allows walking through `if`, `match`, `break`, and block expressions to find where the
/// value produced by the expression is consumed.
pub fn walk_to_expr_usage<'tcx, T>(
cx: &LateContext<'tcx>,
e: &Expr<'tcx>,
mut f: impl FnMut(Node<'tcx>, HirId) -> Option<T>,
) -> Option<T> {
mut f: impl FnMut(HirId, Node<'tcx>, HirId) -> ControlFlow<T>,
) -> Option<ControlFlow<T, (Node<'tcx>, HirId)>> {
let map = cx.tcx.hir();
let mut iter = map.parent_iter(e.hir_id);
let mut child_id = e.hir_id;
while let Some((parent_id, parent)) = iter.next() {
if let Some(x) = f(parent, child_id) {
return Some(x);
if let ControlFlow::Break(x) = f(parent_id, parent, child_id) {
return Some(ControlFlow::Break(x));
}
let parent = match parent {
let parent_expr = match parent {
Node::Expr(e) => e,
Node::Block(Block { expr: Some(body), .. }) | Node::Arm(Arm { body, .. }) if body.hir_id == child_id => {
child_id = parent_id;
@ -2619,18 +2595,19 @@ pub fn walk_to_expr_usage<'tcx, T>(
child_id = parent_id;
continue;
},
_ => return None,
_ => return Some(ControlFlow::Continue((parent, child_id))),
};
match parent.kind {
match parent_expr.kind {
ExprKind::If(child, ..) | ExprKind::Match(child, ..) if child.hir_id != child_id => child_id = parent_id,
ExprKind::Break(Destination { target_id: Ok(id), .. }, _) => {
child_id = id;
iter = map.parent_iter(id);
},
ExprKind::Block(..) => child_id = parent_id,
_ => return None,
ExprKind::Block(..) | ExprKind::DropTemps(_) => child_id = parent_id,
_ => return Some(ControlFlow::Continue((parent, child_id))),
}
}
debug_assert!(false, "no parent node found for `{child_id:?}`");
None
}
@ -2674,6 +2651,8 @@ pub enum ExprUseNode<'tcx> {
Callee,
/// Access of a field.
FieldAccess(Ident),
Expr,
Other,
}
impl<'tcx> ExprUseNode<'tcx> {
/// Checks if the value is returned from the function.
@ -2696,10 +2675,10 @@ impl<'tcx> ExprUseNode<'tcx> {
)),
Self::Return(id) => {
let hir_id = cx.tcx.local_def_id_to_hir_id(id.def_id);
if let Some(Node::Expr(Expr {
if let Node::Expr(Expr {
kind: ExprKind::Closure(c),
..
})) = cx.tcx.opt_hir_node(hir_id)
}) = cx.tcx.hir_node(hir_id)
{
match c.fn_decl.output {
FnRetTy::DefaultReturn(_) => None,
@ -2750,144 +2729,104 @@ impl<'tcx> ExprUseNode<'tcx> {
let sig = cx.tcx.fn_sig(id).skip_binder();
Some(DefinedTy::Mir(cx.tcx.param_env(id).and(sig.input(i))))
},
Self::Local(_) | Self::FieldAccess(..) | Self::Callee => None,
Self::Local(_) | Self::FieldAccess(..) | Self::Callee | Self::Expr | Self::Other => None,
}
}
}
/// Gets the context an expression's value is used in.
#[expect(clippy::too_many_lines)]
pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Option<ExprUseCtxt<'tcx>> {
let mut adjustments = [].as_slice();
let mut is_ty_unified = false;
let mut moved_before_use = false;
let ctxt = e.span.ctxt();
walk_to_expr_usage(cx, e, &mut |parent, child_id| {
// LocalTableInContext returns the wrong lifetime, so go use `expr_adjustments` instead.
walk_to_expr_usage(cx, e, &mut |parent_id, parent, child_id| {
if adjustments.is_empty()
&& let Node::Expr(e) = cx.tcx.hir_node(child_id)
{
adjustments = cx.typeck_results().expr_adjustments(e);
}
match parent {
Node::Local(l) if l.span.ctxt() == ctxt => Some(ExprUseCtxt {
node: ExprUseNode::Local(l),
adjustments,
is_ty_unified,
moved_before_use,
}),
if cx.tcx.hir().span(parent_id).ctxt() != ctxt {
return ControlFlow::Break(());
}
if let Node::Expr(e) = parent {
match e.kind {
ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id != child_id => {
is_ty_unified = true;
moved_before_use = true;
},
ExprKind::Block(_, Some(_)) | ExprKind::Break(..) => {
is_ty_unified = true;
moved_before_use = true;
},
ExprKind::Block(..) => moved_before_use = true,
_ => {},
}
}
ControlFlow::Continue(())
})?
.continue_value()
.map(|(use_node, child_id)| {
let node = match use_node {
Node::Local(l) => ExprUseNode::Local(l),
Node::ExprField(field) => ExprUseNode::Field(field),
Node::Item(&Item {
kind: ItemKind::Static(..) | ItemKind::Const(..),
owner_id,
span,
..
})
| Node::TraitItem(&TraitItem {
kind: TraitItemKind::Const(..),
owner_id,
span,
..
})
| Node::ImplItem(&ImplItem {
kind: ImplItemKind::Const(..),
owner_id,
span,
..
}) if span.ctxt() == ctxt => Some(ExprUseCtxt {
node: ExprUseNode::ConstStatic(owner_id),
adjustments,
is_ty_unified,
moved_before_use,
}),
}) => ExprUseNode::ConstStatic(owner_id),
Node::Item(&Item {
kind: ItemKind::Fn(..),
owner_id,
span,
..
})
| Node::TraitItem(&TraitItem {
kind: TraitItemKind::Fn(..),
owner_id,
span,
..
})
| Node::ImplItem(&ImplItem {
kind: ImplItemKind::Fn(..),
owner_id,
span,
..
}) if span.ctxt() == ctxt => Some(ExprUseCtxt {
node: ExprUseNode::Return(owner_id),
adjustments,
is_ty_unified,
moved_before_use,
}),
}) => ExprUseNode::Return(owner_id),
Node::ExprField(field) if field.span.ctxt() == ctxt => Some(ExprUseCtxt {
node: ExprUseNode::Field(field),
adjustments,
is_ty_unified,
moved_before_use,
}),
Node::Expr(parent) if parent.span.ctxt() == ctxt => match parent.kind {
ExprKind::Ret(_) => Some(ExprUseCtxt {
node: ExprUseNode::Return(OwnerId {
def_id: cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
}),
adjustments,
is_ty_unified,
moved_before_use,
Node::Expr(use_expr) => match use_expr.kind {
ExprKind::Ret(_) => ExprUseNode::Return(OwnerId {
def_id: cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
}),
ExprKind::Closure(closure) => Some(ExprUseCtxt {
node: ExprUseNode::Return(OwnerId { def_id: closure.def_id }),
adjustments,
is_ty_unified,
moved_before_use,
}),
ExprKind::Call(func, args) => Some(ExprUseCtxt {
node: match args.iter().position(|arg| arg.hir_id == child_id) {
Some(i) => ExprUseNode::FnArg(func, i),
None => ExprUseNode::Callee,
},
adjustments,
is_ty_unified,
moved_before_use,
}),
ExprKind::MethodCall(name, _, args, _) => Some(ExprUseCtxt {
node: ExprUseNode::MethodArg(
parent.hir_id,
name.args,
args.iter().position(|arg| arg.hir_id == child_id).map_or(0, |i| i + 1),
),
adjustments,
is_ty_unified,
moved_before_use,
}),
ExprKind::Field(child, name) if child.hir_id == e.hir_id => Some(ExprUseCtxt {
node: ExprUseNode::FieldAccess(name),
adjustments,
is_ty_unified,
moved_before_use,
}),
ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id != child_id => {
is_ty_unified = true;
moved_before_use = true;
None
ExprKind::Closure(closure) => ExprUseNode::Return(OwnerId { def_id: closure.def_id }),
ExprKind::Call(func, args) => match args.iter().position(|arg| arg.hir_id == child_id) {
Some(i) => ExprUseNode::FnArg(func, i),
None => ExprUseNode::Callee,
},
ExprKind::Block(_, Some(_)) | ExprKind::Break(..) => {
is_ty_unified = true;
moved_before_use = true;
None
},
ExprKind::Block(..) => {
moved_before_use = true;
None
},
_ => None,
ExprKind::MethodCall(name, _, args, _) => ExprUseNode::MethodArg(
use_expr.hir_id,
name.args,
args.iter().position(|arg| arg.hir_id == child_id).map_or(0, |i| i + 1),
),
ExprKind::Field(child, name) if child.hir_id == e.hir_id => ExprUseNode::FieldAccess(name),
_ => ExprUseNode::Expr,
},
_ => None,
_ => ExprUseNode::Other,
};
ExprUseCtxt {
node,
adjustments,
is_ty_unified,
moved_before_use,
}
})
}
@ -3264,3 +3203,131 @@ pub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<
})
}
}
/// Produces a path from a local caller to the type of the called method. Suitable for user
/// output/suggestions.
///
/// Returned path can be either absolute (for methods defined non-locally), or relative (for local
/// methods).
pub fn get_path_from_caller_to_method_type<'tcx>(
tcx: TyCtxt<'tcx>,
from: LocalDefId,
method: DefId,
args: GenericArgsRef<'tcx>,
) -> String {
let assoc_item = tcx.associated_item(method);
let def_id = assoc_item.container_id(tcx);
match assoc_item.container {
rustc_ty::TraitContainer => get_path_to_callee(tcx, from, def_id),
rustc_ty::ImplContainer => {
let ty = tcx.type_of(def_id).instantiate_identity();
get_path_to_ty(tcx, from, ty, args)
},
}
}
fn get_path_to_ty<'tcx>(tcx: TyCtxt<'tcx>, from: LocalDefId, ty: Ty<'tcx>, args: GenericArgsRef<'tcx>) -> String {
match ty.kind() {
rustc_ty::Adt(adt, _) => get_path_to_callee(tcx, from, adt.did()),
// TODO these types need to be recursively resolved as well
rustc_ty::Array(..)
| rustc_ty::Dynamic(..)
| rustc_ty::Never
| rustc_ty::RawPtr(_)
| rustc_ty::Ref(..)
| rustc_ty::Slice(_)
| rustc_ty::Tuple(_) => format!("<{}>", EarlyBinder::bind(ty).instantiate(tcx, args)),
_ => ty.to_string(),
}
}
/// Produce a path from some local caller to the callee. Suitable for user output/suggestions.
fn get_path_to_callee(tcx: TyCtxt<'_>, from: LocalDefId, callee: DefId) -> String {
// only search for a relative path if the call is fully local
if callee.is_local() {
let callee_path = tcx.def_path(callee);
let caller_path = tcx.def_path(from.to_def_id());
maybe_get_relative_path(&caller_path, &callee_path, 2)
} else {
tcx.def_path_str(callee)
}
}
/// Tries to produce a relative path from `from` to `to`; if such a path would contain more than
/// `max_super` `super` items, produces an absolute path instead. Both `from` and `to` should be in
/// the local crate.
///
/// Suitable for user output/suggestions.
///
/// This ignores use items, and assumes that the target path is visible from the source
/// path (which _should_ be a reasonable assumption since we in order to be able to use an object of
/// certain type T, T is required to be visible).
///
/// TODO make use of `use` items. Maybe we should have something more sophisticated like
/// rust-analyzer does? <https://docs.rs/ra_ap_hir_def/0.0.169/src/ra_ap_hir_def/find_path.rs.html#19-27>
fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> String {
use itertools::EitherOrBoth::{Both, Left, Right};
// 1. skip the segments common for both paths (regardless of their type)
let unique_parts = to
.data
.iter()
.zip_longest(from.data.iter())
.skip_while(|el| matches!(el, Both(l, r) if l == r))
.map(|el| match el {
Both(l, r) => Both(l.data, r.data),
Left(l) => Left(l.data),
Right(r) => Right(r.data),
});
// 2. for the remaning segments, construct relative path using only mod names and `super`
let mut go_up_by = 0;
let mut path = Vec::new();
for el in unique_parts {
match el {
Both(l, r) => {
// consider:
// a::b::sym:: :: refers to
// c::d::e ::f::sym
// result should be super::super::c::d::e::f
//
// alternatively:
// a::b::c ::d::sym refers to
// e::f::sym:: ::
// result should be super::super::super::super::e::f
if let DefPathData::TypeNs(s) = l {
path.push(s.to_string());
}
if let DefPathData::TypeNs(_) = r {
go_up_by += 1;
}
},
// consider:
// a::b::sym:: :: refers to
// c::d::e ::f::sym
// when looking at `f`
Left(DefPathData::TypeNs(sym)) => path.push(sym.to_string()),
// consider:
// a::b::c ::d::sym refers to
// e::f::sym:: ::
// when looking at `d`
Right(DefPathData::TypeNs(_)) => go_up_by += 1,
_ => {},
}
}
if go_up_by > max_super {
// `super` chain would be too long, just use the absolute path instead
once(String::from("crate"))
.chain(to.data.iter().filter_map(|el| {
if let DefPathData::TypeNs(sym) = el.data {
Some(sym.to_string())
} else {
None
}
}))
.join("::")
} else {
repeat(String::from("super")).take(go_up_by).chain(path).join("::")
}
}

View file

@ -174,7 +174,7 @@ fn check_rvalue<'tcx>(
))
}
},
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => {
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::DebugAssertions, _) | Rvalue::ShallowInitBox(_, _) => {
Ok(())
},
Rvalue::UnaryOp(_, operand) => {

View file

@ -1000,35 +1000,6 @@ pub fn adt_and_variant_of_res<'tcx>(cx: &LateContext<'tcx>, res: Res) -> Option<
}
}
/// Checks if the type is a type parameter implementing `FnOnce`, but not `FnMut`.
pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tcx [ty::Clause<'_>]) -> bool {
let ty::Param(ty) = *ty.kind() else {
return false;
};
let lang = tcx.lang_items();
let (Some(fn_once_id), Some(fn_mut_id), Some(fn_id)) = (lang.fn_once_trait(), lang.fn_mut_trait(), lang.fn_trait())
else {
return false;
};
predicates
.iter()
.try_fold(false, |found, p| {
if let ty::ClauseKind::Trait(p) = p.kind().skip_binder()
&& let ty::Param(self_ty) = p.trait_ref.self_ty().kind()
&& ty.index == self_ty.index
{
// This should use `super_traits_of`, but that's a private function.
if p.trait_ref.def_id == fn_once_id {
return Some(true);
} else if p.trait_ref.def_id == fn_mut_id || p.trait_ref.def_id == fn_id {
return None;
}
}
Some(found)
})
.unwrap_or(false)
}
/// Comes up with an "at least" guesstimate for the type's size, not taking into
/// account the layout of type parameters.
pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 {

View file

@ -1,6 +1,6 @@
[package]
name = "declare_clippy_lint"
version = "0.1.77"
version = "0.1.78"
edition = "2021"
publish = false

View file

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2024-01-25"
channel = "nightly-2024-02-08"
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]

View file

@ -1,3 +1,5 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![feature(rustc_private)]
#![feature(let_chains)]
#![feature(lazy_cell)]
@ -22,9 +24,11 @@ use rustc_session::EarlyDiagCtxt;
use rustc_span::symbol::Symbol;
use std::env;
use std::fs::read_to_string;
use std::ops::Deref;
use std::path::Path;
use std::process::exit;
use std::string::ToString;
use anstream::println;
@ -188,12 +192,31 @@ pub fn main() {
exit(rustc_driver::catch_with_exit_code(move || {
let mut orig_args: Vec<String> = env::args().collect();
let has_sysroot_arg = arg_value(&orig_args, "--sysroot", |_| true).is_some();
let has_sysroot_arg = |args: &mut [String]| -> bool {
if arg_value(args, "--sysroot", |_| true).is_some() {
return true;
}
// https://doc.rust-lang.org/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path
// Beside checking for existence of `--sysroot` on the command line, we need to
// check for the arg files that are prefixed with @ as well to be consistent with rustc
for arg in args.iter() {
if let Some(arg_file_path) = arg.strip_prefix('@') {
if let Ok(arg_file) = read_to_string(arg_file_path) {
let split_arg_file: Vec<String> = arg_file.lines().map(ToString::to_string).collect();
if arg_value(&split_arg_file, "--sysroot", |_| true).is_some() {
return true;
}
}
}
}
false
};
let sys_root_env = std::env::var("SYSROOT").ok();
let pass_sysroot_env_if_given = |args: &mut Vec<String>, sys_root_env| {
if let Some(sys_root) = sys_root_env {
if !has_sysroot_arg {
if !has_sysroot_arg(args) {
args.extend(vec!["--sysroot".into(), sys_root]);
}
};

View file

@ -0,0 +1,45 @@
error: lint group `rust_2018_idioms` has the same priority (0) as a lint
--> Cargo.toml:7:1
|
7 | rust_2018_idioms = "warn"
| ^^^^^^^^^^^^^^^^ ------ has an implicit priority of 0
8 | bare_trait_objects = "allow"
| ------------------ has the same priority as this lint
|
= note: the order of the lints in the table is ignored by Cargo
= note: `#[deny(clippy::lint_groups_priority)]` on by default
help: to have lints override the group set `rust_2018_idioms` to a lower priority
|
7 | rust_2018_idioms = { level = "warn", priority = -1 }
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: lint group `unused` has the same priority (0) as a lint
--> Cargo.toml:10:1
|
10 | unused = { level = "deny" }
| ^^^^^^ ------------------ has an implicit priority of 0
11 | unused_braces = { level = "allow", priority = 1 }
12 | unused_attributes = { level = "allow" }
| ----------------- has the same priority as this lint
|
= note: the order of the lints in the table is ignored by Cargo
help: to have lints override the group set `unused` to a lower priority
|
10 | unused = { level = "deny", priority = -1 }
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: lint group `pedantic` has the same priority (-1) as a lint
--> Cargo.toml:19:1
|
19 | pedantic = { level = "warn", priority = -1 }
| ^^^^^^^^
20 | similar_names = { level = "allow", priority = -1 }
| ------------- has the same priority as this lint
|
= note: the order of the lints in the table is ignored by Cargo
help: to have lints override the group set `pedantic` to a lower priority
|
19 | pedantic = { level = "warn", priority = -2 }
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: could not compile `fail` (lib) due to 3 previous errors

View file

@ -0,0 +1,20 @@
[package]
name = "fail"
version = "0.1.0"
publish = false
[lints.rust]
rust_2018_idioms = "warn"
bare_trait_objects = "allow"
unused = { level = "deny" }
unused_braces = { level = "allow", priority = 1 }
unused_attributes = { level = "allow" }
# `warnings` is not a group so the order it is passed does not matter
warnings = "deny"
deprecated = "allow"
[lints.clippy]
pedantic = { level = "warn", priority = -1 }
similar_names = { level = "allow", priority = -1 }

View file

@ -0,0 +1,10 @@
[package]
name = "pass"
version = "0.1.0"
publish = false
[lints.clippy]
pedantic = { level = "warn", priority = -1 }
style = { level = "warn", priority = 1 }
similar_names = "allow"
dbg_macro = { level = "warn", priority = 2 }

View file

@ -1,4 +1,4 @@
#![allow(clippy::redundant_clone, clippy::unnecessary_operation)]
#![allow(clippy::redundant_clone, clippy::unnecessary_operation, clippy::incompatible_msrv)]
#![warn(clippy::manual_non_exhaustive, clippy::borrow_as_ptr, clippy::manual_bits)]
use std::mem::{size_of, size_of_val};

View file

@ -1,4 +1,4 @@
#![allow(clippy::redundant_clone, clippy::unnecessary_operation)]
#![allow(clippy::redundant_clone, clippy::unnecessary_operation, clippy::incompatible_msrv)]
#![warn(clippy::manual_non_exhaustive, clippy::borrow_as_ptr, clippy::manual_bits)]
use std::mem::{size_of, size_of_val};

View file

@ -0,0 +1 @@
allow-comparison-to-zero = false

View file

@ -0,0 +1,10 @@
#![warn(clippy::modulo_arithmetic)]
fn main() {
let a = -1;
let b = 2;
let c = a % b == 0;
let c = a % b != 0;
let c = 0 == a % b;
let c = 0 != a % b;
}

View file

@ -0,0 +1,40 @@
error: you are using modulo operator on types that might have different signs
--> $DIR/modulo_arithmetic.rs:6:13
|
LL | let c = a % b == 0;
| ^^^^^
|
= note: double check for expected result especially when interoperating with different languages
= note: or consider using `rem_euclid` or similar function
= note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]`
error: you are using modulo operator on types that might have different signs
--> $DIR/modulo_arithmetic.rs:7:13
|
LL | let c = a % b != 0;
| ^^^^^
|
= note: double check for expected result especially when interoperating with different languages
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
--> $DIR/modulo_arithmetic.rs:8:18
|
LL | let c = 0 == a % b;
| ^^^^^
|
= note: double check for expected result especially when interoperating with different languages
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
--> $DIR/modulo_arithmetic.rs:9:18
|
LL | let c = 0 != a % b;
| ^^^^^
|
= note: double check for expected result especially when interoperating with different languages
= note: or consider using `rem_euclid` or similar function
error: aborting due to 4 previous errors

View file

@ -3,6 +3,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
absolute-paths-max-segments
accept-comment-above-attributes
accept-comment-above-statement
allow-comparison-to-zero
allow-dbg-in-tests
allow-expect-in-tests
allow-mixed-uninlined-format-args
@ -14,6 +15,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
allowed-duplicate-crates
allowed-idents-below-min-chars
allowed-scripts
allowed-wildcard-imports
arithmetic-side-effects-allowed
arithmetic-side-effects-allowed-binary
arithmetic-side-effects-allowed-unary
@ -80,6 +82,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
absolute-paths-max-segments
accept-comment-above-attributes
accept-comment-above-statement
allow-comparison-to-zero
allow-dbg-in-tests
allow-expect-in-tests
allow-mixed-uninlined-format-args
@ -91,6 +94,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
allowed-duplicate-crates
allowed-idents-below-min-chars
allowed-scripts
allowed-wildcard-imports
arithmetic-side-effects-allowed
arithmetic-side-effects-allowed-binary
arithmetic-side-effects-allowed-unary
@ -157,6 +161,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
absolute-paths-max-segments
accept-comment-above-attributes
accept-comment-above-statement
allow-comparison-to-zero
allow-dbg-in-tests
allow-expect-in-tests
allow-mixed-uninlined-format-args
@ -168,6 +173,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
allowed-duplicate-crates
allowed-idents-below-min-chars
allowed-scripts
allowed-wildcard-imports
arithmetic-side-effects-allowed
arithmetic-side-effects-allowed-binary
arithmetic-side-effects-allowed-unary

View file

@ -1 +1,4 @@
warn-on-all-wildcard-imports = true
# This should be ignored since `warn-on-all-wildcard-imports` has higher precedence
allowed-wildcard-imports = ["utils"]

View file

@ -3,9 +3,28 @@
mod prelude {
pub const FOO: u8 = 1;
}
mod utils {
pub const BAR: u8 = 1;
pub fn print() {}
}
mod my_crate {
pub mod utils {
pub fn my_util_fn() {}
}
}
use utils::{BAR, print};
//~^ ERROR: usage of wildcard import
use my_crate::utils::my_util_fn;
//~^ ERROR: usage of wildcard import
use prelude::FOO;
//~^ ERROR: usage of wildcard import
fn main() {
let _ = FOO;
let _ = BAR;
print();
my_util_fn();
}

View file

@ -3,9 +3,28 @@
mod prelude {
pub const FOO: u8 = 1;
}
mod utils {
pub const BAR: u8 = 1;
pub fn print() {}
}
mod my_crate {
pub mod utils {
pub fn my_util_fn() {}
}
}
use utils::*;
//~^ ERROR: usage of wildcard import
use my_crate::utils::*;
//~^ ERROR: usage of wildcard import
use prelude::*;
//~^ ERROR: usage of wildcard import
fn main() {
let _ = FOO;
let _ = BAR;
print();
my_util_fn();
}

View file

@ -1,11 +1,23 @@
error: usage of wildcard import
--> $DIR/wildcard_imports.rs:6:5
--> $DIR/wildcard_imports.rs:18:5
|
LL | use prelude::*;
| ^^^^^^^^^^ help: try: `prelude::FOO`
LL | use utils::*;
| ^^^^^^^^ help: try: `utils::{BAR, print}`
|
= note: `-D clippy::wildcard-imports` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
error: aborting due to 1 previous error
error: usage of wildcard import
--> $DIR/wildcard_imports.rs:20:5
|
LL | use my_crate::utils::*;
| ^^^^^^^^^^^^^^^^^^ help: try: `my_crate::utils::my_util_fn`
error: usage of wildcard import
--> $DIR/wildcard_imports.rs:22:5
|
LL | use prelude::*;
| ^^^^^^^^^^ help: try: `prelude::FOO`
error: aborting due to 3 previous errors

View file

@ -0,0 +1 @@
allowed-wildcard-imports = ["utils"]

View file

@ -0,0 +1,26 @@
#![warn(clippy::wildcard_imports)]
mod utils {
pub fn print() {}
}
mod utils_plus {
pub fn do_something() {}
}
mod my_crate {
pub mod utils {
pub fn my_util_fn() {}
}
}
use my_crate::utils::*;
use utils::*;
use utils_plus::do_something;
//~^ ERROR: usage of wildcard import
fn main() {
print();
my_util_fn();
do_something();
}

View file

@ -0,0 +1,26 @@
#![warn(clippy::wildcard_imports)]
mod utils {
pub fn print() {}
}
mod utils_plus {
pub fn do_something() {}
}
mod my_crate {
pub mod utils {
pub fn my_util_fn() {}
}
}
use my_crate::utils::*;
use utils::*;
use utils_plus::*;
//~^ ERROR: usage of wildcard import
fn main() {
print();
my_util_fn();
do_something();
}

View file

@ -0,0 +1,11 @@
error: usage of wildcard import
--> $DIR/wildcard_imports.rs:19:5
|
LL | use utils_plus::*;
| ^^^^^^^^^^^^^ help: try: `utils_plus::do_something`
|
= note: `-D clippy::wildcard-imports` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
error: aborting due to 1 previous error

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