From ac609f98e80b25b27f779095e24a0ab726ec0361 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 2 Aug 2026 21:30:02 +1000 Subject: [PATCH 01/26] Distinguish or/refutable/irrefutable patterns in `InterPat` --- .../src/builder/matches/match_pair.rs | 322 +++++++++--------- 1 file changed, 165 insertions(+), 157 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index b4ce8149f5e4d..2dcfbf3ca3098 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -107,113 +107,81 @@ fn squash_inter_pat<'tcx>( extra_data: &mut PatternExtraData<'tcx>, // Bindings/ascriptions are added here ) { // Destructure exhaustively to make sure we don't miss any fields. - let InterPat { - place, - testable_case, - subpats, - or_subpats, - ascriptions, - binding, - pattern_span, - is_never: _, // Not needed by `MatchPairTree` forests. - } = inter_pat; + // The `is_never` field is not needed by `MatchPairTree` forests. + let InterPat { kind, ascriptions, pattern_span, is_never: _ } = inter_pat; // Type ascriptions can appear regardless of whether the node is an or-pattern. extra_data.ascriptions.extend(ascriptions); - // Or and non-or patterns have very different handling. - if let Some(or_subpats) = or_subpats { - // We're dealing with an or-pattern node. - assert!(testable_case.is_none()); - assert!(subpats.is_empty()); - assert!(binding.is_none()); - - let or_subpats = or_subpats - .into_iter() - .map(|subpat| FlatPat::from_inter_pat(subpat)) - .collect::>(); - - if !or_subpats[0].extra_data.bindings.is_empty() { - // Hold a place for any bindings established in (possibly-nested) or-patterns. - // By only holding a place when bindings are present, we skip over any - // or-patterns that will be simplified by `merge_trivial_subcandidates`. In - // other words, we can assume this expands into subcandidates. - // FIXME(@dianne): this needs updating/removing if we always merge or-patterns - extra_data.bindings.push(super::SubpatternBindings::FromOrPattern); - } + // Or patterns, refutable patterns, and irrefutable patterns all have different handling. + match kind { + InterPatKind::Or { or_subpats } => { + let or_subpats = or_subpats + .into_iter() + .map(|subpat| FlatPat::from_inter_pat(subpat)) + .collect::>(); + + if !or_subpats[0].extra_data.bindings.is_empty() { + // Hold a place for any bindings established in (possibly-nested) or-patterns. + // By only holding a place when bindings are present, we skip over any + // or-patterns that will be simplified by `merge_trivial_subcandidates`. In + // other words, we can assume this expands into subcandidates. + // FIXME(@dianne): this needs updating/removing if we always merge or-patterns + extra_data.bindings.push(super::SubpatternBindings::FromOrPattern); + } - match_pairs.push(MatchPairTree { - // Or-patterns never need a place during MIR building. - place: None, - testable_case: TestableCase::Or { pats: or_subpats }, - subpairs: vec![], - pattern_span, - }); - } else { - // We're dealing with a node that isn't an or-pattern. - - // Recursively squash any subpatterns into refutable `MatchPairTree` forests. - // This must happen _before_ pushing the binding, as described by the binding step. - let mut subpairs = vec![]; - for subpat in subpats { - squash_inter_pat(subpat, &mut subpairs, extra_data); + match_pairs.push(MatchPairTree { + // Or-patterns never need a place during MIR building. + place: None, + testable_case: TestableCase::Or { pats: or_subpats }, + subpairs: vec![], + pattern_span, + }); } - if let Some(testable_case) = testable_case { + InterPatKind::Refutable { place, testable_case, subpats } => { + // Recursively squash any subpatterns into refutable `MatchPairTree` forests, + // which will become the children of a new node. + let mut subpairs = vec![]; + for subpat in subpats { + squash_inter_pat(subpat, &mut subpairs, extra_data); + } + // This pattern is refutable, so push a new match-pair node. - // - // If this match is inside a closure, it's essential that the place - // we're testing was actually captured! Be sure to keep `ExprUseVisitor` - // in sync with the refutability checks in this module. - assert!(place.is_some()); assert!(!matches!(testable_case, TestableCase::Or { .. })); - match_pairs.push(MatchPairTree { place, testable_case, subpairs, pattern_span }); - } else { - // This pattern is irrefutable, so it doesn't need its own match-pair node. - // Just push its refutable subpatterns instead, if any. - match_pairs.extend(subpairs); + match_pairs.push(MatchPairTree { + place: Some(place), + testable_case, + subpairs, + pattern_span, + }); } - // If present, the binding must be pushed _after_ traversing subpatterns. - // This is so that when lowering something like `x @ NonCopy { copy_field }`, - // the binding to `copy_field` will occur before the binding for `x`. - // See for more background. - if let Some(binding) = binding { - extra_data.bindings.push(super::SubpatternBindings::One(binding)); + InterPatKind::Irrefutable { subpats, binding } => { + // Recursively squash any subpatterns into refutable `MatchPairTree` forests. + // This must happen _before_ pushing the binding, as described by the binding step. + for subpat in subpats { + // For irrefutable nodes, squash directly into the caller's match pairs. + squash_inter_pat(subpat, match_pairs, extra_data); + } + + // If present, the binding must be pushed _after_ traversing subpatterns. + // This is so that when lowering something like `x @ NonCopy { copy_field }`, + // the binding to `copy_field` will occur before the binding for `x`. + // See for more background. + if let Some(binding) = binding { + extra_data.bindings.push(super::SubpatternBindings::One(binding)); + } } } } /// "Intermediate pattern", a partly-lowered THIR [`Pat`] that has not yet been /// squashed into a forest of refutable [`MatchPairTree`] nodes. -/// -/// FIXME(Zalathar): This could potentially be split into different enum variants -/// for or-patterns and non-or patterns, but for now the flat structure makes -/// construction a bit easier, at the cost of more complicated invariants. struct InterPat<'tcx> { - /// Place that this pattern node will test. - /// - /// If `None`, we're in a closure that didn't capture the relevant place, - /// because it won't actually be tested. - place: Option>, - /// Testable condition to compare the place to (e.g. "is 3" or "is Some"). - /// - /// If `None`, this pattern node is irrefutable or an or-pattern, - /// though it might have refutable descendants. - testable_case: Option>, - - /// Immediate subpatterns of a node that is *not* an or-pattern. - subpats: Vec>, - /// Immediate subpatterns of an or-pattern node. - /// - /// Invariant: If this is Some, then fields `subpats`, `testable_case`, - /// and `binding` must all be empty. - or_subpats: Option]>>, + kind: InterPatKind<'tcx>, ascriptions: Vec>, - /// Binding to establish for a [`PatKind::Binding`] node. - binding: Option>, - /// Span field of the THIR pattern this node was created from. pattern_span: Span, /// True if this pattern can never match, because all of its alternatives @@ -221,6 +189,33 @@ struct InterPat<'tcx> { is_never: bool, } +enum InterPatKind<'tcx> { + Or { + /// The alternatives of an or-pattern, e.g. `P` and `Q` in `P | Q`. + or_subpats: Box<[InterPat<'tcx>]>, + }, + + /// Pattern node that performs some kind of test on a place. + Refutable { + /// Place that this pattern node will test. + place: Place<'tcx>, + /// Testable condition to compare the place to (e.g. "is 3" or "is Some"). + /// + /// Invariant: Must not be [`TestableCase::Or`]. + testable_case: TestableCase<'tcx>, + /// Immediate subpatterns. + subpats: Vec>, + }, + + /// Pattern node that doesn't test anything, though it might have refutable descendants. + Irrefutable { + /// Immediate subpatterns. + subpats: Vec>, + /// Binding to establish for a [`PatKind::Binding`] node. + binding: Option>, + }, +} + impl<'tcx> InterPat<'tcx> { fn lower_thir_pat( cx: &mut Builder<'_, 'tcx>, @@ -250,44 +245,49 @@ impl<'tcx> InterPat<'tcx> { } } - // Variables that will become `InterPat` fields: let place = place_builder.try_to_place(cx); - let mut subpats = vec![]; - let mut or_subpats = None; - let mut ascriptions = vec![]; - let mut binding = None; // Apply any type ascriptions to the value at `match_pair.place`. + let mut ascriptions = vec![]; if let Some(place) = place && let Some(extra) = &pattern.extra { - for &Ascription { ref annotation, variance } in &extra.ascriptions { - ascriptions.push(super::Ascription { + ascriptions.extend(extra.ascriptions.iter().map( + |&Ascription { ref annotation, variance }| super::Ascription { source: place, annotation: annotation.clone(), variance, - }); - } + }, + )); } - let testable_case = match pattern.kind { - PatKind::Missing | PatKind::Wild | PatKind::Error(_) => None, + // For refutable nodes a place must be available, either because it is not a + // closure upvar or because it was captured. + let unwrap_place = || place.expect("refutable patterns must have captured a place"); + + let kind: InterPatKind<'_> = match pattern.kind { + PatKind::Missing | PatKind::Wild | PatKind::Error(_) => { + InterPatKind::Irrefutable { subpats: vec![], binding: None } + } PatKind::Or { ref pats } => { - or_subpats = Some( - pats.iter() - .map(|subpat| InterPat::lower_thir_pat(cx, place_builder.clone(), subpat)) - .collect::>(), - ); - None + let or_subpats = pats + .iter() + .map(|subpat| InterPat::lower_thir_pat(cx, place_builder.clone(), subpat)) + .collect::>(); + InterPatKind::Or { or_subpats } } PatKind::Range(ref range) => { assert_eq!(pattern.ty, range.ty); if range.is_full_range(cx.tcx) == Some(true) { - None + InterPatKind::Irrefutable { subpats: vec![], binding: None } } else { - Some(TestableCase::Range(Arc::clone(range))) + InterPatKind::Refutable { + place: unwrap_place(), + testable_case: TestableCase::Range(Arc::clone(range)), + subpats: vec![], + } } } @@ -311,27 +311,30 @@ impl<'tcx> InterPat<'tcx> { // which could be split out into their own kinds. PatConstKind::Other }; - Some(TestableCase::Constant { value, kind: const_kind }) + + InterPatKind::Refutable { + place: unwrap_place(), + testable_case: TestableCase::Constant { value, kind: const_kind }, + subpats: vec![], + } } PatKind::Binding { mode, var, is_shorthand, ref subpattern, .. } => { // First, recurse into the subpattern, if any. - if let Some(subpattern) = subpattern.as_ref() { - // this is the `x @ P` case; have to keep matching against `P` now - subpats.push(InterPat::lower_thir_pat(cx, place_builder, subpattern)); - } + // This is the `x @ P` case; have to keep matching against `P` now. + let subpat: Option> = subpattern + .as_deref() + .map(|subpattern| InterPat::lower_thir_pat(cx, place_builder, subpattern)); // Then push this binding, after any bindings in the subpattern. - if let Some(place) = place { - binding = Some(super::Binding { - span: pattern.span, - source: place, - var_id: var, - binding_mode: mode, - is_shorthand, - }); - } - None + let binding = place.map(|place| super::Binding { + span: pattern.span, + source: place, + var_id: var, + binding_mode: mode, + is_shorthand, + }); + InterPatKind::Irrefutable { subpats: Vec::from_iter(subpat), binding } } PatKind::Array { ref prefix, ref slice, ref suffix } => { @@ -343,6 +346,8 @@ impl<'tcx> InterPat<'tcx> { ty::Array(_, len) => len.try_to_target_usize(cx.tcx), _ => None, }; + + let mut subpats = vec![]; if let Some(array_len) = array_len { for (subplace, subpat) in prefix_slice_suffix(&place_builder, Some(array_len), prefix, slice, suffix) @@ -361,9 +366,10 @@ impl<'tcx> InterPat<'tcx> { ); } - None + InterPatKind::Irrefutable { subpats, binding: None } } PatKind::Slice { ref prefix, ref slice, ref suffix } => { + let mut subpats = vec![]; for (subplace, subpat) in prefix_slice_suffix(&place_builder, None, prefix, slice, suffix) { @@ -373,24 +379,26 @@ impl<'tcx> InterPat<'tcx> { if prefix.is_empty() && slice.is_some() && suffix.is_empty() { // A slice pattern shaped like `[..]` is irrefutable. // It can match a slice of any length, so no length test is needed. - None + InterPatKind::Irrefutable { subpats, binding: None } } else { // Any other shape of slice pattern requires a length test. // Slice patterns with a `..` subpattern require a minimum // length; those without `..` require an exact length. - Some(TestableCase::Slice { + let testable_case = TestableCase::Slice { len: u64::try_from(prefix.len() + suffix.len()).unwrap(), op: if slice.is_some() { SliceLenOp::GreaterOrEqual } else { SliceLenOp::Equal }, - }) + }; + InterPatKind::Refutable { place: unwrap_place(), testable_case, subpats } } } PatKind::Variant { adt_def, variant_index, args: _, ref subpatterns } => { let downcast_place = place_builder.downcast(adt_def, variant_index); // `(x as Variant)` + let mut subpats = vec![]; for &FieldPat { field, pattern: ref subpat } in subpatterns { let subplace = downcast_place.clone_project(PlaceElem::Field(field, subpat.ty)); subpats.push(InterPat::lower_thir_pat(cx, subplace, subpat)); @@ -401,18 +409,20 @@ impl<'tcx> InterPat<'tcx> { let refutable = adt_def.variants().len() > 1 || adt_def.is_variant_list_non_exhaustive(); if refutable { - Some(TestableCase::Variant { adt_def, variant_index }) + let testable_case = TestableCase::Variant { adt_def, variant_index }; + InterPatKind::Refutable { place: unwrap_place(), testable_case, subpats } } else { - None + InterPatKind::Irrefutable { subpats, binding: None } } } PatKind::Leaf { ref subpatterns } => { + let mut subpats = vec![]; for &FieldPat { field, pattern: ref subpat } in subpatterns { let subplace = place_builder.clone_project(PlaceElem::Field(field, subpat.ty)); subpats.push(InterPat::lower_thir_pat(cx, subplace, subpat)); } - None + InterPatKind::Irrefutable { subpats, binding: None } } PatKind::Deref { pin: Pinnedness::Pinned, ref subpattern } => { @@ -420,20 +430,20 @@ impl<'tcx> InterPat<'tcx> { Some(p_ty) if p_ty.is_ref() => p_ty, _ => span_bug!(pattern.span, "bad type for pinned deref: {:?}", pattern.ty), }; - subpats.push(InterPat::lower_thir_pat( + let subpat = InterPat::lower_thir_pat( cx, // Project into the `Pin(_)` struct, then deref the inner `&` or `&mut`. place_builder.field(FieldIdx::ZERO, pinned_ref_ty).deref(), subpattern, - )); + ); - None + InterPatKind::Irrefutable { subpats: vec![subpat], binding: None } } PatKind::Deref { pin: Pinnedness::Not, ref subpattern } | PatKind::DerefPattern { ref subpattern, borrow: DerefPatBorrowMode::Box } => { - subpats.push(InterPat::lower_thir_pat(cx, place_builder.deref(), subpattern)); - None + let subpat = InterPat::lower_thir_pat(cx, place_builder.deref(), subpattern); + InterPatKind::Irrefutable { subpats: vec![subpat], binding: None } } PatKind::DerefPattern { @@ -446,41 +456,39 @@ impl<'tcx> InterPat<'tcx> { Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, subpattern.ty, mutability), pattern.span, ); - subpats.push(InterPat::lower_thir_pat( - cx, - PlaceBuilder::from(temp).deref(), - subpattern, - )); - Some(TestableCase::Deref { temp, mutability }) + let subpat = + InterPat::lower_thir_pat(cx, PlaceBuilder::from(temp).deref(), subpattern); + InterPatKind::Refutable { + place: unwrap_place(), + testable_case: TestableCase::Deref { temp, mutability }, + subpats: vec![subpat], + } } PatKind::Guard { .. } => { // FIXME(guard_patterns) - None + InterPatKind::Irrefutable { subpats: vec![], binding: None } } - PatKind::Never => Some(TestableCase::Never), + PatKind::Never => InterPatKind::Refutable { + place: unwrap_place(), + testable_case: TestableCase::Never, + subpats: vec![], + }, }; // A pattern node is guaranteed to never match if one of these is true: // - The node itself is a never pattern (`!`). // - It is not an or-pattern, and one of its subpatterns will never match. // - It is an or-pattern, and _all_ of its or-subpatterns will never match. - let is_never = matches!(pattern.kind, PatKind::Never) - || subpats.iter().any(|subpat| subpat.is_never) - || or_subpats - .as_ref() - .is_some_and(|or_subpats| or_subpats.iter().all(|subpat| subpat.is_never)); - - InterPat { - place, - testable_case, - subpats, - or_subpats, - ascriptions, - binding, - pattern_span: pattern.span, - is_never, - } + let is_never = match &kind { + InterPatKind::Refutable { testable_case: TestableCase::Never, .. } => true, + InterPatKind::Refutable { subpats, .. } | InterPatKind::Irrefutable { subpats, .. } => { + subpats.iter().any(|subpat| subpat.is_never) + } + InterPatKind::Or { or_subpats } => or_subpats.iter().all(|subpat| subpat.is_never), + }; + + InterPat { kind, ascriptions, pattern_span: pattern.span, is_never } } } From b12184e40190d7aa87279946ae6dae1290c31cfd Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 3 Aug 2026 00:03:21 +1000 Subject: [PATCH 02/26] Distinguish or/testable patterns in `MatchPairTree` --- .../src/builder/matches/buckets.rs | 30 ++++++--- .../src/builder/matches/match_pair.rs | 18 ++--- .../src/builder/matches/mod.rs | 65 ++++++++++--------- .../src/builder/matches/test.rs | 14 ++-- .../src/builder/matches/util.rs | 59 +++++++++-------- 5 files changed, 96 insertions(+), 90 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/buckets.rs b/compiler/rustc_mir_build/src/builder/matches/buckets.rs index 0d2e9bf87585d..36d3d78c21ec0 100644 --- a/compiler/rustc_mir_build/src/builder/matches/buckets.rs +++ b/compiler/rustc_mir_build/src/builder/matches/buckets.rs @@ -2,12 +2,12 @@ use std::cmp::Ordering; use rustc_data_structures::fx::FxIndexMap; use rustc_middle::mir::Place; -use rustc_middle::span_bug; +use rustc_middle::{bug, span_bug}; use tracing::debug; use crate::builder::Builder; use crate::builder::matches::{ - Candidate, PatConstKind, SliceLenOp, Test, TestBranch, TestKind, TestableCase, + Candidate, MatchPairKind, PatConstKind, SliceLenOp, Test, TestBranch, TestKind, TestableCase, }; /// Output of [`Builder::partition_candidates_into_buckets`]. @@ -131,17 +131,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // than one, but it'd be very unusual to have two sides that // both require tests; you'd expect one side to be simplified // away.) - let (match_pair_index, match_pair) = candidate - .match_pairs - .iter() - .enumerate() - .find(|&(_, mp)| mp.place == Some(test_place))?; + let (match_pair_index, match_pair_testable_case) = + candidate.match_pairs.iter().enumerate().find_map(|(i, mp)| { + if let MatchPairKind::Testable { place, ref testable_case, .. } = mp.kind + && place == test_place + { + Some((i, testable_case)) + } else { + None + } + })?; // If true, the match pair is completely entailed by its corresponding test // branch, so it can be removed. If false, the match pair is _compatible_ // with its test branch, but still needs a more specific test. let fully_matched; - let ret = match (&test.kind, &match_pair.testable_case) { + let ret = match (&test.kind, match_pair_testable_case) { // If we are performing a variant switch, then this // informs variant patterns, but nothing else. ( @@ -174,7 +179,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; let is_conflicting_candidate = |candidate: &&mut Candidate<'tcx>| { candidate.match_pairs.iter().any(|mp| { - mp.place == Some(test_place) && is_covering_range(&mp.testable_case) + matches!(mp.kind, MatchPairKind::Testable { place, ref testable_case, .. } + if place == test_place && is_covering_range(testable_case) + ) }) }; if prior_candidates @@ -364,7 +371,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if fully_matched { // Replace the match pair by its sub-pairs. let match_pair = candidate.match_pairs.remove(match_pair_index); - candidate.match_pairs.extend(match_pair.subpairs); + let MatchPairKind::Testable { subpairs, .. } = match_pair.kind else { + bug!("match pair must have been refutable"); + }; + candidate.match_pairs.extend(subpairs); // Move or-patterns to the end. candidate.sort_match_pairs(); } diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 2dcfbf3ca3098..7ad21b3272783 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -10,7 +10,7 @@ use rustc_span::Span; use crate::builder::Builder; use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder}; use crate::builder::matches::{ - FlatPat, MatchPairTree, PatConstKind, PatternExtraData, SliceLenOp, TestableCase, + FlatPat, MatchPairKind, MatchPairTree, PatConstKind, PatternExtraData, SliceLenOp, TestableCase, }; /// For an array or slice pattern's subpatterns (prefix/slice/suffix), returns a list @@ -130,13 +130,8 @@ fn squash_inter_pat<'tcx>( extra_data.bindings.push(super::SubpatternBindings::FromOrPattern); } - match_pairs.push(MatchPairTree { - // Or-patterns never need a place during MIR building. - place: None, - testable_case: TestableCase::Or { pats: or_subpats }, - subpairs: vec![], - pattern_span, - }); + match_pairs + .push(MatchPairTree { kind: MatchPairKind::Or { or_subpats }, pattern_span }); } InterPatKind::Refutable { place, testable_case, subpats } => { @@ -148,11 +143,8 @@ fn squash_inter_pat<'tcx>( } // This pattern is refutable, so push a new match-pair node. - assert!(!matches!(testable_case, TestableCase::Or { .. })); match_pairs.push(MatchPairTree { - place: Some(place), - testable_case, - subpairs, + kind: MatchPairKind::Testable { place, testable_case, subpairs }, pattern_span, }); } @@ -200,8 +192,6 @@ enum InterPatKind<'tcx> { /// Place that this pattern node will test. place: Place<'tcx>, /// Testable condition to compare the place to (e.g. "is 3" or "is Some"). - /// - /// Invariant: Must not be [`TestableCase::Or`]. testable_case: TestableCase<'tcx>, /// Immediate subpatterns. subpats: Vec>, diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 109f4de2698a4..ca1eebb3c69cf 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1030,7 +1030,7 @@ struct Candidate<'tcx> { /// (see [`Builder::test_remaining_match_pairs_after_or`]). /// /// Invariants: - /// - All or-patterns ([`TestableCase::Or`]) have been sorted to the end. + /// - All or-patterns ([`MatchPairKind::Or`]) have been sorted to the end. match_pairs: Vec>, /// ...and if this is non-empty, one of these subcandidates also has to match... @@ -1116,14 +1116,14 @@ impl<'tcx> Candidate<'tcx> { /// Restores the invariant that or-patterns must be sorted to the end. fn sort_match_pairs(&mut self) { - self.match_pairs.sort_by_key(|pair| matches!(pair.testable_case, TestableCase::Or { .. })); + self.match_pairs.sort_by_key(|pair| matches!(pair.kind, MatchPairKind::Or { .. })); } /// Returns whether the first match pair of this candidate is an or-pattern. fn starts_with_or_pattern(&self) -> bool { matches!( - &*self.match_pairs, - [MatchPairTree { testable_case: TestableCase::Or { .. }, .. }, ..] + self.match_pairs.first(), + Some(MatchPairTree { kind: MatchPairKind::Or { .. }, .. }) ) } @@ -1223,7 +1223,6 @@ enum TestableCase<'tcx> { Slice { len: u64, op: SliceLenOp }, Deref { temp: Place<'tcx>, mutability: Mutability }, Never, - Or { pats: Box<[FlatPat<'tcx>]> }, } impl<'tcx> TestableCase<'tcx> { @@ -1261,32 +1260,32 @@ enum PatConstKind { /// Each node also has a list of subpairs (possibly empty) that must also match, /// and some additional information from the THIR pattern it represents. #[derive(Debug, Clone)] -pub(crate) struct MatchPairTree<'tcx> { - /// This place... - /// - /// --- - /// This can be `None` if it referred to a non-captured place in a closure. - /// - /// Invariant: Can only be `None` when `testable_case` is `Or`. - /// Therefore this must be `Some(_)` after or-pattern expansion. - place: Option>, - - /// ... must pass this test... - testable_case: TestableCase<'tcx>, - - /// ... and these subpairs must match. - /// - /// --- - /// Subpairs typically represent tests that can only be performed after their - /// parent has succeeded. For example, the pattern `Some(3)` might have an - /// outer match pair that tests for the variant `Some`, and then a subpair - /// that tests its field for the value `3`. - subpairs: Vec, +struct MatchPairTree<'tcx> { + kind: MatchPairKind<'tcx>, /// Span field of the THIR pattern this node was created from. pattern_span: Span, } +#[derive(Debug, Clone)] +enum MatchPairKind<'tcx> { + Or { + or_subpats: Box<[FlatPat<'tcx>]>, + }, + Testable { + /// Place that will be tested. + place: Place<'tcx>, + /// Test to perform against the place, and the desired outcome. + testable_case: TestableCase<'tcx>, + + /// Further tests that can only be performed after this test has succeeded. + /// For example, in the pattern `Some(3)` this node might represent a test + /// for the variant `Some`, while a subpair would test its field for the + /// value `3`. + subpairs: Vec>, + }, +} + /// A runtime test to perform to determine which candidates match a scrutinee place. /// /// The kind of test to perform is indicated by [`TestKind`]. @@ -1950,10 +1949,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate: &mut Candidate<'tcx>, match_pair: MatchPairTree<'tcx>, ) { - let TestableCase::Or { pats } = match_pair.testable_case else { bug!() }; - debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats); + let MatchPairKind::Or { or_subpats } = match_pair.kind else { bug!() }; + debug!("expanding or-pattern: candidate={:#?}\nor_subpats={:#?}", candidate, or_subpats); candidate.or_span = Some(match_pair.pattern_span); - candidate.subcandidates = pats + candidate.subcandidates = or_subpats .into_iter() .map(|flat_pat| Candidate::from_flat_pat(flat_pat, candidate.has_guard)) .collect(); @@ -2118,7 +2117,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug_assert!( remaining_match_pairs .iter() - .all(|match_pair| matches!(match_pair.testable_case, TestableCase::Or { .. })) + .all(|match_pair| matches!(match_pair.kind, MatchPairKind::Or { .. })) ); // Visit each leaf candidate within this subtree, add a copy of the remaining @@ -2169,8 +2168,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Extract the match-pair from the highest priority candidate let match_pair = &candidates[0].match_pairs[0]; let test = self.pick_test_for_match_pair(match_pair); - // Unwrap is ok after simplification. - let match_place = match_pair.place.unwrap(); + + let MatchPairKind::Testable { place: match_place, .. } = match_pair.kind else { + bug!("match pair must be testable") + }; debug!(?test, ?match_pair); (match_place, test) diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 1c234bb8d70dc..8e8c73bcb87a2 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -19,7 +19,8 @@ use tracing::{debug, instrument}; use crate::builder::Builder; use crate::builder::matches::{ - MatchPairTree, PatConstKind, SliceLenOp, Test, TestBranch, TestKind, TestableCase, + MatchPairKind, MatchPairTree, PatConstKind, SliceLenOp, Test, TestBranch, TestKind, + TestableCase, }; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -30,7 +31,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, match_pair: &MatchPairTree<'tcx>, ) -> Test<'tcx> { - let kind = match match_pair.testable_case { + // Or-patterns are not tested directly; instead they are expanded into subcandidates, + // which are then distinguished by testing whatever non-or patterns they contain. + let MatchPairKind::Testable { ref testable_case, .. } = match_pair.kind else { + bug!("or-patterns should have already been handled") + }; + let kind = match *testable_case { TestableCase::Variant { adt_def, variant_index: _ } => TestKind::Switch { adt_def }, TestableCase::Constant { value: _, kind: PatConstKind::Bool } => TestKind::If, @@ -51,10 +57,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TestableCase::Deref { temp, mutability } => TestKind::Deref { temp, mutability }, TestableCase::Never => TestKind::Never, - - // Or-patterns are not tested directly; instead they are expanded into subcandidates, - // which are then distinguished by testing whatever non-or patterns they contain. - TestableCase::Or { .. } => bug!("or-patterns should have already been handled"), }; Test { span: match_pair.pattern_span, kind } diff --git a/compiler/rustc_mir_build/src/builder/matches/util.rs b/compiler/rustc_mir_build/src/builder/matches/util.rs index 3246dab73dcbf..fa94a41bad339 100644 --- a/compiler/rustc_mir_build/src/builder/matches/util.rs +++ b/compiler/rustc_mir_build/src/builder/matches/util.rs @@ -6,7 +6,9 @@ use tracing::debug; use crate::builder::Builder; use crate::builder::expr::as_place::PlaceBase; -use crate::builder::matches::{Binding, Candidate, FlatPat, MatchPairTree, TestableCase}; +use crate::builder::matches::{ + Binding, Candidate, FlatPat, MatchPairKind, MatchPairTree, TestableCase, +}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Creates a false edge to `imaginary_target` and a real edge to @@ -159,35 +161,36 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { } fn visit_match_pair(&mut self, match_pair: &MatchPairTree<'tcx>) { - if let TestableCase::Or { pats, .. } = &match_pair.testable_case { - for flat_pat in pats.iter() { - self.visit_flat_pat(flat_pat) - } - } else if matches!(match_pair.testable_case, TestableCase::Deref { .. }) { - // The subpairs of a deref pattern are all places relative to the deref temporary, so we - // don't fake borrow them. Problem is, if we only shallowly fake-borrowed - // `match_pair.place`, this would allow: - // ``` - // let mut b = Box::new(false); - // match b { - // deref!(true) => {} // not reached because `*b == false` - // _ if { *b = true; false } => {} // not reached because the guard is `false` - // deref!(false) => {} // not reached because the guard changed it - // // UB because we reached the unreachable. - // } - // ``` - // Hence we fake borrow using a deep borrow. - if let Some(place) = match_pair.place { - self.fake_borrow(place, FakeBorrowKind::Deep); - } - } else { - // Insert a Shallow borrow of any place that is switched on. - if let Some(place) = match_pair.place { - self.fake_borrow(place, FakeBorrowKind::Shallow); + match match_pair.kind { + MatchPairKind::Or { ref or_subpats } => { + for flat_pat in or_subpats { + self.visit_flat_pat(flat_pat); + } } + MatchPairKind::Testable { place, ref testable_case, ref subpairs } => { + if matches!(testable_case, TestableCase::Deref { .. }) { + // The subpairs of a deref pattern are all places relative to the deref temporary, so we + // don't fake borrow them. Problem is, if we only shallowly fake-borrowed + // `match_pair.place`, this would allow: + // ``` + // let mut b = Box::new(false); + // match b { + // deref!(true) => {} // not reached because `*b == false` + // _ if { *b = true; false } => {} // not reached because the guard is `false` + // deref!(false) => {} // not reached because the guard changed it + // // UB because we reached the unreachable. + // } + // ``` + // Hence we fake borrow using a deep borrow. + self.fake_borrow(place, FakeBorrowKind::Deep); + } else { + // Insert a Shallow borrow of any place that is switched on. + self.fake_borrow(place, FakeBorrowKind::Shallow); - for subpair in &match_pair.subpairs { - self.visit_match_pair(subpair); + for subpair in subpairs { + self.visit_match_pair(subpair); + } + } } } } From a280dde63d9932c67fb57c3ee270800c4c0e3121 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 27 Aug 2026 16:53:18 +1000 Subject: [PATCH 03/26] Rename and combine `then_else_break` to `lower_if_condition` The existing name doesn't give a good intuition for what's actually happening, which is that we lower a (possibly complex) boolean condition and then proceed if it's true or break if it's false. This commit also directly exposes the arguments struct to callers, since it makes the call sites more self-documenting. --- .../rustc_mir_build/src/builder/expr/into.rs | 24 ++--- .../src/builder/matches/mod.rs | 95 +++++++------------ 2 files changed, 49 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index 13a64346c36c4..17d64f5a69c06 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -14,7 +14,7 @@ use rustc_trait_selection::infer::InferCtxtExt; use tracing::{debug, instrument}; use crate::builder::expr::category::{Category, RvalueFunc}; -use crate::builder::matches::{DeclareLetBindings, Exhaustive, HasMatchGuard}; +use crate::builder::matches::{DeclareLetBindings, Exhaustive, HasMatchGuard, LowerIfCondArgs}; use crate::builder::scope::LintLevel; use crate::builder::{BlockAnd, BlockAndExtension, BlockFrame, Builder, NeedsTemporary}; use crate::diagnostics::{LoopMatchArmWithGuard, LoopMatchUnsupportedType}; @@ -85,12 +85,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let (then_block, else_block) = this.in_if_then_scope(condition_scope, then_span, |this| { let then_blk = this - .then_else_break( + .lower_if_condition( block, cond, - Some(condition_scope), // Temp scope - source_info, - DeclareLetBindings::Yes, // Declare `let` bindings normally + LowerIfCondArgs { + temp_scope_override: Some(condition_scope), + variable_source_info: source_info, + declare_let_bindings: DeclareLetBindings::Yes, + }, ) .into_block(); @@ -160,14 +162,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // We first evaluate the left-hand side of the predicate ... let (then_block, else_block) = this.in_if_then_scope(condition_scope, expr.span, |this| { - this.then_else_break( + this.lower_if_condition( block, lhs, - Some(condition_scope), // Temp scope - source_info, - // This flag controls how inner `let` expressions are lowered, - // but either way there shouldn't be any of those in here. - DeclareLetBindings::LetNotPermitted, + LowerIfCondArgs { + temp_scope_override: Some(condition_scope), + variable_source_info: source_info, + declare_let_bindings: DeclareLetBindings::LetNotPermitted, + }, ) }); let (short_circuit, continuation, constant) = match op { diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index ddeb9e084b21d..632049560b67d 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -40,18 +40,26 @@ mod test; mod user_ty; mod util; -/// Arguments to [`Builder::then_else_break_inner`] that are usually forwarded +/// Arguments to [`Builder::lower_if_condition`] that are usually forwarded /// to recursive invocations. #[derive(Clone, Copy)] -struct ThenElseArgs { +pub(crate) struct LowerIfCondArgs { /// Used as the temp scope for lowering `expr`. If absent (for match guards), /// `self.local_scope()` is used. - temp_scope_override: Option, - variable_source_info: SourceInfo, + pub(crate) temp_scope_override: Option, + pub(crate) variable_source_info: SourceInfo, /// Determines how bindings should be handled when lowering `let` expressions. /// /// Forwarded to [`Builder::lower_let_expr`] when lowering [`ExprKind::Let`]. - declare_let_bindings: DeclareLetBindings, + pub(crate) declare_let_bindings: DeclareLetBindings, +} + +impl LowerIfCondArgs { + /// Returns a copy of `self` with [`DeclareLetBindings::LetNotPermitted`]. + /// Used when recursing into a sub-condition that does not permit `let` (e.g. `||` or `!`). + fn let_not_permitted(self) -> Self { + LowerIfCondArgs { declare_let_bindings: DeclareLetBindings::LetNotPermitted, ..self } + } } /// Should lowering a `let` expression also declare its bindings? @@ -83,32 +91,19 @@ pub(crate) enum ScheduleDrops { } impl<'a, 'tcx> Builder<'a, 'tcx> { - /// Lowers a condition in a way that ensures that variables bound in any let - /// expressions are definitely initialized in the if body. + /// Lowers the condition for an `if`-expression or similar construct + /// (including `&&` and `||` expressions, and match-guard conditions). /// - /// If `declare_let_bindings` is false then variables created in `let` - /// expressions will not be declared. This is for if let guards on arms with - /// an or pattern, where the guard is lowered multiple times. - pub(crate) fn then_else_break( - &mut self, - block: BasicBlock, - expr_id: ExprId, - temp_scope_override: Option, - variable_source_info: SourceInfo, - declare_let_bindings: DeclareLetBindings, - ) -> BlockAnd<()> { - self.then_else_break_inner( - block, - expr_id, - ThenElseArgs { temp_scope_override, variable_source_info, declare_let_bindings }, - ) - } - - fn then_else_break_inner( + /// Must be called within [`Builder::in_if_then_scope`], which keeps track + /// of drop scope and knows where to break to if the condition is false. + /// + /// Returns the block for the *true* arm of the condition check. + /// The *true* and *false* arms are returned by [`Builder::in_if_then_scope`]. + pub(crate) fn lower_if_condition( &mut self, block: BasicBlock, // Block that the condition and branch will be lowered into expr_id: ExprId, // Condition expression to lower - args: ThenElseArgs, + args: LowerIfCondArgs, ) -> BlockAnd<()> { let this = self; // See "LET_THIS_SELF". let expr = &this.thir[expr_id]; @@ -116,33 +111,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match expr.kind { ExprKind::LogicalOp { op: LogicalOp::And, lhs, rhs } => { - let lhs_then_block = this.then_else_break_inner(block, lhs, args).into_block(); + let lhs_then_block = this.lower_if_condition(block, lhs, args).into_block(); let rhs_then_block = - this.then_else_break_inner(lhs_then_block, rhs, args).into_block(); + this.lower_if_condition(lhs_then_block, rhs, args).into_block(); rhs_then_block.unit() } ExprKind::LogicalOp { op: LogicalOp::Or, lhs, rhs } => { let local_scope = this.local_scope(); let (lhs_success_block, failure_block) = this.in_if_then_scope(local_scope, expr_span, |this| { - this.then_else_break_inner( - block, - lhs, - ThenElseArgs { - declare_let_bindings: DeclareLetBindings::LetNotPermitted, - ..args - }, - ) + this.lower_if_condition(block, lhs, args.let_not_permitted()) }); let rhs_success_block = this - .then_else_break_inner( - failure_block, - rhs, - ThenElseArgs { - declare_let_bindings: DeclareLetBindings::LetNotPermitted, - ..args - }, - ) + .lower_if_condition(failure_block, rhs, args.let_not_permitted()) .into_block(); // Make the LHS and RHS success arms converge to a common block. @@ -169,14 +150,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if this.tcx.sess.instrument_coverage() { this.cfg.push_coverage_span_marker(block, this.source_info(expr_span)); } - this.then_else_break_inner( - block, - arg, - ThenElseArgs { - declare_let_bindings: DeclareLetBindings::LetNotPermitted, - ..args - }, - ) + this.lower_if_condition(block, arg, args.let_not_permitted()) }); this.break_for_else(success_block, args.variable_source_info); failure_block.unit() @@ -184,10 +158,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::Scope { region_scope, hir_id, value } => { let region_scope = (region_scope, this.source_info(expr_span)); this.in_scope(region_scope, LintLevel::Explicit(hir_id), |this| { - this.then_else_break_inner(block, value, args) + this.lower_if_condition(block, value, args) }) } - ExprKind::Use { source } => this.then_else_break_inner(block, source, args), + ExprKind::Use { source } => this.lower_if_condition(block, source, args), ExprKind::Let { expr, ref pat } => this.lower_let_expr( block, expr, @@ -2448,12 +2422,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let (post_guard_block, otherwise_post_guard_block) = self.in_if_then_scope(match_scope, guard_span, |this| { guard_span = this.thir[guard].span; - this.then_else_break( + this.lower_if_condition( block, guard, - None, // Use `self.local_scope()` as the temp scope - this.source_info(arm.span), - DeclareLetBindings::No, // For guards, `let` bindings are declared separately + LowerIfCondArgs { + temp_scope_override: None, // Use `this.local_scope()`. + variable_source_info: this.source_info(arm.span), + // For guards, `let` bindings are declared separately. + declare_let_bindings: DeclareLetBindings::No, + }, ) }); From fde9cd0719b07cda054d20b403cba09aa96b4c0e Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 27 Aug 2026 17:12:11 +1000 Subject: [PATCH 04/26] Describe if-condition arms as `(true_block, false_block)` This convention is a little less intuitive for simple if-expressions, but is easier to follow when dealing with complex nested conditions or with other if-like constructs. --- compiler/rustc_mir_build/src/builder/block.rs | 31 ++++++--- .../src/builder/coverageinfo.rs | 12 ++-- .../rustc_mir_build/src/builder/expr/into.rs | 57 ++++++++-------- .../src/builder/matches/mod.rs | 66 +++++++++++-------- compiler/rustc_mir_build/src/builder/scope.rs | 33 +++++----- 5 files changed, 114 insertions(+), 85 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/block.rs b/compiler/rustc_mir_build/src/builder/block.rs index 7d85579325751..553b7af91e30c 100644 --- a/compiler/rustc_mir_build/src/builder/block.rs +++ b/compiler/rustc_mir_build/src/builder/block.rs @@ -166,18 +166,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // should never be used to take values at the end of the failure // block. let dummy_place = this.temp(this.tcx.types.never, else_block_span); - let failure_entry = this.cfg.start_new_block(); - let failure_block; - failure_block = this + // An unsuccessful match will jump to this block. + let failure_entry_block = this.cfg.start_new_block(); + let failure_end_block = this .ast_block( dummy_place, - failure_entry, + failure_entry_block, *else_block, this.source_info(else_block_span), ) .into_block(); this.cfg.terminate( - failure_block, + failure_end_block, this.source_info(else_block_span), TerminatorKind::Unreachable, ); @@ -193,7 +193,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let initializer_span = this.thir[*initializer].span; let scope = (*init_scope, source_info); let lint_level = LintLevel::Explicit(*hir_id); - let failure_and_block = this.in_scope(scope, lint_level, |this| { + + // Lower the initializer and test it against the pattern, leading to a + // true path (successful match) and a false path (failure). + let true_and_false_blocks = this.in_scope(scope, lint_level, |this| { this.declare_bindings( visibility_scope, remainder_span, @@ -202,8 +205,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Some((Some(&destination), initializer_span)), ); let else_block_span = this.thir[*else_block].span; - let (matching, failure) = + let (true_block, false_block) = this.in_if_then_scope(last_remainder_scope, else_block_span, |this| { + // Bypass `lower_if_condition` and call `lower_let_expr` directly, + // since we don't have an actual THIR let-expression here. this.lower_let_expr( block, *initializer, @@ -213,10 +218,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { DeclareLetBindings::No, ) }); - matching.and(failure) + // Pack `(true_block, false_block)` into `BlockAnd`. + true_block.and(false_block) }); - let failure = unpack!(block = failure_and_block); - this.cfg.goto(failure, source_info, failure_entry); + // Unpack `BlockAnd` into `(true_block, false_block)`. + let (true_block, false_block); + false_block = unpack!(true_block = true_and_false_blocks); + + // Proceed along the successful path, or jump to the failure path. + block = true_block; + this.cfg.goto(false_block, source_info, failure_entry_block); if let Some(source_scope) = visibility_scope { this.source_scope = source_scope; diff --git a/compiler/rustc_mir_build/src/builder/coverageinfo.rs b/compiler/rustc_mir_build/src/builder/coverageinfo.rs index 2e29600c9339b..67135f2677a6e 100644 --- a/compiler/rustc_mir_build/src/builder/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/builder/coverageinfo.rs @@ -232,13 +232,13 @@ impl<'tcx> Builder<'_, 'tcx> { *block = join_block; } - /// If branch coverage is enabled, inject marker statements into `then_block` - /// and `else_block`, and record their IDs in the table of branch spans. + /// If branch coverage is enabled, inject marker statements into `true_block` + /// and `false_block`, and record their IDs in the table of branch spans. pub(crate) fn visit_coverage_branch_condition( &mut self, mut expr_id: ExprId, - mut then_block: BasicBlock, - mut else_block: BasicBlock, + mut true_block: BasicBlock, + mut false_block: BasicBlock, ) { // Bail out if coverage is not enabled for this function. let Some(coverage_info) = self.coverage_info.as_mut() else { return }; @@ -248,13 +248,13 @@ impl<'tcx> Builder<'_, 'tcx> { if let Some(&NotInfo { enclosing_not, is_flipped }) = coverage_info.nots.get(&expr_id) { expr_id = enclosing_not; if is_flipped { - std::mem::swap(&mut then_block, &mut else_block); + std::mem::swap(&mut true_block, &mut false_block); } } let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope }; - coverage_info.register_two_way_branch(&mut self.cfg, source_info, then_block, else_block); + coverage_info.register_two_way_branch(&mut self.cfg, source_info, true_block, false_block); } /// If branch coverage is enabled, inject marker statements into `true_block` diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index 17d64f5a69c06..39b6389018c8e 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -67,7 +67,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let then_source_info = this.source_info(then_span); let condition_scope = this.local_scope(); - let then_and_else_blocks = this.in_scope( + let true_and_false_blocks = this.in_scope( (if_then_scope, then_source_info), LintLevel::Inherited, |this| { @@ -81,10 +81,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.source_info(then_span) }; - // Lower the condition, and have it branch into `then` and `else` blocks. - let (then_block, else_block) = + // Lower the condition, and have it branch into *true* and *false* blocks. + let (true_block, false_block) = this.in_if_then_scope(condition_scope, then_span, |this| { - let then_blk = this + let true_block = this .lower_if_condition( block, cond, @@ -97,33 +97,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .into_block(); // Lower the `then` arm into its block. - this.expr_into_dest(destination, then_blk, then) + this.expr_into_dest(destination, true_block, then) }); - // Pack `(then_block, else_block)` into `BlockAnd`. - then_block.and(else_block) + // Pack `(true_block, false_block)` into `BlockAnd`. + true_block.and(false_block) }, ); - // Unpack `BlockAnd` into `(then_blk, else_blk)`. - let (then_blk, mut else_blk); - else_blk = unpack!(then_blk = then_and_else_blocks); + // Unpack `BlockAnd` into `(true_block, false_block)`. + let (true_block, mut false_block); + false_block = unpack!(true_block = true_and_false_blocks); - // If there is an `else` arm, lower it into `else_blk`. + // If there is an `else` arm, lower it into `false_block`. if let Some(else_expr) = else_opt { - else_blk = this.expr_into_dest(destination, else_blk, else_expr).into_block(); + false_block = + this.expr_into_dest(destination, false_block, else_expr).into_block(); } else { // There is no `else` arm, so we know both arms have type `()`. // Generate the implicit `else {}` by assigning unit. let correct_si = this.source_info(expr_span.shrink_to_hi()); - this.cfg.push_assign_unit(else_blk, correct_si, destination, this.tcx); + this.cfg.push_assign_unit(false_block, correct_si, destination, this.tcx); } // The `then` and `else` arms have been lowered into their respective // blocks, so make both of them meet up in a new block. let join_block = this.cfg.start_new_block(); - this.cfg.goto(then_blk, source_info, join_block); - this.cfg.goto(else_blk, source_info, join_block); + this.cfg.goto(true_block, source_info, join_block); + this.cfg.goto(false_block, source_info, join_block); join_block.unit() } ExprKind::Let { .. } => { @@ -160,7 +161,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let source_info = this.source_info(expr.span); // We first evaluate the left-hand side of the predicate ... - let (then_block, else_block) = + let (true_block, false_block) = this.in_if_then_scope(condition_scope, expr.span, |this| { this.lower_if_condition( block, @@ -172,36 +173,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }, ) }); - let (short_circuit, continuation, constant) = match op { - LogicalOp::And => (else_block, then_block, false), - LogicalOp::Or => (then_block, else_block, true), - }; + // At this point, the control flow splits into a short-circuiting path // and a continuation path. // - If the operator is `&&`, passing `lhs` leads to continuation of evaluation on `rhs`; // failing it leads to the short-circuting path which assigns `false` to the place. // - If the operator is `||`, failing `lhs` leads to continuation of evaluation on `rhs`; // passing it leads to the short-circuting path which assigns `true` to the place. + let (short_circuit_block, short_circuit_value, continue_block) = match op { + LogicalOp::And => (false_block, false, true_block), + LogicalOp::Or => (true_block, true, false_block), + }; this.cfg.push_assign_constant( - short_circuit, + short_circuit_block, source_info, destination, ConstOperand { span: expr.span, user_ty: None, - const_: Const::from_bool(this.tcx, constant), + const_: Const::from_bool(this.tcx, short_circuit_value), }, ); let mut rhs_block = - this.expr_into_dest(destination, continuation, rhs).into_block(); + this.expr_into_dest(destination, continue_block, rhs).into_block(); // Instrument the lowered RHS's value for condition coverage. // (Does nothing if condition coverage is not enabled.) this.visit_coverage_standalone_condition(rhs, destination, &mut rhs_block); - let target = this.cfg.start_new_block(); - this.cfg.goto(rhs_block, source_info, target); - this.cfg.goto(short_circuit, source_info, target); - target.unit() + // Reunite the continuation path and the short-circuit path. + let join_block = this.cfg.start_new_block(); + this.cfg.goto(rhs_block, source_info, join_block); + this.cfg.goto(short_circuit_block, source_info, join_block); + join_block.unit() } ExprKind::Loop { body } => { // [block] diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 632049560b67d..f6f9d43be6ec8 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -111,30 +111,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match expr.kind { ExprKind::LogicalOp { op: LogicalOp::And, lhs, rhs } => { - let lhs_then_block = this.lower_if_condition(block, lhs, args).into_block(); - let rhs_then_block = - this.lower_if_condition(lhs_then_block, rhs, args).into_block(); - rhs_then_block.unit() + // A condition of `lhs && rhs` is fairly straightforward. + // We can just lower them in sequence, and break if either is false. + let lhs_true_block = this.lower_if_condition(block, lhs, args).into_block(); + let rhs_true_block = + this.lower_if_condition(lhs_true_block, rhs, args).into_block(); + rhs_true_block.unit() } ExprKind::LogicalOp { op: LogicalOp::Or, lhs, rhs } => { + // A condition of `lhs || rhs` is more complicated, because we need to + // short-circuit if `lhs` is *true*. So an inner condition-scope is needed. + // See . let local_scope = this.local_scope(); - let (lhs_success_block, failure_block) = + let (lhs_true_block, lhs_false_block) = this.in_if_then_scope(local_scope, expr_span, |this| { this.lower_if_condition(block, lhs, args.let_not_permitted()) }); - let rhs_success_block = this - .lower_if_condition(failure_block, rhs, args.let_not_permitted()) + let rhs_true_block = this + .lower_if_condition(lhs_false_block, rhs, args.let_not_permitted()) .into_block(); - // Make the LHS and RHS success arms converge to a common block. - // (We can't just make LHS goto RHS, because `rhs_success_block` + // Make the LHS-true and RHS-true arms converge to a common block. + // (We can't just make LHS goto RHS, because `rhs_true_block` // might contain statements that we don't want on the LHS path.) let success_block = this.cfg.start_new_block(); - this.cfg.goto(lhs_success_block, args.variable_source_info, success_block); - this.cfg.goto(rhs_success_block, args.variable_source_info, success_block); + this.cfg.goto(lhs_true_block, args.variable_source_info, success_block); + this.cfg.goto(rhs_true_block, args.variable_source_info, success_block); success_block.unit() } ExprKind::Unary { op: UnOp::Not, arg } => { + // For a condition of `!cond`, lower `cond` as its own condition, + // then invert the meaning of the true/false blocks. + // This avoids an intermediate temporary for negating the condition value. + // See . + // Improve branch coverage instrumentation by noting conditions // nested within one or more `!` expressions. // (Skipped if branch coverage is not enabled.) @@ -143,7 +153,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let local_scope = this.local_scope(); - let (success_block, failure_block) = + let (true_block, false_block) = this.in_if_then_scope(local_scope, expr_span, |this| { // Help out coverage instrumentation by injecting a dummy statement with // the original condition's span (including `!`). This fixes #115468. @@ -152,8 +162,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } this.lower_if_condition(block, arg, args.let_not_permitted()) }); - this.break_for_else(success_block, args.variable_source_info); - failure_block.unit() + // Break if the condition was true; proceed if the condition was false. + this.break_for_else(true_block, args.variable_source_info); + false_block.unit() } ExprKind::Scope { region_scope, hir_id, value } => { let region_scope = (region_scope, this.source_info(expr_span)); @@ -170,7 +181,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { args.variable_source_info.span, args.declare_let_bindings, ), + _ => { + // The condition is an ordinary boolean-valued expression, + // so lower it normally and branch on the result. let mut block = block; let temp_scope = args.temp_scope_override.unwrap_or_else(|| this.local_scope()); let mutability = Mutability::Mut; @@ -189,19 +203,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let operand = Operand::Move(Place::from(place)); - let then_block = this.cfg.start_new_block(); - let else_block = this.cfg.start_new_block(); - let term = TerminatorKind::if_(operand, then_block, else_block); + let true_block = this.cfg.start_new_block(); + let false_block = this.cfg.start_new_block(); + let term = TerminatorKind::if_(operand, true_block, false_block); // Record branch coverage info for this condition. // (Does nothing if branch coverage is not enabled.) - this.visit_coverage_branch_condition(expr_id, then_block, else_block); + this.visit_coverage_branch_condition(expr_id, true_block, false_block); let source_info = this.source_info(expr_span); this.cfg.terminate(block, source_info, term); - this.break_for_else(else_block, source_info); + this.break_for_else(false_block, source_info); - then_block.unit() + true_block.unit() } } } @@ -2419,7 +2433,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut guard_span = rustc_span::DUMMY_SP; - let (post_guard_block, otherwise_post_guard_block) = + let (guard_true_block, guard_false_block) = self.in_if_then_scope(match_scope, guard_span, |this| { guard_span = this.thir[guard].span; this.lower_if_condition( @@ -2448,10 +2462,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { for &(_, temp, _) in fake_borrows { let cause = FakeReadCause::ForMatchGuard; - self.cfg.push_fake_read(post_guard_block, guard_end, cause, Place::from(temp)); + self.cfg.push_fake_read(guard_true_block, guard_end, cause, Place::from(temp)); } - self.cfg.goto(otherwise_post_guard_block, source_info, sub_branch.otherwise_block); + self.cfg.goto(guard_false_block, source_info, sub_branch.otherwise_block); // We want to ensure that the matched candidates are bound // after we have confirmed this candidate *and* any @@ -2488,16 +2502,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { for binding in by_value_bindings.clone() { let local_id = self.var_local_id(binding.var_id, RefWithinGuard); let cause = FakeReadCause::ForGuardBinding; - self.cfg.push_fake_read(post_guard_block, guard_end, cause, Place::from(local_id)); + self.cfg.push_fake_read(guard_true_block, guard_end, cause, Place::from(local_id)); } // Only schedule drops for the last sub-branch we lower. self.bind_matched_candidate_for_arm_body( - post_guard_block, + guard_true_block, schedule_drops, by_value_bindings, ); - post_guard_block + guard_true_block } else { // (Here, it is not too early to bind the matched // candidate on `block`, because there is no guard result diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 26e89cedb3070..17e9486f1db94 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -638,9 +638,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// guards. /// /// For an if-let chain: - /// - /// if let Some(x) = a && let Some(y) = b && let Some(z) = c { ... } - /// + /// ```rust,ignore(illustrative) + /// if let Some(x) = a && let Some(y) = b && let Some(z) = c { ... } + /// ``` /// There are three possible ways the condition can be false and we may have /// to drop `x`, `x` and `y`, or neither depending on which binding fails. /// To handle this correctly we use a `DropTree` in a similar way to a @@ -650,30 +650,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// - We don't need to keep a stack of scopes in the `Builder` because the /// 'else' paths will only leave the innermost scope. /// - This is also used for match guards. - pub(crate) fn in_if_then_scope( + /// + /// Returns blocks for the two condition outcomes, `(true_block, false_block)`. + pub(crate) fn in_if_then_scope( &mut self, region_scope: region::Scope, span: Span, - f: F, - ) -> (BasicBlock, BasicBlock) - where - F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd<()>, - { + // Closure that will lower the condition(s), register breaks, and return `true_block`. + f: impl FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd<()>, + ) -> (BasicBlock, BasicBlock) { let scope = IfThenScope { region_scope, else_drops: DropTree::new() }; let previous_scope = mem::replace(&mut self.scopes.if_then_scope, Some(scope)); - let then_block = f(self).into_block(); + let true_block = f(self).into_block(); let if_then_scope = mem::replace(&mut self.scopes.if_then_scope, previous_scope).unwrap(); assert!(if_then_scope.region_scope == region_scope); - let else_block = - self.build_exit_tree(if_then_scope.else_drops, region_scope, span, None).map_or_else( - || self.cfg.start_new_block(), - |else_block_and| else_block_and.into_block(), - ); + // Lower any break paths (where the condition was false) + // into a drop tree that ends in `false_block`. + let false_block = self + .build_exit_tree(if_then_scope.else_drops, region_scope, span, None) + .map(|false_block: BlockAnd<()>| false_block.into_block()) + .unwrap_or_else(|| self.cfg.start_new_block()); - (then_block, else_block) + (true_block, false_block) } /// Convenience wrapper that pushes a scope and then executes `f` From 422d1fd099d5f447eb029d39d2f95324ffd54bc2 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 27 Aug 2026 18:08:28 +1000 Subject: [PATCH 05/26] Rename `break_for_else` to `break_from_if_then_scope` --- compiler/rustc_mir_build/src/builder/matches/mod.rs | 10 +++++++--- compiler/rustc_mir_build/src/builder/scope.rs | 13 ++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index f6f9d43be6ec8..2085213326188 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -163,7 +163,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.lower_if_condition(block, arg, args.let_not_permitted()) }); // Break if the condition was true; proceed if the condition was false. - this.break_for_else(true_block, args.variable_source_info); + this.break_from_if_then_scope(true_block, args.variable_source_info); false_block.unit() } ExprKind::Scope { region_scope, hir_id, value } => { @@ -213,7 +213,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let source_info = this.source_info(expr_span); this.cfg.terminate(block, source_info, term); - this.break_for_else(false_block, source_info); + this.break_from_if_then_scope(false_block, source_info); true_block.unit() } @@ -2324,6 +2324,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// Use [`DeclareLetBindings`] to control whether the `let` bindings are /// declared or not. + /// + /// Must be called within a [`Builder::in_if_then_scope`], to indicate where + /// to break to if the `let` fails to match. pub(crate) fn lower_let_expr( &mut self, mut block: BasicBlock, @@ -2345,7 +2348,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); let [branch] = built_tree.branches.try_into().unwrap(); - self.break_for_else(built_tree.otherwise_block, self.source_info(expr_span)); + // If pattern-matching failed, break out of the enclosing if-then scope. + self.break_from_if_then_scope(built_tree.otherwise_block, self.source_info(expr_span)); match declare_let_bindings { DeclareLetBindings::Yes => { diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 17e9486f1db94..b7aaa0a52816a 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -1055,12 +1055,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { return self.cfg.start_new_block().unit(); } - /// Sets up the drops for breaking from `block` due to an `if` condition - /// that turned out to be false. + /// Breaks out of the enclosing [`Builder::in_if_then_scope`] due to a + /// condition being false. + /// + /// This adds relevant drops in the drop tree, and adds a dummy terminator + /// that will become a real `goto` when the scope's drop tree is built. /// /// Must be called in the context of [`Builder::in_if_then_scope`], so that /// there is an if-then scope to tell us what the target scope is. - pub(crate) fn break_for_else(&mut self, block: BasicBlock, source_info: SourceInfo) { + pub(crate) fn break_from_if_then_scope(&mut self, block: BasicBlock, source_info: SourceInfo) { let if_then_scope = self .scopes .if_then_scope @@ -1970,7 +1973,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { /// Build a drop tree for a breakable scope. /// /// If `continue_block` is `Some`, then the tree is for `continue` inside a - /// loop. Otherwise this is for `break` or `return`. + /// loop. Otherwise this is for `break`, `return`, or `if`. fn build_exit_tree( &mut self, mut drops: DropTree, @@ -2119,7 +2122,7 @@ impl<'tcx> DropTreeBuilder<'tcx> for ExitScopes { fn link_entry_point(cfg: &mut CFG<'tcx>, from: BasicBlock, to: BasicBlock) { // There should be an existing terminator with real source info and a // dummy TerminatorKind. Replace it with a proper goto. - // (The dummy is added by `break_scope` and `break_for_else`.) + // (The dummy is added by `break_scope` and `break_from_if_then_scope`.) let term = cfg.block_data_mut(from).terminator_mut(); if let TerminatorKind::UnwindResume = term.kind { term.kind = TerminatorKind::Goto { target: to }; From 82ee18a644c39f8b0901e2a795a1b54e83481b46 Mon Sep 17 00:00:00 2001 From: Jeremy Smart Date: Tue, 4 Aug 2026 19:41:25 -0400 Subject: [PATCH 06/26] stabilize map functions --- library/alloc/src/boxed.rs | 4 +--- library/alloc/src/rc.rs | 7 ++----- library/alloc/src/sync.rs | 7 ++----- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 613791448eb5b..1112415e3a875 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -712,14 +712,12 @@ impl Box { /// # Examples /// /// ``` - /// #![feature(smart_pointer_try_map)] - /// /// let b = Box::new(7); /// let new = Box::map(b, |i| i + 7); /// assert_eq!(*new, 14); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + #[stable(feature = "smart_pointer_map", since = "CURRENT_RUSTC_VERSION")] pub fn map(this: Self, f: impl FnOnce(T) -> U) -> Box { let (value, allocation) = Box::take(this); let (raw, alloc) = Box::into_non_null_with_allocator(allocation); diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 37714859ede38..5a76dae6400bd 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1033,8 +1033,6 @@ impl Rc { /// # Examples /// /// ``` - /// #![feature(smart_pointer_try_map)] - /// /// use std::rc::Rc; /// /// let r = Rc::new(7); @@ -1042,7 +1040,7 @@ impl Rc { /// assert_eq!(*new, 14); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + #[stable(feature = "smart_pointer_map", since = "CURRENT_RUSTC_VERSION")] pub fn map(this: Self, f: impl FnOnce(&T) -> U) -> Rc { if size_of::() == size_of::() && align_of::() == align_of::() @@ -4274,7 +4272,6 @@ impl UniqueRc { /// # Examples /// /// ``` - /// #![feature(smart_pointer_try_map)] /// #![feature(unique_rc_arc)] /// /// use std::rc::UniqueRc; @@ -4284,7 +4281,7 @@ impl UniqueRc { /// assert_eq!(*new, 14); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + #[unstable(feature = "unique_rc_arc", issue = "112566")] pub fn map(this: Self, f: impl FnOnce(T) -> U) -> UniqueRc { if size_of::() == size_of::() && align_of::() == align_of::() diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index cca6f881e1740..7dd5393a32295 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1189,8 +1189,6 @@ impl Arc { /// # Examples /// /// ``` - /// #![feature(smart_pointer_try_map)] - /// /// use std::sync::Arc; /// /// let r = Arc::new(7); @@ -1198,7 +1196,7 @@ impl Arc { /// assert_eq!(*new, 14); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + #[stable(feature = "smart_pointer_map", since = "CURRENT_RUSTC_VERSION")] pub fn map(this: Self, f: impl FnOnce(&T) -> U) -> Arc { if size_of::() == size_of::() && align_of::() == align_of::() @@ -4739,7 +4737,6 @@ impl UniqueArc { /// # Examples /// /// ``` - /// #![feature(smart_pointer_try_map)] /// #![feature(unique_rc_arc)] /// /// use std::sync::UniqueArc; @@ -4749,7 +4746,7 @@ impl UniqueArc { /// assert_eq!(*new, 14); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "smart_pointer_try_map", issue = "144419")] + #[unstable(feature = "unique_rc_arc", issue = "112566")] pub fn map(this: Self, f: impl FnOnce(T) -> U) -> UniqueArc { if size_of::() == size_of::() && align_of::() == align_of::() From 178eb4b50fd1bbeef1e2c62c314c8eafe05a235d Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 6 Aug 2026 19:15:04 +0200 Subject: [PATCH 07/26] attach naked function target features to module assembly --- .../rustc_codegen_cranelift/src/global_asm.rs | 1 + compiler/rustc_codegen_gcc/src/asm.rs | 1 + compiler/rustc_codegen_llvm/src/asm.rs | 19 +- compiler/rustc_codegen_ssa/src/base.rs | 2 +- .../rustc_codegen_ssa/src/mir/naked_asm.rs | 4 +- compiler/rustc_codegen_ssa/src/traits/asm.rs | 5 + .../naked-functions/target-feature.rs | 165 ++++++++++++++++++ .../naked-functions/target-feature-aarch64.rs | 47 +++++ .../target-feature-aarch64.sha3.stderr | 10 ++ .../target-feature-aarch64.vanilla.stderr | 18 ++ .../naked-functions/target-feature-s390x.rs | 30 ++++ .../target-feature-s390x.stderr | 10 ++ 12 files changed, 307 insertions(+), 5 deletions(-) create mode 100644 tests/assembly-llvm/naked-functions/target-feature.rs create mode 100644 tests/ui/asm/naked-functions/target-feature-aarch64.rs create mode 100644 tests/ui/asm/naked-functions/target-feature-aarch64.sha3.stderr create mode 100644 tests/ui/asm/naked-functions/target-feature-aarch64.vanilla.stderr create mode 100644 tests/ui/asm/naked-functions/target-feature-s390x.rs create mode 100644 tests/ui/asm/naked-functions/target-feature-s390x.stderr diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 9763b0c0fa867..c5b164b8e9cce 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs @@ -30,6 +30,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for GlobalAsmContext<'_, 'tcx> { operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, _line_spans: &[Span], + _extra_rust_target_features: &[String], ) { codegen_global_asm_inner(self.tcx, self.global_asm, template, operands, options); } diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index ac86fbe7428b0..733dc52465dea 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -928,6 +928,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, line_spans: &[Span], + _extra_rust_target_features: &[String], ) { let asm_arch = self.tcx.sess.asm_arch.unwrap(); diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 549769547da78..6f9ddc1fe2c88 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -414,6 +414,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, _line_spans: &[Span], + extra_rust_target_features: &[String], ) { let asm_arch = self.tcx.sess.asm_arch.unwrap(); @@ -499,14 +500,26 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { template_str.push_str("\n.att_syntax\n"); } - let target_features = self.tcx.global_backend_features(()).join(","); - let target_cpu = llvm_util::target_cpu(self.tcx.sess); + // Globally-enabled features that are already in the backend format. + let global_features = self.tcx.global_backend_features(()).iter().map(String::as_str); + + // Features enabled on a particular instance, in the rust format. + // These need to be translated to the LLVM format. + let function_features: Vec<_> = extra_rust_target_features + .iter() + .flat_map(|feat| llvm_util::to_llvm_features(self.tcx.sess, feat)) + .flat_map(|feat| feat.into_iter().map(|f| format!("+{f}"))) + .collect(); + + let function_features = function_features.iter().map(String::as_str); + let target_features = + global_features.chain(function_features).intersperse(",").collect::(); llvm::append_module_inline_asm( self.llmod, template_str.as_bytes(), &target_features, - target_cpu, + llvm_util::target_cpu(self.tcx.sess), ); } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 9eb4fd510fd7f..c870d1694d068 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -490,7 +490,7 @@ where }) .collect(); - cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans); + cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans, &[]); } else { span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type") } diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 05b87bb6d7159..939e5395e4741 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -54,7 +54,9 @@ pub fn codegen_naked_asm< template_vec.extend(template.iter().cloned()); template_vec.push(rustc_ast::ast::InlineAsmTemplatePiece::String(end.into())); - cx.codegen_global_asm(&template_vec, &operands, options, line_spans); + let target_features: Vec<_> = + cx.tcx().asm_target_features(instance.def_id()).iter().map(|s| s.to_string()).collect(); + cx.codegen_global_asm(&template_vec, &operands, options, line_spans, &target_features); } fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>>( diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs index 85a2fe09ba414..1deed8c4dc016 100644 --- a/compiler/rustc_codegen_ssa/src/traits/asm.rs +++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs @@ -66,12 +66,17 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes { } pub trait AsmCodegenMethods<'tcx> { + /// Codegen a module-level assembly block. + /// + /// NOTE: the target features must be the rust target feature names, not backend target + /// feature names. This argument is used to forward target features on naked functions. fn codegen_global_asm( &mut self, template: &[InlineAsmTemplatePiece], operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, line_spans: &[Span], + extra_rust_target_features: &[String], ); /// The mangled name of this instance diff --git a/tests/assembly-llvm/naked-functions/target-feature.rs b/tests/assembly-llvm/naked-functions/target-feature.rs new file mode 100644 index 0000000000000..500e2a778e475 --- /dev/null +++ b/tests/assembly-llvm/naked-functions/target-feature.rs @@ -0,0 +1,165 @@ +//@ revisions: aarch64-elf aarch64-macho aarch64-coff x86_64 s390x riscv64 powerpc64 loongarch64 +//@ add-minicore +//@ assembly-output: emit-asm +//@ min-llvm-version: 23 +// +//@ [x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//@ [x86_64] needs-llvm-components: x86 +// +//@ [aarch64-elf] compile-flags: --target aarch64-unknown-linux-gnu +//@ [aarch64-elf] needs-llvm-components: aarch64 +//@ [aarch64-macho] compile-flags: --target aarch64-apple-darwin +//@ [aarch64-macho] needs-llvm-components: aarch64 +//@ [aarch64-coff] compile-flags: --target aarch64-pc-windows-gnullvm +//@ [aarch64-coff] needs-llvm-components: aarch64 +// +//@ [s390x] compile-flags: --target s390x-unknown-linux-gnu +//@ [s390x] needs-llvm-components: systemz +// +//@ [powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//@ [powerpc64] needs-llvm-components: powerpc +// +//@ [riscv64] compile-flags: --target riscv64gc-unknown-linux-gnu +//@ [riscv64] needs-llvm-components: riscv +// +// NOTE: loongarch64 does not error when using an instruction without enabling the corresponding +// target feature. +//@ [loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu +//@ [loongarch64] needs-llvm-components: loongarch + +// Test that the #[target_feature(enable = ...)]` works on naked functions. + +#![crate_type = "lib"] +#![feature(no_core, naked_functions_target_feature)] +#![feature(s390x_target_feature, powerpc_target_feature, loongarch_target_feature)] +#![no_core] + +extern crate minicore; +use minicore::*; + +// x86_64-LABEL: vpclmulqdq: +// x86_64: vpclmulqdq +#[no_mangle] +#[unsafe(naked)] +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "vpclmulqdq")] +unsafe extern "C" fn vpclmulqdq() { + naked_asm!("vpclmulqdq zmm1, zmm2, zmm3, 4") +} + +// i8mm is not enabled by default +// +// note that aarch64-apple-darwin enables more features than aarch64-unknown-linux-gnu +// +// aarch64-elf-LABEL: i8mm: +// aarch64-elf: usdot +// aarch64-macho-LABEL: i8mm: +// aarch64-macho: usdot +// aarch64-coff-LABEL: i8mm: +// aarch64-coff: usdot +#[no_mangle] +#[unsafe(naked)] +#[cfg(target_arch = "aarch64")] +#[target_feature(enable = "i8mm")] +unsafe extern "C" fn i8mm() { + naked_asm!("usdot v0.4s, v1.16b, v2.4b[3]") +} + +// riscv64: sh1add: +// riscv64: sh1add +#[no_mangle] +#[unsafe(naked)] +#[cfg(target_arch = "riscv64")] +#[target_feature(enable = "zba")] +unsafe extern "C" fn sh1add() { + naked_asm!("sh1add a0, a1, a2", "ret"); +} + +#[cfg(target_arch = "s390x")] +mod s390x { + use super::*; + + // s390x: vector: + // s390x: vavglg + #[no_mangle] + #[unsafe(naked)] + #[target_feature(enable = "vector")] + unsafe extern "C" fn vector() { + naked_asm!("vavglg %v0, %v0, %v0") + } + + // s390x: vector_enhancements_1: + // s390x: vfcesbs + #[no_mangle] + #[unsafe(naked)] + #[target_feature(enable = "vector-enhancements-1")] + unsafe extern "C" fn vector_enhancements_1() { + naked_asm!("vfcesbs %v0, %v0, %v0") + } + + // s390x: vector_enhancements_2: + // s390x: vclfp + #[no_mangle] + #[unsafe(naked)] + #[target_feature(enable = "vector-enhancements-2")] + unsafe extern "C" fn vector_enhancements_2() { + naked_asm!("vclfp %v0, %v0, 0, 0, 0") + } + + // s390x: vector_packed_decimal: + // s390x: vlrlr + #[no_mangle] + #[unsafe(naked)] + #[target_feature(enable = "vector-packed-decimal")] + unsafe extern "C" fn vector_packed_decimal() { + naked_asm!("vlrlr %v24, %r3, 0(%r2)", "br %r14") + } + + // s390x: vector_packed_decimal_enhancement: + // s390x: vcvbg + #[no_mangle] + #[unsafe(naked)] + #[target_feature(enable = "vector-packed-decimal-enhancement")] + unsafe extern "C" fn vector_packed_decimal_enhancement() { + naked_asm!("vcvbg %r0, %v0, 0, 1") + } + + // s390x: vector_packed_decimal_enhancement_2: + // s390x: vupkzl + #[no_mangle] + #[unsafe(naked)] + #[target_feature(enable = "vector-packed-decimal-enhancement-2")] + unsafe extern "C" fn vector_packed_decimal_enhancement_2() { + naked_asm!("vupkzl %v0, %v0, 0") + } +} + +// powerpc64: power10_vector: +// powerpc64: xxpermx +#[no_mangle] +#[unsafe(naked)] +#[cfg(target_arch = "powerpc64")] +#[target_feature(enable = "power10-vector")] +unsafe extern "C" fn power10_vector() { + naked_asm!("xxpermx 34, 0, 1, 2, 0", "blr") +} + +// loongarch64: lasx: +// loongarch64: xvadd.b +#[no_mangle] +#[unsafe(naked)] +#[cfg(target_arch = "loongarch64")] +#[target_feature(enable = "lasx")] +unsafe extern "C" fn lasx() { + naked_asm!("xvadd.b $xr0, $xr0, $xr1", "ret") +} + +// wasm32: simd128: +// wasm32: i8x16.shuffle +#[no_mangle] +#[unsafe(naked)] +#[cfg(target_arch = "wasm32")] +#[target_feature(enable = "simd128")] +unsafe extern "C" fn simd128() { + naked_asm!("i8x16.shuffle 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15", "return"); +} diff --git a/tests/ui/asm/naked-functions/target-feature-aarch64.rs b/tests/ui/asm/naked-functions/target-feature-aarch64.rs new file mode 100644 index 0000000000000..f82122f773ca0 --- /dev/null +++ b/tests/ui/asm/naked-functions/target-feature-aarch64.rs @@ -0,0 +1,47 @@ +//@ add-minicore +//@ build-fail +//@ revisions: vanilla sha3 +//@ compile-flags: --target aarch64-unknown-linux-gnu -Z deduplicate-diagnostics=yes +//@[sha3] compile-flags: -Ctarget-feature=+sha3 +//@ needs-llvm-components: aarch64 +//@ min-llvm-version: 23 + +#![crate_type = "lib"] +#![feature(no_core, naked_functions_target_feature)] +#![no_core] + +extern crate minicore; +use minicore::*; + +// check that a naked function using target features does not keep these features enabled +// for subsequent asm blocks. + +#[no_mangle] +#[unsafe(naked)] +#[target_feature(enable = "i8mm")] +unsafe extern "C" fn a() { + naked_asm!("usdot v0.4s, v1.16b, v2.4b[3]") +} + +//~? ERROR instruction requires: i8mm + +#[no_mangle] +#[unsafe(naked)] +unsafe extern "C" fn c() { + naked_asm!("usdot v0.4s, v2.16b, v2.4b[3]") +} + +#[no_mangle] +#[unsafe(naked)] +#[target_feature(enable = "sha3")] +unsafe extern "C" fn d() { + naked_asm!("eor3 v0.16b, v1.16b, v2.16b, v3.16b") +} + +//[vanilla]~? ERROR instruction requires: sha3 + +#[no_mangle] +#[unsafe(naked)] +unsafe extern "C" fn b() { + naked_asm!("eor3 v0.16b, v1.16b, v2.16b, v3.16b") +} diff --git a/tests/ui/asm/naked-functions/target-feature-aarch64.sha3.stderr b/tests/ui/asm/naked-functions/target-feature-aarch64.sha3.stderr new file mode 100644 index 0000000000000..49a65eaadb904 --- /dev/null +++ b/tests/ui/asm/naked-functions/target-feature-aarch64.sha3.stderr @@ -0,0 +1,10 @@ +error: instruction requires: i8mm + | +note: instantiated into assembly here + --> :15:1 + | +LL | usdot v0.4s, v2.16b, v2.4b[3] + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/asm/naked-functions/target-feature-aarch64.vanilla.stderr b/tests/ui/asm/naked-functions/target-feature-aarch64.vanilla.stderr new file mode 100644 index 0000000000000..8ac31d19f5e3e --- /dev/null +++ b/tests/ui/asm/naked-functions/target-feature-aarch64.vanilla.stderr @@ -0,0 +1,18 @@ +error: instruction requires: sha3 + | +note: instantiated into assembly here + --> :6:1 + | +LL | eor3 v0.16b, v1.16b, v2.16b, v3.16b + | ^ + +error: instruction requires: i8mm + | +note: instantiated into assembly here + --> :15:1 + | +LL | usdot v0.4s, v2.16b, v2.4b[3] + | ^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/asm/naked-functions/target-feature-s390x.rs b/tests/ui/asm/naked-functions/target-feature-s390x.rs new file mode 100644 index 0000000000000..b0f806c4c0a16 --- /dev/null +++ b/tests/ui/asm/naked-functions/target-feature-s390x.rs @@ -0,0 +1,30 @@ +//@ add-minicore +//@ build-fail +//@ compile-flags: --target s390x-unknown-linux-gnu -Z deduplicate-diagnostics=yes +//@ needs-llvm-components: systemz +//@ min-llvm-version: 23 + +#![crate_type = "lib"] +#![feature(no_core, naked_functions_target_feature)] +#![no_core] + +extern crate minicore; +use minicore::*; + +// check that a naked function using target features does not keep these features enabled +// for subsequent asm blocks. + +#[no_mangle] +#[unsafe(naked)] +#[target_feature(enable = "vector-packed-decimal")] +unsafe extern "C" fn a() { + naked_asm!("vlrlr %v24, %r3, 0(%r2)") +} + +//~? ERROR instruction requires: vector-packed-decimal + +#[no_mangle] +#[unsafe(naked)] +unsafe extern "C" fn b() { + naked_asm!("vlrlr %v24, %r3, 0(%r3)") +} diff --git a/tests/ui/asm/naked-functions/target-feature-s390x.stderr b/tests/ui/asm/naked-functions/target-feature-s390x.stderr new file mode 100644 index 0000000000000..84d60c43bc765 --- /dev/null +++ b/tests/ui/asm/naked-functions/target-feature-s390x.stderr @@ -0,0 +1,10 @@ +error: instruction requires: vector-packed-decimal + | +note: instantiated into assembly here + --> :6:1 + | +LL | vlrlr %v24, %r3, 0(%r3) + | ^ + +error: aborting due to 1 previous error + From 2060175f5af18b4100acf5995979f4bfb31a000c Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sun, 30 Aug 2026 20:53:37 -0400 Subject: [PATCH 08/26] bootstrap: stage0 to cbae9b4cae2b108f6a3d18cfe6075714bb739463 Also contains a formatting change due to rustfmt bump --- src/stage0 | 1203 ++++++++--------- ...rivate-const-fn-only-used-in-const-eval.rs | 4 +- 2 files changed, 602 insertions(+), 605 deletions(-) diff --git a/src/stage0 b/src/stage0 index 247feb05642ae..3426edfafbf16 100644 --- a/src/stage0 +++ b/src/stage0 @@ -13,610 +13,605 @@ nightly_branch=main # All changes below this comment will be overridden the next time the # tool is executed. -compiler_channel_manifest_hash=7c8035eccd259661acc845afb33fb40892f4722327f7d8d8c49feda172d1a159 -compiler_git_commit_hash=f47d5bb13648d5c859f5b438eb7dc834b9729961 -compiler_date=2026-08-18 +compiler_channel_manifest_hash=1612da194f5a1c699d7a20519341ed9aa62e29f28bf3f303ab6801e8e266b103 +compiler_git_commit_hash=cbae9b4cae2b108f6a3d18cfe6075714bb739463 +compiler_date=2026-08-30 compiler_version=beta -rustfmt_channel_manifest_hash=bcbc0888e7f826a04d404f32618e159234d3c866929403b9a23843011aa74bf9 -rustfmt_git_commit_hash=8fa1c96cfd489e4c27654c144ae871ce2c4db6c6 -rustfmt_date=2026-08-18 +rustfmt_channel_manifest_hash=d950b3b494cde6b8448964e1795a86530bff7ee5e729a48ed6341c6ec3ee5ad1 +rustfmt_git_commit_hash=fd7ed57dfd3bdebb745a1d8158638727b0e7047a +rustfmt_date=2026-08-30 rustfmt_version=nightly -dist/2026-08-18/rustc-beta-aarch64-apple-darwin.tar.gz=4e04b1d8e2de5099073f7165c9473ae6e6b5cf7206382a6f943d37f557f90252 -dist/2026-08-18/rustc-beta-aarch64-apple-darwin.tar.xz=23f57cd995a7131558c74da34707dbafae6b89a1557534820c7d5f09a030c80e -dist/2026-08-18/rustc-beta-aarch64-pc-windows-gnullvm.tar.gz=c5b821b82d01fcd996bc2937abcbe6b395d7869dc12ba72ff1895282bd4acec3 -dist/2026-08-18/rustc-beta-aarch64-pc-windows-gnullvm.tar.xz=ca7098528a3f9eb604036943dab84bb9c83733c95de79748b249762fa3c309d3 -dist/2026-08-18/rustc-beta-aarch64-pc-windows-msvc.tar.gz=18be6800753c250d59d4558b4d3210bb5565b0f64b76e93a310967df031785f9 -dist/2026-08-18/rustc-beta-aarch64-pc-windows-msvc.tar.xz=1310e973389038d668781e0e53bfd1817f72774b9974dcac39599a00e60130b6 -dist/2026-08-18/rustc-beta-aarch64-unknown-freebsd.tar.gz=d52701206dab37eeff082d1fdd3ca4158b6c3fe391ec14a1b124e314db82b50b -dist/2026-08-18/rustc-beta-aarch64-unknown-freebsd.tar.xz=5363d51a3c0349a6306234743cee60432f4725678fa8efb1a046ecc9f3a3c0bd -dist/2026-08-18/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=3855b3810d036cbe22ec3ee1e924f8fa85222399f84f0205c75d4e7e13dfdfe1 -dist/2026-08-18/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=db329b33fed3303ce317e15054e22c599b50794362ed1a9643500671908c8a95 -dist/2026-08-18/rustc-beta-aarch64-unknown-linux-musl.tar.gz=f5f329b194f4b57b9ce226b79142f8ff040b9b8a46627efd0611fe9476faa100 -dist/2026-08-18/rustc-beta-aarch64-unknown-linux-musl.tar.xz=debf6ca1b5df26926eefb86cd78b16a4785c6e901cb7420753efea9e173a5725 -dist/2026-08-18/rustc-beta-aarch64-unknown-linux-ohos.tar.gz=6844476814d2bb90b53af87b94c4851d74a77cb071ebda6902223a8594f51597 -dist/2026-08-18/rustc-beta-aarch64-unknown-linux-ohos.tar.xz=8c522be24939b1529ae1861ebb9d5d0d51a74145d88fddd252cdfc6bec19e867 -dist/2026-08-18/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=717dd10b35c068afb1f241caba5488aed9a2f7cf4b187be2dfc0cd888932e19d -dist/2026-08-18/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=3569084f389294cad8314db51601a51f84fdf562f125169a01a1326f6b190d6f -dist/2026-08-18/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=a93b5721ceb24371de80046fa72923b182df2ffdf571ce217f31531178caa4cc -dist/2026-08-18/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=36e7b26884281544d386c9faef0d45e92387032f6f3825725ba922d5ade8fdfb -dist/2026-08-18/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=2120ad8499f7d18f1bdc382796af43d257c15f5c40e49aa158ed92e057e801bc -dist/2026-08-18/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=575b270ece686b6fb8545cd8ca7de143d8cb0b46987e554f5f35dc2caa02a9ec -dist/2026-08-18/rustc-beta-i686-pc-windows-gnu.tar.gz=ae4f7ce459c4bcadc7fa2b58e47071d131e378df6b08c4ce2d1f7d9e8f375cae -dist/2026-08-18/rustc-beta-i686-pc-windows-gnu.tar.xz=c821cabd5de0c7167b27911a6f1a55e1194be915ab16259ba039f762605846de -dist/2026-08-18/rustc-beta-i686-pc-windows-msvc.tar.gz=24bb41d3dce7e9b66468654bd35b765ae435da92e626a6e5f23c0ec13b8d982a -dist/2026-08-18/rustc-beta-i686-pc-windows-msvc.tar.xz=aa1457f95d957283f7bc0858fcd43399277cc7e7dc32410a15377ad828352111 -dist/2026-08-18/rustc-beta-i686-unknown-linux-gnu.tar.gz=9f42adaf503c9afaac3b20b7b877af2ef2af563b5fd02d11cde3f5f231a27380 -dist/2026-08-18/rustc-beta-i686-unknown-linux-gnu.tar.xz=62ea2c3ea2ad18009968d2656d0bb603a3ca1ec9d0a13531b52b81194b29050b -dist/2026-08-18/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=1c9e9e6fddd7d89382be658235819a4bc05b122d0a7ef716d4ab365721eb798d -dist/2026-08-18/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=7ffef16a0588c5428906aa2546a19c4333a7fb4cc689cca2d598a13a086612cb -dist/2026-08-18/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=3e9f29411e26fbf96e97fb2b5bb6e6c4b3310dfd583163b19a2d5dc559e6bfc8 -dist/2026-08-18/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=fb545c822175c6f3bd3975e988eaf472a4349d890e3453932ed289891031099b -dist/2026-08-18/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=a45c291440db15376e06f67c752d0d4d31cd03a706c4ecca9c75686e4e1f9503 -dist/2026-08-18/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=dd12b86878741ed0b348d85060aac1bd7e64327b87f8c9d92cce16bb78736a88 -dist/2026-08-18/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=02bb7a5d7524e8eef2fd6a182b9d3335ce89a8454f8bed8ea1e37a4fa8360029 -dist/2026-08-18/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=0f6ebebc1d45dd8a05e108631f05d726badcfa9f2a56bb6f366cf01f8850cbd0 -dist/2026-08-18/rustc-beta-powerpc64-unknown-linux-musl.tar.gz=3a81060f6a6b6c5130cc9ca7e33aaadab0e5efab4113c9e6c90eb1bb3742002a -dist/2026-08-18/rustc-beta-powerpc64-unknown-linux-musl.tar.xz=787c1702bb8a3f390ff4f2fa724fa357cd780446bdf9492d0b528f155d63a400 -dist/2026-08-18/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=41e6812404daf866dda17d6389f2dd164d48e227bc91207d6ec17964e2796c30 -dist/2026-08-18/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=d1f8f153e216356bf034d804a816c874e2cb0a1b2a289f7e944bf07e52f55c3e -dist/2026-08-18/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=765771107ada2703cc0528affeafe47334bf8fc9816c6103d1acf388602029f2 -dist/2026-08-18/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=3f913b5a72f14ebabc07c6cf80a0fe2ea6fd450355ead4fd027183849a93d316 -dist/2026-08-18/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=680b09e7b774c6deb0ce1e6a630d1cfc40d8d6a7a0eec84fc5a342cde16c30b3 -dist/2026-08-18/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=aba55cab20c6c384f0660047ea2c1e5c7f0607be751d78009d089be824ff178a -dist/2026-08-18/rustc-beta-riscv64gc-unknown-linux-musl.tar.gz=f178f8b873cbdad29ebd9c3bf77288ab198e71e1245e382d7daa1fdaeef0ca13 -dist/2026-08-18/rustc-beta-riscv64gc-unknown-linux-musl.tar.xz=80a6a15d4f647d4d2f271e4b730b7bc95abff3e040ca65f78937ffa1cdea6028 -dist/2026-08-18/rustc-beta-s390x-unknown-linux-gnu.tar.gz=b9b7bd2d193dc92cb4bfc2903b295d6661026ffec7d03691169675d7c839602b -dist/2026-08-18/rustc-beta-s390x-unknown-linux-gnu.tar.xz=61ca8e658188cb8657bac8f8c197c79bdd18f7bf50929b2c83905f21777bd8b8 -dist/2026-08-18/rustc-beta-sparcv9-sun-solaris.tar.gz=dfcab6819e60e6d8168bbcd9ae6179c1764d6d4fd5bb50585e686c97ab882ecb -dist/2026-08-18/rustc-beta-sparcv9-sun-solaris.tar.xz=595e66e81982690ff4249a58b0e7551b06884ec61dcf2db146b1123190274b28 -dist/2026-08-18/rustc-beta-x86_64-apple-darwin.tar.gz=381bd8e703643b8eaabbd4a6d57810d7d3d3be88f3c8c4b00a7463426cd8ffb4 -dist/2026-08-18/rustc-beta-x86_64-apple-darwin.tar.xz=61bc970524afc5daa0922e94cb5ba6c4ceedfae02500e8d02f4aad8a78e66b30 -dist/2026-08-18/rustc-beta-x86_64-pc-solaris.tar.gz=a3615e85f1ecb3adb6a2730473d98d509939c0f03cc365114b2dfcbfe73cf21b -dist/2026-08-18/rustc-beta-x86_64-pc-solaris.tar.xz=b0d62333a8d1207c6ba8a5668737252e2fdd8807c51be1f7716de6411459d1fe -dist/2026-08-18/rustc-beta-x86_64-pc-windows-gnu.tar.gz=c56b41ac05d836723b5782660ef09a66a0f40eb08d7bcac261c40a7f2d573e45 -dist/2026-08-18/rustc-beta-x86_64-pc-windows-gnu.tar.xz=1659dca16389fe3534712e460541a47be22d0c108a97dd7d8c3f3b7b3d57c5d1 -dist/2026-08-18/rustc-beta-x86_64-pc-windows-gnullvm.tar.gz=bf006112bd8f4de8d6f5487fbeb81b50145353243d96790bbdee5db64438f6cc -dist/2026-08-18/rustc-beta-x86_64-pc-windows-gnullvm.tar.xz=70ed4cb39020b89e7a750788aaec9fb375c46b6f2a834260f3ad3b1add6c8f0b -dist/2026-08-18/rustc-beta-x86_64-pc-windows-msvc.tar.gz=2c3988db60d89a8d87a3ff3a796cf3246579c5bddbf04d966050beb8065978c3 -dist/2026-08-18/rustc-beta-x86_64-pc-windows-msvc.tar.xz=876caa0be5e7b089fd8277a4257e2e088d129e2b90df5860b35b5669197c760a -dist/2026-08-18/rustc-beta-x86_64-unknown-freebsd.tar.gz=4a059078cdb1677a8eceb7aae1eed70ed228bd790564927df8b3ecbbda348857 -dist/2026-08-18/rustc-beta-x86_64-unknown-freebsd.tar.xz=32d8f974359bab0158e7e29985f50eaef90e9b4ed6afba20e456459cc693354b -dist/2026-08-18/rustc-beta-x86_64-unknown-illumos.tar.gz=64d67ee42a8099946482ac57f4a5aea941162296041ab244f18c6eae22b72fd4 -dist/2026-08-18/rustc-beta-x86_64-unknown-illumos.tar.xz=fb161219e0c9119e13d3d3e29252d8ca14b207e376925318688d980451f924c3 -dist/2026-08-18/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=f9e6ae7af4c3a8044b53e63afdfb57da7d81afb6c76b4dc56fc9dbd655147988 -dist/2026-08-18/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=984458ef8cfe2e544ff9002b29aae08d77368713d905d236fd31a9ea41234d5c -dist/2026-08-18/rustc-beta-x86_64-unknown-linux-musl.tar.gz=08673148e2beff75af3bd110833b9d00a5d6f08faf87f5ef89e4a8f3943bb460 -dist/2026-08-18/rustc-beta-x86_64-unknown-linux-musl.tar.xz=857c0346c487d9a1bd7ef9fb14b36259ba0654845ff48a3b9967c49b9a589359 -dist/2026-08-18/rustc-beta-x86_64-unknown-netbsd.tar.gz=e15857d6f2b2f21b6cf188db2260d5490e2be3531d430b9994e8934329095c01 -dist/2026-08-18/rustc-beta-x86_64-unknown-netbsd.tar.xz=2a5c52fee84fc55836aee4189f16737b60b31f712157ba8a4ebb15c4d8499fe2 -dist/2026-08-18/rust-std-beta-aarch64-apple-darwin.tar.gz=34834a3732a7acc760a1eaeea63ddd74338d5b9bc54f12098a2b3ca3c65e6787 -dist/2026-08-18/rust-std-beta-aarch64-apple-darwin.tar.xz=9329d72e3f56915f580f9968ba50a5055e32c3466b20e2c59309f3fc560b9826 -dist/2026-08-18/rust-std-beta-aarch64-apple-ios.tar.gz=8b4df0bd79bf101064d6c785a25405830947ecd9b42e1bf5209af926bb29ea99 -dist/2026-08-18/rust-std-beta-aarch64-apple-ios.tar.xz=be4d8fe624282bd30c3a67811f5e14f32dc16013480b364eacedcf39be5b2976 -dist/2026-08-18/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=2f1804ad64cf220db1d8ceed5c898002604ba0c26ce29100c68f80ce1c5b4a8a -dist/2026-08-18/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=24a621ab6c15670ff5c456e1e6843389dc3c5312799bae9a218c66c82ddba52f -dist/2026-08-18/rust-std-beta-aarch64-apple-ios-sim.tar.gz=833645565f778c3783fba3f008c9620155c731b5c98e35686972f7a5093a964b -dist/2026-08-18/rust-std-beta-aarch64-apple-ios-sim.tar.xz=55d0507f3904efb1d005bdd13c2a131c2935aabea3c1620931c2e79a195564a9 -dist/2026-08-18/rust-std-beta-aarch64-apple-tvos.tar.gz=1a50623dadf720e75ceba9fdc48207db2c80c70d3d052e431ce4181a38479522 -dist/2026-08-18/rust-std-beta-aarch64-apple-tvos.tar.xz=9ac966df182833b323f4293fa63e4bb24e07cbbec0ffc96758d860c712a3c775 -dist/2026-08-18/rust-std-beta-aarch64-apple-tvos-sim.tar.gz=4ac899af9afd534ece4d4894752889d63355390b27da040bfea240b4314f7bf8 -dist/2026-08-18/rust-std-beta-aarch64-apple-tvos-sim.tar.xz=4095069b71b40cc6966b48d0eac459fe54627c8abf8b07867f56e32a6a7ee984 -dist/2026-08-18/rust-std-beta-aarch64-apple-visionos.tar.gz=8cba6a324f3e03aa0001199ed21aea27caa1951223050204bfefc11db93e6301 -dist/2026-08-18/rust-std-beta-aarch64-apple-visionos.tar.xz=3062fb044995d684f495583f2f90b707e1a60655043ec539038ef2e064ff1a4f -dist/2026-08-18/rust-std-beta-aarch64-apple-visionos-sim.tar.gz=80693d5bddc90add2b3889efecbc33e94dce5f7b77763db83bf089ecdbb5bd6b -dist/2026-08-18/rust-std-beta-aarch64-apple-visionos-sim.tar.xz=643307ce75ac8dd24192468607e36306dbff89f92b75cbd38604abf5b188c297 -dist/2026-08-18/rust-std-beta-aarch64-apple-watchos.tar.gz=ea41e3775809ec9f5fefd158801e82987e027d28556b8beb8000a965d2303263 -dist/2026-08-18/rust-std-beta-aarch64-apple-watchos.tar.xz=a86df724b5e843038e2e8c796d87ebda49e87c364b8d94410a36d079180f384a -dist/2026-08-18/rust-std-beta-aarch64-apple-watchos-sim.tar.gz=c0b7c2c5e945b54003e1449db974dcda1dbb9287fe1d04e60c1e7b3c44a55138 -dist/2026-08-18/rust-std-beta-aarch64-apple-watchos-sim.tar.xz=57b245490bb3208b0531e59a59d9dd393c5ba251903706b539bed962ec4d705d -dist/2026-08-18/rust-std-beta-aarch64-linux-android.tar.gz=32844779365cb1f7ff6f0c23ef25041c2428f0431ee7aadebe0d3c7202e6472e -dist/2026-08-18/rust-std-beta-aarch64-linux-android.tar.xz=b5610133a25db38f19b305a02e01a8f70a3dba06abc790c8d98264968cfb65c8 -dist/2026-08-18/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=5347597c4547cfcb92e87f64fad06cb6f0398d017370be2618ffd25c62ce77ed -dist/2026-08-18/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=c82e0315ff536d1680b1f7b72cf02f58048f37824e90848322536a2cd6733c8e -dist/2026-08-18/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=c7961799c6eaf17b0761116dd34717d44c305e5c72b6799bf5219a821966b3e6 -dist/2026-08-18/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=8ca6c068d24a4f0e68e6ba32842fc90624c474edce560eb2ee15d78cc8952ae6 -dist/2026-08-18/rust-std-beta-aarch64-unknown-freebsd.tar.gz=cb921d27103accc84ceb60ab8bdb1555f42570156ac24117c94c7f373463d21f -dist/2026-08-18/rust-std-beta-aarch64-unknown-freebsd.tar.xz=ef81216d517d2512305943dd1e7e8be2c355990581a86821bf73c40c39013256 -dist/2026-08-18/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=b98d1928d05baa48a904dd0ee22a2c22bdecc008b1279b6475dcb860a350223b -dist/2026-08-18/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=fef6c278692eb43215f8ace09cf1cb4aea8664dbf72bf6096b814454adf5658e -dist/2026-08-18/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=1f97f2e0738bcb2ce250e48975a8b8fbcd70506285be4384caa2e7e360c90638 -dist/2026-08-18/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=812c4d65cb4c94d0298163dc4a9895fa0d6454d37d343af0d83eec41a8b28a1a -dist/2026-08-18/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=1750b0d88d77910f1ee9ca73cfaf72c459f330cb666217e06b37e2b17ca80319 -dist/2026-08-18/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=c5212cab3b201497d96b156f097cf8290174f938e4a93cfac720158b52319a3e -dist/2026-08-18/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=bb2838a893c513de58e87f736e4ea4038fb4c990afc4c18da82ff6a7826bbf7f -dist/2026-08-18/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=fffc1c914777a192781564e7d0ad626605083085c7295d4fca08ca1797ce2afb -dist/2026-08-18/rust-std-beta-aarch64-unknown-none.tar.gz=29fda5895f9add0c81fa1d5547999a02675f48c289ad0f288e69d2594e1e8543 -dist/2026-08-18/rust-std-beta-aarch64-unknown-none.tar.xz=82fc6096a49543fdce15d5d686250403c1789a849e09c0da6508d728bfaafe00 -dist/2026-08-18/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=2ff6ce8f11fb5623061a4ce0bd83a2397c51a74b0fa018ae400e93ec6ca95b69 -dist/2026-08-18/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=5a9c290858327f612b1c090ca8a61ca8535f4ebbb4091e99888fc8fddea91498 -dist/2026-08-18/rust-std-beta-aarch64-unknown-uefi.tar.gz=0a493ae8437efbe27c36edd7a27c436df95b1d71f91b6347a5bd22c32a2c8d23 -dist/2026-08-18/rust-std-beta-aarch64-unknown-uefi.tar.xz=fb5564beaa147e5f1e4a38c076c9df70a9836c041fc5ece7023ff49d82908da8 -dist/2026-08-18/rust-std-beta-arm-linux-androideabi.tar.gz=e2dbaff7a2868eb72825878ed7fb45c1b567c432999996240c0bdbf15be71f93 -dist/2026-08-18/rust-std-beta-arm-linux-androideabi.tar.xz=61bb58c6b73ff6ae587a2e86f2f921e70da132dcaf3176a5620c37d41af793f0 -dist/2026-08-18/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=41e980987fb1db88074228b5525d5ae00462ac2dc29a22b712785ade9b89199e -dist/2026-08-18/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=ec0c9a221402fd508a846e4dd7fc92ed6d8afdd99a06bb28bd5214ad91a8715b -dist/2026-08-18/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=07cfd6006c5551e266c0b862c8abe17daf8ce4027a7c18f845044bf5d6ba8cda -dist/2026-08-18/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=b81824402050964457fb7930fa3556ed35f79d6fc7ac496a074e8f766a8fa967 -dist/2026-08-18/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=ab1d60983a7a65723b98398989cc73d3bdcf30f055592f89af1d7d15ad2a4fa3 -dist/2026-08-18/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=12518d18c2b2ccaf1e0821a262a84f06a96cb98007aeb950f6702a3ba93bf25b -dist/2026-08-18/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=75aa7f1551a3b573b4ec0c39e7c1e7e66a6fd8fc6bd8c8f1f2d0cc4dd617ad9e -dist/2026-08-18/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=5b554f3d76b0271ab3c241a9c518e991bd1d9c547c3cfabd753463c9173c2caf -dist/2026-08-18/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=3664fec431f39b3b8ab8511124ba7aa55a8cb094c931bb627d04ace7490b23d6 -dist/2026-08-18/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=bd6647ae522fc81f979328c1afe2959c2f635a663a3cd9f33b52b943e3a06226 -dist/2026-08-18/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=3958e36d7bc0c19069ee721b34798e2abc529ffd71fa30e131cee115d53cac28 -dist/2026-08-18/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=27976b41113939065bb389aaa6530687e0cc60e4a9c5663826d394dec8ea19ee -dist/2026-08-18/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=5b8cea4d1cc40af06f7715a5aec3596e0165f90836648e78615f61ed0d7f675a -dist/2026-08-18/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=72fc0625e95ed31619a37099a478c82d9b7ffe7e8f5defcde2735f613a81bb0a -dist/2026-08-18/rust-std-beta-armv7-linux-androideabi.tar.gz=b703064c3a27b22ef57056db5009103d854e8bdf39622103dad58ee9f9150e4a -dist/2026-08-18/rust-std-beta-armv7-linux-androideabi.tar.xz=4a03d3a9d9a002306b5bdb7cb5cfb170f6c5ecffe624a244acce3807ddf35ceb -dist/2026-08-18/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=9aae96ab8882a45588998feb941764ed5e5d0df2ab32cf3d6d281029e9a09707 -dist/2026-08-18/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=337278c86fc2f998a50ce25f8fd5cdd5d3a41b92eb30e2bd4c01aea1dbc66720 -dist/2026-08-18/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=6a8bd67c2029f181ee41a9315afe936e8641f15406bf4301b6d441d3028540e0 -dist/2026-08-18/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=8477c949c59dea0003897cc3a5624ba011b335192c9d8354ea0b371252646ae1 -dist/2026-08-18/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=3fdfe336fc7fe6304304b0e1cba416c44d4344acc3c8e92aff9650bd61e78add -dist/2026-08-18/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=e9b310c49fbaeaef5c4260e403b1df4dd3223c77574db2be4d6dd4e129c6105e -dist/2026-08-18/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=5ef1634babcd37af66128f46c3384a7bcf936b54212bb79f91f651a14e61e79a -dist/2026-08-18/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=7a19827f6ccbe866689f798d5cb85337a123e3170c33e7526c9568c8f6aa7ef9 -dist/2026-08-18/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=b7819cd9f01e881ee55ac742290e36ff08b01f26302cc54378fb241aec9f12b3 -dist/2026-08-18/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=a7befe40f281f00182b4874726f6575797fce00144ec88ed588da323824f2889 -dist/2026-08-18/rust-std-beta-armv7a-none-eabi.tar.gz=ade7b42b966bc689acb6cd70b08d3426d6a2b72c8088dc21a55edcdaf16674ea -dist/2026-08-18/rust-std-beta-armv7a-none-eabi.tar.xz=4fa9375932737c11fb58b00091ed0bae2726843fb99fb9d3d3adadd922d99ed8 -dist/2026-08-18/rust-std-beta-armv7a-none-eabihf.tar.gz=573ab85be5e7ccdb2095979bb585a5ff0ae939acec60be1d8465e6394e494028 -dist/2026-08-18/rust-std-beta-armv7a-none-eabihf.tar.xz=1484581e5d9af650f22da71f9d6349bf50e7e5a52601dc7c7e3ce482a76b1733 -dist/2026-08-18/rust-std-beta-armv7r-none-eabi.tar.gz=581b334afa99cbf801ee3d3ca0a644f3b6e44071dc46d6de4259bbc63238a366 -dist/2026-08-18/rust-std-beta-armv7r-none-eabi.tar.xz=dc0065ffe0672dbacae3986760aa843216bb8a4ec84c10d6050e3d6f29a81df2 -dist/2026-08-18/rust-std-beta-armv7r-none-eabihf.tar.gz=f11b94b577afff0f9b7f31c492e8e11a90f41a2b128d4a48be1af96d61fc325c -dist/2026-08-18/rust-std-beta-armv7r-none-eabihf.tar.xz=117da690023ee06e258a4efdacd4611c9cdc9d666af45d57ca59a6f11af0098d -dist/2026-08-18/rust-std-beta-armv8r-none-eabihf.tar.gz=0b4609dd9c98de14f996f89739cb2fcf6eb7e5ac4ae1150dca02d0559c50d05c -dist/2026-08-18/rust-std-beta-armv8r-none-eabihf.tar.xz=c0c3006daecc37acb35aeadf02fe95f84a36a9bb95792e4fe999cce9067e79c0 -dist/2026-08-18/rust-std-beta-i586-unknown-linux-gnu.tar.gz=ccd007bea8986e20876377d6ee626fb546bf4d58e6f6bc9277bc875850d162c0 -dist/2026-08-18/rust-std-beta-i586-unknown-linux-gnu.tar.xz=d1fead88db7a134f096ab6dd4de1970ab6934878d74919c6211ec15db6d33a1a -dist/2026-08-18/rust-std-beta-i586-unknown-linux-musl.tar.gz=ef5d4b552d0924c42b84270828c8fc68f092e3b52aa9d21134c9d67b97257b76 -dist/2026-08-18/rust-std-beta-i586-unknown-linux-musl.tar.xz=ef51f4e7059cdf6bb8a6cce9717b42d5d429988dba84261804a0fb513667706c -dist/2026-08-18/rust-std-beta-i686-linux-android.tar.gz=c53aed6571880b250a2497eac0b42f6cdd568d961bc87b0022b1e9ede7f0fa58 -dist/2026-08-18/rust-std-beta-i686-linux-android.tar.xz=18fb44e0bbaba05e2261588d8c4bd709c220e6e270ec6173fc0b10e379dae8b0 -dist/2026-08-18/rust-std-beta-i686-pc-windows-gnu.tar.gz=24bcf9e24998ced5bdb6b786d880776f6c1019876749afde55ba6d73dcea8fd5 -dist/2026-08-18/rust-std-beta-i686-pc-windows-gnu.tar.xz=9009e3b19474ea7eecf4032ffcde52335870daf1515221b1092ef8c76b99dc06 -dist/2026-08-18/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=9df7c78051113071c6b2616e20014324a64e8f3f3670a4a36f9023299b6b7c64 -dist/2026-08-18/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=1b10465d807043c035db811c1cf4969f9d0c322bb8558f274533a9305e37af9d -dist/2026-08-18/rust-std-beta-i686-pc-windows-msvc.tar.gz=e0a69a32e978b2d0134d3d3c6a1246959dc4cd1d7c4e81ea7d01bca4ebc2e6c3 -dist/2026-08-18/rust-std-beta-i686-pc-windows-msvc.tar.xz=a4b54b0268d1820b6c1c31ae73b288a5d2869a2ff6f64e17bf91ebd0449f6d10 -dist/2026-08-18/rust-std-beta-i686-unknown-freebsd.tar.gz=a3b9949948cf9482b7f462b0355bbd63b093ace7c0e02f1be7e92475b5419823 -dist/2026-08-18/rust-std-beta-i686-unknown-freebsd.tar.xz=cdbd22ae0966afcbd0bea8b6686cee392d8a293069ec80a3e571445f9382bbc6 -dist/2026-08-18/rust-std-beta-i686-unknown-linux-gnu.tar.gz=b3c435de1b8e7384f3c10f518f4910ae482b4f5f65c850ee1c417c61c8810bff -dist/2026-08-18/rust-std-beta-i686-unknown-linux-gnu.tar.xz=9537a3cd2d2ec665f5939fb1ae385d889813749d872e5d712f899500f352e927 -dist/2026-08-18/rust-std-beta-i686-unknown-linux-musl.tar.gz=86a15ced2374683aa3057a7e94f90ef49f88a4e88382604ff67732a2b1fc11f4 -dist/2026-08-18/rust-std-beta-i686-unknown-linux-musl.tar.xz=ecf636e1477b0597aa7452c5832853fdfbacee3314cbc7718de7bf0713df7559 -dist/2026-08-18/rust-std-beta-i686-unknown-uefi.tar.gz=eb5a0f499dfb1bac444e3dc882a9394c92bea31b0474a24da511100c9ad23774 -dist/2026-08-18/rust-std-beta-i686-unknown-uefi.tar.xz=fbd30e34ed7644acdbe55f78eed1ceb4396cd03a25864a3c6e1901c9119be3ef -dist/2026-08-18/rust-std-beta-loongarch32-unknown-none.tar.gz=90bc2e6610d4b9e3e3fd8841b6000d9926e5a5cf569789645dd96687f81b5bb1 -dist/2026-08-18/rust-std-beta-loongarch32-unknown-none.tar.xz=bf9c673894c724fa31122e9914fdd3e114ecf20251014e903981ad51a371c1d1 -dist/2026-08-18/rust-std-beta-loongarch32-unknown-none-softfloat.tar.gz=11fd9f4b909ce0dbb58997e5bcf0387186d7d154107bd084eb26ac5c41b61294 -dist/2026-08-18/rust-std-beta-loongarch32-unknown-none-softfloat.tar.xz=a1a0dc03fd40e4a77d0e1551d5c4d8741789efcb3d157f5f9533ff07d6adb9d4 -dist/2026-08-18/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=cad9ce9002b37341d7ae52b4acd6d50cb712af1443079f2c301313699413e9bb -dist/2026-08-18/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=9285c13a94a0d3480ee50b72fc7f26d00fc97f3afd4b57a2287b21035e3dc821 -dist/2026-08-18/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=57943248450839c467dd817f11dae6a9ce7ca19726d696fc211861d584908aa7 -dist/2026-08-18/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=dbfb7582486a7352f64a9a6c500d53921ae7520cbdbf79ebff770181315df42e -dist/2026-08-18/rust-std-beta-loongarch64-unknown-none.tar.gz=02de7811f7559a69ba441f4185fce172bb2343adf74fcbdbbea93a457202f733 -dist/2026-08-18/rust-std-beta-loongarch64-unknown-none.tar.xz=dcf2ce821b50aa3db0d944b83c74e3ffce54dd752cb3e20180d8e0f76806c234 -dist/2026-08-18/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=26061f8fe261d1be1e0c39d4f0d43013d0f4152f511364102d7086e8c99aec20 -dist/2026-08-18/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=035e63e86a1ed04a4d267b2eb4a1d73d088227ac70ac0686c648b47190b1541a -dist/2026-08-18/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=0751c940c4e555c43eac082cd0ca4a55c71fe084978478817a54a5e6fb4069f1 -dist/2026-08-18/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=da142c0f895799f9e988b596edcc1abe89c5243c364ed6a8cd0f18ba9fad7bbd -dist/2026-08-18/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=82f148ada0f7a0c0e887720b647e348849c7f7416455afb8807abdc895d08cc7 -dist/2026-08-18/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=75e1a9b47514b72bb26e24b74dac3d7f9297e9a24e7d685b091bf6c08d995f98 -dist/2026-08-18/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=33e13d632efe4765ab2093eab4fc68f4202223f274e0350b72673625f3478ca9 -dist/2026-08-18/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=71c058fe88ec219a8fcfbc5ac4d20af66726db797f9ffd587bff081b2ca64081 -dist/2026-08-18/rust-std-beta-powerpc64-unknown-linux-musl.tar.gz=8d57d035e2bd60d11f5ed31ca94896e78e5fd665e4825f70e11cca2d53f6985d -dist/2026-08-18/rust-std-beta-powerpc64-unknown-linux-musl.tar.xz=3ca6248f199bf9aed97549b96440dc1decd102282e72be2d1873b1571d12eae7 -dist/2026-08-18/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=bd0336716b73e4110f1140048fbc0f65492737a8d2febf238543455884814d40 -dist/2026-08-18/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=de06218dd3797cd9b634abb6f595c654e8f478858c4091ec2ec41ab62b303854 -dist/2026-08-18/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=9d0ad884617ebe1033e6dfe91673c15e5751b04663afeb25fbf9b14c725623b6 -dist/2026-08-18/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=417d40ab222a2add87d277711983e1d846235c4221f64b54c5ef643d898af40c -dist/2026-08-18/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=5e494883642b408d716715234845d26d2172446cf1ce330d6658a310da8cb127 -dist/2026-08-18/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=a1c089849361724dd9106c6dd7447402e40ed4851bebd444cfaab2aa1f2fe293 -dist/2026-08-18/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=d2a0c901bbf91ef5933e7f66d64e5635a6cbdd428b665789400f9efc9b926081 -dist/2026-08-18/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=04f2999eaa1b38e6800d0c725ad761932430d6fdac9c841b7e7e0b30b681933c -dist/2026-08-18/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=e977988456540ea9280802102cd4d3a48f745940400960c1d22b64de2a0297e0 -dist/2026-08-18/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=8681ca97d702581f48229342921f064f65babd5688be88426d5eb553e9b8f481 -dist/2026-08-18/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=d430ba157c422f3d5cc2390c58f7304b69dc7dcd72ac26f7ec988e04e1c1b886 -dist/2026-08-18/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=ae7011392aed6d69a7c3c57ffe639ddf0b8c5e6151e35badc7d1d522203328b5 -dist/2026-08-18/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=0ea48d15d79f29d9aa8f0488f2626eb54e29da9db308728e6cb2ed3f8ef52d44 -dist/2026-08-18/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=02b2901a9d3df3ea58733327147073150b6449a5eb13c34a65819eabc9c7dccd -dist/2026-08-18/rust-std-beta-riscv64a23-unknown-linux-gnu.tar.gz=0573dd8ac8eadbd8366eddf11f08886a2a8f0930ce3640638160f4bf98d6b5c0 -dist/2026-08-18/rust-std-beta-riscv64a23-unknown-linux-gnu.tar.xz=eeb6909ded0c7c04b295fe3e79d3db9eed6b2f21f6e720cce5f1822311153583 -dist/2026-08-18/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=b2bf8d4a8789627acfd37ff732eadc6657ec6e07aaa42f8d51d139d84933274e -dist/2026-08-18/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=d0037e7da6ac8cb0e9fea048e93c4bdf878d0be6339cbf890a97930605232357 -dist/2026-08-18/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=bf52f259973d538fec8a903370be3b347e5d3ee341ce8f0cf42386668705bd99 -dist/2026-08-18/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=23b92d8e7e40922c395d4997be32a5c580b1dab4fcfb1b80e515eb18957b4327 -dist/2026-08-18/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=419d18bf44b0b0308fbd7c6d623064cde8eb8672ac6d81d24dc5b2a1b98e690d -dist/2026-08-18/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=98db402b82cad0495a8021b4da09df41421eb6f3e249493d06a00af5c5b5a3d5 -dist/2026-08-18/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=4d12962b4350783e6d976da210ebb10e0f5f98c97d828ff3201742e25a12fc2a -dist/2026-08-18/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=a33b67d9f80db5845e423f21fad8bdc8ce8f81eed11528bb488ad995762f04bd -dist/2026-08-18/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=40e3ceedbd8efdae307e29082bb4aafebf9712d58316a2c93d85e96f8b91b4bb -dist/2026-08-18/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=b4c3f8b9b6f454d295b0e4487fd48ef87b74e9a83455de1d135810c485f81a48 -dist/2026-08-18/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=d5576fd1f9a3383b08ac07347f44ea0bee108faebdbaac2aacaa3e40b8c75fd5 -dist/2026-08-18/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=b6c983501fd9072db9041eb90770128e3bfaca71e52f9772108bba3d126530fd -dist/2026-08-18/rust-std-beta-sparcv9-sun-solaris.tar.gz=41d93cbe9bcc9237988a159364809b36456d4b7ceea69ed0f71c7ef3371376c5 -dist/2026-08-18/rust-std-beta-sparcv9-sun-solaris.tar.xz=369d00cb600849f69c20a4094433e4fcf199632d31110fc48d053dcf78528323 -dist/2026-08-18/rust-std-beta-thumbv6m-none-eabi.tar.gz=feaa560f63a5edfe234bcbc019a14e610a311c26311cc1cd9c5fc321c0a3dc16 -dist/2026-08-18/rust-std-beta-thumbv6m-none-eabi.tar.xz=9cd3af4baa64ee8e49cb2dbe3a2116ddec18ddf17e631ba806486afc8f9fae99 -dist/2026-08-18/rust-std-beta-thumbv7a-none-eabi.tar.gz=bbcb01314c8551cfd921030da82e7f7d9159205f2e0ad92b32c03ef5e24b348a -dist/2026-08-18/rust-std-beta-thumbv7a-none-eabi.tar.xz=e75c6fc1dfcffe2a6cc59019d63c17978ce35f2bb327ffead1a7c5ad23093741 -dist/2026-08-18/rust-std-beta-thumbv7a-none-eabihf.tar.gz=fc7ba754b6a5aace65805071b00cd6d8bee45985af55409efa78801979190375 -dist/2026-08-18/rust-std-beta-thumbv7a-none-eabihf.tar.xz=4cbd907d064d7cfa5fa50d01cc0eb340ef2d043542ccf9beb53c69ac6bc962bc -dist/2026-08-18/rust-std-beta-thumbv7em-none-eabi.tar.gz=aa793233f7bb7fe0cddd7c5a5cdbdae37045bdd2ade9ad324a783d6e2fc38139 -dist/2026-08-18/rust-std-beta-thumbv7em-none-eabi.tar.xz=565eae0f73e5f34fba9497e1952989bc5c33628b2035b4845fe7df9b1747553b -dist/2026-08-18/rust-std-beta-thumbv7em-none-eabihf.tar.gz=9d3a12dd7fdfbc6c79218e4c48d750648a3414af9bbd119497539274f55942aa -dist/2026-08-18/rust-std-beta-thumbv7em-none-eabihf.tar.xz=2eb2d70d1477f5c7bdcc55864f71a9d35c4ce0003137422513cc0afde74790cb -dist/2026-08-18/rust-std-beta-thumbv7m-none-eabi.tar.gz=c487a3ae94aa8987715f8b2c81554b88fb46a953c60c7915b1ae06050208321d -dist/2026-08-18/rust-std-beta-thumbv7m-none-eabi.tar.xz=130f816b0dd9bbc3e33626b91f9a172c41894942561d7bf70fc84a354cb1539c -dist/2026-08-18/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=433d6557f9f3fe7bef498508887d849c762947b47b19606df2847183376a0540 -dist/2026-08-18/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=b0be39d694e7f3585c91a1a8a477c97679ec40486cdab3788a916e955a1567a8 -dist/2026-08-18/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=d21a967b1e0449f743953d8b73ea7cf66d03672195711a822b3101c6f66b7528 -dist/2026-08-18/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=780512ddb91330a366fa8183e793667cc1ec37384da08495faedced5f0d89e93 -dist/2026-08-18/rust-std-beta-thumbv7r-none-eabi.tar.gz=a96f2769c37781202b359c93fccdf7bcb88f2de7be28536c15e1edc18b9f6419 -dist/2026-08-18/rust-std-beta-thumbv7r-none-eabi.tar.xz=755fcca4591e5cfaa2f1eac8a191844006531d4d45e3f66e22ddef4477b66082 -dist/2026-08-18/rust-std-beta-thumbv7r-none-eabihf.tar.gz=ad60aa1c0f5eb69cba9cf3048a8404b8b519a3218ce1971b4d4d172e694c07ec -dist/2026-08-18/rust-std-beta-thumbv7r-none-eabihf.tar.xz=f8b3a42c17f98387c8a35940e6ddd8246e48e87a97388bf01259c5203d0b4aaf -dist/2026-08-18/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=abda1031eea6925d529842e5777475c79a62d4e0ee68003e108a85f6107f80f9 -dist/2026-08-18/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=e7ea22d26dd3f87bbc618c954f047c32e15189bca3730ac390a4670822e55d6e -dist/2026-08-18/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=f9c224b391cbf3bd8f4f1abd82a8cab80fc7099935f46b846d687627d23ca6b9 -dist/2026-08-18/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=b68e769e593444a1b09981f1517ce9217e02e8ac997cbb1caa514c8cdf5bbd1b -dist/2026-08-18/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=def20bc12fa35b64dcdd05669351ad6e15238dd15830eb88fc11c7298ed4bbcb -dist/2026-08-18/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=de82adeb27d1247e67e96d78ee46a8e3a1f9f5240a9ae75680e8b30fff3d13c2 -dist/2026-08-18/rust-std-beta-thumbv8r-none-eabihf.tar.gz=b77cd1ddaa277ae2de9bb683249b5220e47a8a3ffbbffd42f7eb0c547e2854bc -dist/2026-08-18/rust-std-beta-thumbv8r-none-eabihf.tar.xz=f2f6d6e4ab4b2cd7f02f2f1927adae35c869bbdb4d47af955bc0395fed05256d -dist/2026-08-18/rust-std-beta-wasm32-unknown-emscripten.tar.gz=a2c4876eb3a6a217e18e835bb4845483db2d31489713cbe3a0e70cfad4ffd46f -dist/2026-08-18/rust-std-beta-wasm32-unknown-emscripten.tar.xz=5012e27d94c93c9de88d36f6e80d109156b3c98824e63f38d48be70099da6ed9 -dist/2026-08-18/rust-std-beta-wasm32-unknown-unknown.tar.gz=2cccf18769ad214b6cfc86f12ccbc6bffc9e3b6d0ff5cc3cb9c3b864daad9d35 -dist/2026-08-18/rust-std-beta-wasm32-unknown-unknown.tar.xz=672aa082395be89a958b718bf65efbfac9674af366ca04fdf6426643b49baa1d -dist/2026-08-18/rust-std-beta-wasm32-wasip1.tar.gz=9d8c6c2fd9116236036a782a70b7c2aca953f22a3114c0cacaaf343a0f1d47d9 -dist/2026-08-18/rust-std-beta-wasm32-wasip1.tar.xz=ab889ce4db42f253dc4ea2b95824218e8b8d0f08608ed8857941a85c4fe0d04e -dist/2026-08-18/rust-std-beta-wasm32-wasip1-threads.tar.gz=98fffa4fc85dfcd2725929158146f19466742fe58cd0a4ee53f24ffdd18afe76 -dist/2026-08-18/rust-std-beta-wasm32-wasip1-threads.tar.xz=a453485e1a0b76aef806f73d4903d4b2d9a068a47c38fa6ed1f8c4075deb2619 -dist/2026-08-18/rust-std-beta-wasm32-wasip2.tar.gz=b07bc47ba8d0fa7d6d5749686ae1335c60c6995b8150bf6bcd60d71fc4ff0980 -dist/2026-08-18/rust-std-beta-wasm32-wasip2.tar.xz=6b7b1e6f097d298709335b1dd34d109cfef42195dbb55250d9f13983cc36aae6 -dist/2026-08-18/rust-std-beta-wasm32v1-none.tar.gz=e8ae650b7a0e0e63c837c7a8b26fac1e60c53ae5cbf062c97999f563e5b37f93 -dist/2026-08-18/rust-std-beta-wasm32v1-none.tar.xz=bf4e91d4eb2fdea5a38847df2fa435543e435b0cb118368cfc4f4e226130c792 -dist/2026-08-18/rust-std-beta-x86_64-apple-darwin.tar.gz=9f0c07733b3ce60ad0e6b2b94899359d10b48237edc56a87e67c396ff8f6f7de -dist/2026-08-18/rust-std-beta-x86_64-apple-darwin.tar.xz=19a832229cb48e0292c591f986cb304ecafe0b99d02c084e8c958960e1da1920 -dist/2026-08-18/rust-std-beta-x86_64-apple-ios.tar.gz=a7637319dd2ed867914a7294112c2b4b8614b3fab1d81223853858a3468b1248 -dist/2026-08-18/rust-std-beta-x86_64-apple-ios.tar.xz=f9ea76c0533b9ed163bbbdfaa4c46d59e6245f4a815b9e0af3cecbe1ea7a65fc -dist/2026-08-18/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=62c682bf98f9359174d1d5eaf9c0d02f07a901d35a9cc9d07811e52ef6dda082 -dist/2026-08-18/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=69d907f47da87fd4822972f59ff991f86144f0c2dff8465ffd107bb6517c36f6 -dist/2026-08-18/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=8d2a4e09e3472d55865bfaabe4087241d6602834a914dd980396f682c4fc3d1c -dist/2026-08-18/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=5fc7ebb2ec72193fd3bea974a29bcdf4f4807191c0f94dbfc8ee9575bc32615c -dist/2026-08-18/rust-std-beta-x86_64-linux-android.tar.gz=1bf77b56ec03260ea17d1a3910d53331ecd9b10c0c1936ab95e316fa172688ed -dist/2026-08-18/rust-std-beta-x86_64-linux-android.tar.xz=2d5dc26bf724b1aa1b98e92bcff52a8e70f259bf19c5e793595e8fa9e4e452a6 -dist/2026-08-18/rust-std-beta-x86_64-pc-solaris.tar.gz=a30a78879ee94297ff5399dc84412ed083097deda10f9990076fc61b816d8f7c -dist/2026-08-18/rust-std-beta-x86_64-pc-solaris.tar.xz=19b960b55da422632779b09df31daaeaaae0103b16b1b520af4b1cec75bd7641 -dist/2026-08-18/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=927d02ab22fa436a2aa63f15eb3bd07a0ddcfae14e9e4ba746eaba22e67ccdf2 -dist/2026-08-18/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=9ff3bb08d2622fe4a012d13cb68ee800f802220d65e6796c016bf7da080453bc -dist/2026-08-18/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=ce0729a8e6b27ef85c061fd48d1c301504181e00da85c4e2c605f09a1c6b20d7 -dist/2026-08-18/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=7a2440b42cc956862b279116dcbdcc5e50bf08a5b3a2dc5ba1cfe744cdaf6e14 -dist/2026-08-18/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=f165427ae926cffcff75ab6a29fb1376fccc7e21bebfd74d0c2a48e42824da36 -dist/2026-08-18/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=0c0955300d9c8b86fe8bc96b4b909ef1ea8df2418eb9e7a4a79bf5b789d9830d -dist/2026-08-18/rust-std-beta-x86_64-unknown-freebsd.tar.gz=6138f76740a957614d600cfc4dd75da376a49038ec67981a2a0d4a2ae132fd07 -dist/2026-08-18/rust-std-beta-x86_64-unknown-freebsd.tar.xz=b1463bc56af553251f9ff437e8c8a943113ba840c086c7a5a5ada90df03b1b97 -dist/2026-08-18/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=737d6c1765f9f9abf1d19c4b7c02b2e217fb1fe8d315456abdaaf7ec583a50ef -dist/2026-08-18/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=470bfa673d0aa4aacd7bff4370943c2ec0aa0b7b77ae17b8fea38ff1eb744fde -dist/2026-08-18/rust-std-beta-x86_64-unknown-illumos.tar.gz=deeca38b53e700671c553342cfde9609e121c2b392db8694d6a1d99f81d84738 -dist/2026-08-18/rust-std-beta-x86_64-unknown-illumos.tar.xz=06d4153c8d3bedfe19184a5c9eca4fa11a989da0c178897f594d133a5c391dd5 -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=2cc5cea651371e4ae2b8cbae1e9b2b226f2ae814e72260c189aa87b408651c69 -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=43fb198f1a3c3b9d2c056bd8b818128356014732a1a1de16027ed927b559ef0d -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-gnuasan.tar.gz=9fc4dc11ac79631173c5d61bd51e5a5c215da2784c46f6d31d6e010a45681349 -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-gnuasan.tar.xz=edf9de2127f330877fd108e9eb74514cf2c401f12eb3f3c065489eef68bf24ce -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-gnumsan.tar.gz=b14ed9acde7162a5d64a731f35db5f93ef40b745c39079cd37b1e4c916d2054b -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-gnumsan.tar.xz=ac1269c347b1d5bc3c44fa3e61b16b7aae0573428fd79732d837dcdf98f58acf -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-gnutsan.tar.gz=1572a2f9b94dab1abff33c262448a677b64da34e1644128479121a5cd918f769 -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-gnutsan.tar.xz=b2054ff433da395465819c7be4cb9ec43fd526c5aa9e00265ad327cf333e2477 -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=ba7a9ca84f37a7e7f4e5b8a9ac7348e41a2f275c625833a1a9bd84642fef4122 -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=96795295816bdd7d31633f9a0f99db06d97ed1763b97fc92fc897d8d624707fd -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=575f397c532d297e6a0ea5e7b150f0494684b8afd085eb25e62006af87ae4be3 -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=36029c14a57a5687a1aab57a6c742d6f300d6aac3f54f103c8571632f8903047 -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=6e765b32274d7c513af104afd323530aca14155828b6d15ea56ba57b36ec6110 -dist/2026-08-18/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=c829acf9d3eae4d2fc338b1a65357e3685c29f80a2a5dedfa7d28a9b98cefeea -dist/2026-08-18/rust-std-beta-x86_64-unknown-netbsd.tar.gz=5d5cd4bcc16d52d15d8ff64c51b3a10df87fe811260659253ad89d26ad105fa0 -dist/2026-08-18/rust-std-beta-x86_64-unknown-netbsd.tar.xz=b5f5d13c1ba56fefd789dba094eef61abcfc7b59e03b34583606599c8a1f9177 -dist/2026-08-18/rust-std-beta-x86_64-unknown-none.tar.gz=d250f8849e1a0d33564dadce29e1c257778a4da67f4de2d2333f22546ee5cfd0 -dist/2026-08-18/rust-std-beta-x86_64-unknown-none.tar.xz=a0f6930fe4808ff4a31539c33509d9015c92024a1c3c2c3dee1f1b04a4eb65cf -dist/2026-08-18/rust-std-beta-x86_64-unknown-redox.tar.gz=9756c71c869dc619372ae4eb24a96252709bbcf8039a5502347ec00418a99c58 -dist/2026-08-18/rust-std-beta-x86_64-unknown-redox.tar.xz=73a698c9099bad4115fcc650bfdc611d497bf46b1b77b7b721b8453b723fcb06 -dist/2026-08-18/rust-std-beta-x86_64-unknown-uefi.tar.gz=77222a2b46518d5aeb9652d7e939a0654c6a8441ae608e958dc77ad045a4b45f -dist/2026-08-18/rust-std-beta-x86_64-unknown-uefi.tar.xz=ad7118856f9a41706cc6465efa9118dfd00259f656f79bfe52d22374b86adf5b -dist/2026-08-18/cargo-beta-aarch64-apple-darwin.tar.gz=424927100212831a294b17c04b196e5a5de82681dfaf86991533406051791192 -dist/2026-08-18/cargo-beta-aarch64-apple-darwin.tar.xz=c6e606cc652aa373368283d8246de82667c32284935b3dbca0abac0f5a8f14a8 -dist/2026-08-18/cargo-beta-aarch64-pc-windows-gnullvm.tar.gz=898c236611c6c350d3075d06fd22426edf0c6edcff6f2c81cb25a83560486241 -dist/2026-08-18/cargo-beta-aarch64-pc-windows-gnullvm.tar.xz=912630573060444545fb1c17493acd7ee62396f0893dbee10a0ca703701c8c51 -dist/2026-08-18/cargo-beta-aarch64-pc-windows-msvc.tar.gz=f046787529f076ee159bfb5503432ce9d9d1dddc78c3c665c85564c433177f08 -dist/2026-08-18/cargo-beta-aarch64-pc-windows-msvc.tar.xz=5256cba7138f02320a6252f11f66a18d691290d7d9624666944a16544e2f73d8 -dist/2026-08-18/cargo-beta-aarch64-unknown-freebsd.tar.gz=51fc228c980b69160aae66dedc1600fe6404ea1186672ec10e03243f76325904 -dist/2026-08-18/cargo-beta-aarch64-unknown-freebsd.tar.xz=36b689a54d704cafed73ce5d2a01ed0b4418a4b77dc8ac7e39930273ebfe340f -dist/2026-08-18/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=27a8c441081d7d53e6be98f1a81a43bda6fd96d757ce85b6d35917fb81098fb7 -dist/2026-08-18/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=4dffb31c03af5d381eab76ea6992598cf481fa73d760184138298138d776a661 -dist/2026-08-18/cargo-beta-aarch64-unknown-linux-musl.tar.gz=4bfa647b80f633f82a477135365d0c459dc00b4a365fa4bb7ce2ff2b531a8ad4 -dist/2026-08-18/cargo-beta-aarch64-unknown-linux-musl.tar.xz=234b8671193d5772b39ad0d30cb9822776eef1b26ed92d68fe504331fcc68eaa -dist/2026-08-18/cargo-beta-aarch64-unknown-linux-ohos.tar.gz=80b13c14d55f3af8e173473664fec8b0658833d01dc66fde12c54b33725a15e2 -dist/2026-08-18/cargo-beta-aarch64-unknown-linux-ohos.tar.xz=8bf4339eb6f11037098a8d8c9383397929e12566924a1c5563e4f11728301e3c -dist/2026-08-18/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=81a09dd8d86020bc414f53d9f8d3f01b769fca4015c8b492bf0bfdb84f85ce9c -dist/2026-08-18/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=f0b089b59c14c1979b94d5cc068fb89777e2ae194ecadc54b4ccf54244c32aa5 -dist/2026-08-18/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=9b1f316355fc394c270fe2bcc97b9d75345aa8444fd66c7a145cafc31c616090 -dist/2026-08-18/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=32a4a7dc9845afcea8eab677d173151af1c674eaa1c9e541e94c15ecf6d7b141 -dist/2026-08-18/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=57558eaea67aa66563fab5562bac551adb2685a55505851336621e8e5583797f -dist/2026-08-18/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=1eca79bd1d55882fdc93fcd1487891b8dc906330b1f78d6d0b8630d541030474 -dist/2026-08-18/cargo-beta-i686-pc-windows-gnu.tar.gz=e73b6d7b286eac143d43e7b2ba2ed5245ebbefe5b558a2a490e4a6d40113b8cd -dist/2026-08-18/cargo-beta-i686-pc-windows-gnu.tar.xz=92b4f592f837c58492d9be16dc2e650b3dde996f12d1430f57c7ba02ff4b079c -dist/2026-08-18/cargo-beta-i686-pc-windows-msvc.tar.gz=678ca4a0a7db21705980c77bb00711b1263e0bdaa9369ee3c941b0ab2c80fe45 -dist/2026-08-18/cargo-beta-i686-pc-windows-msvc.tar.xz=a30a0ce6c67e0505f648d236d3a4e08571a9ae174fcdb4c266373f65b1e98d2e -dist/2026-08-18/cargo-beta-i686-unknown-linux-gnu.tar.gz=18a1e12717023c45c5d01c5c9100e4a2bead108bb861cdbf17a073bc64b1d5ad -dist/2026-08-18/cargo-beta-i686-unknown-linux-gnu.tar.xz=cc1beb2273d154c6daf6e215f7f6214718d0701f53f71731fb48c38aad4414fa -dist/2026-08-18/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=c0e5e6b2bc3d907a752fad7f982fa3c4feffb0d5e0fbbe00034a45e84e1fbf9c -dist/2026-08-18/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=10bdaf4ac8109c4addb500df4618b254c86c920a73076633a246f437bb77fbaa -dist/2026-08-18/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=397039a85cc300997f5e9c540bfc7b5ac5f56202d50c7244da628bda6690535b -dist/2026-08-18/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=fabd6e56b86d69cc36fa61b101a0da9ac210c6618edab55dba684254b3c22741 -dist/2026-08-18/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=cbdf7d2958df1f9a37314059512a53c4749b441addf30bb84a83c689d9d11dde -dist/2026-08-18/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=573b9be1e0066ac4359bc8c696315988fd475386a92a4dfe27db0a5d63abf036 -dist/2026-08-18/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=201ccfd4e24b2891809f0a2d3cdd0e57757e46c436fa50ad1912af237b4fc06d -dist/2026-08-18/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=ebed264b9cbe05465dbcc3d1c618833f6e401db02df282f856cafa0a8737861d -dist/2026-08-18/cargo-beta-powerpc64-unknown-linux-musl.tar.gz=9c457b61f3d8cd547d68f92e129be23fa43f5e542d42a156b19f598d1ac45184 -dist/2026-08-18/cargo-beta-powerpc64-unknown-linux-musl.tar.xz=0abf134c439af2f9e915fb6849c0d0223754d2fa572d69d25d230d344a4b267b -dist/2026-08-18/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=61b406d8bfe5a28cd7076fdb164e005a999bd8a97825deabf31a16ab997f474a -dist/2026-08-18/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=49661faa1e97dd357787821beb5bb260259b658959247ea55ffdc08218567be6 -dist/2026-08-18/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=b16a47da9a5ba8271cf381b95365c5189a5abf91ef8a37f841774375aee59a0a -dist/2026-08-18/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=4ab9b6309902f12c0003b89fb7fd2acae48bf6a583f322c1ab10f794866c272d -dist/2026-08-18/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=778bd607c173c2a417be15d050ea07b78f0a8affa4e54b61f8a8cb3b89f954d7 -dist/2026-08-18/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=bc4aa00b04f62ae8cf93d1643a39fe74927b42c795d738927182470febe14436 -dist/2026-08-18/cargo-beta-riscv64gc-unknown-linux-musl.tar.gz=40ee8c220f453a5f9a6fe37453e25a16052fb148a1c8ebbff8eff32914b8b520 -dist/2026-08-18/cargo-beta-riscv64gc-unknown-linux-musl.tar.xz=c90545ca7bb32764a618c63c4ec5e0f4e96494b9d1fba56a4577e12d826f0653 -dist/2026-08-18/cargo-beta-s390x-unknown-linux-gnu.tar.gz=db62de0842a76f63bc87988e57255ffebc86d5df46626e9ad5c0f424abd721f3 -dist/2026-08-18/cargo-beta-s390x-unknown-linux-gnu.tar.xz=26f786c87899d55212c97260e3ae99b0374fed80b418e3b15f0c21b45012ac0c -dist/2026-08-18/cargo-beta-sparcv9-sun-solaris.tar.gz=5436d9476157d5e30e0be155a545a61597563c9c25ccbad80f8a6e0e81872772 -dist/2026-08-18/cargo-beta-sparcv9-sun-solaris.tar.xz=294b9110e182deb5468c88dd68f1647f4d25d37d6373c222940d01fabcf2f770 -dist/2026-08-18/cargo-beta-x86_64-apple-darwin.tar.gz=ad73fe27d749dc82fd51a39a56cb76ba9731c23e968656500193cae116727ff1 -dist/2026-08-18/cargo-beta-x86_64-apple-darwin.tar.xz=f6107108f9f6a684c59a61cfceae0a9309e8c5c4314a6bc105c2888bdc699bd8 -dist/2026-08-18/cargo-beta-x86_64-pc-solaris.tar.gz=fb88d7175f5fa8750f56cee9c0fc4493a66253256a9da1cd9ae947c4f7a8289f -dist/2026-08-18/cargo-beta-x86_64-pc-solaris.tar.xz=48bba42d85d677b28c2ab3748052b46cee4caec43f05434f7cba0adca4a43d5b -dist/2026-08-18/cargo-beta-x86_64-pc-windows-gnu.tar.gz=39a70736a0f5ceb9727b941c4299577646ef7264e398aabbb77763ec4f10c3de -dist/2026-08-18/cargo-beta-x86_64-pc-windows-gnu.tar.xz=9f4ebc59f40d448d703f7b1b6a07a84c60cc4b2e526465be9fee6fe49ac5dd09 -dist/2026-08-18/cargo-beta-x86_64-pc-windows-gnullvm.tar.gz=e0540a0b1a37a590b80d32725c654d8f1fa9c13da5aba1101e069b00befe28af -dist/2026-08-18/cargo-beta-x86_64-pc-windows-gnullvm.tar.xz=a01efa5cbeaa2adb44ddf93c010da7e9e26802852bc6640618261e410c747350 -dist/2026-08-18/cargo-beta-x86_64-pc-windows-msvc.tar.gz=c1d9d27a66930cec6e7db1f2b3114843c4cc60991b112ae4c05782660d53fde4 -dist/2026-08-18/cargo-beta-x86_64-pc-windows-msvc.tar.xz=92f46aa54cf0715bc5449cc5ddebebfc57a372d5b1c2ce4169af94fecc1ba1c5 -dist/2026-08-18/cargo-beta-x86_64-unknown-freebsd.tar.gz=fef1a5fb244689c8464496dd98580b7fc0964b90dbfbbb0c52526b58f14228e8 -dist/2026-08-18/cargo-beta-x86_64-unknown-freebsd.tar.xz=2749ad0cae6a035309a5ad0c277ae6b127aa22a095d7be8e5f92191e9f6ad4e7 -dist/2026-08-18/cargo-beta-x86_64-unknown-illumos.tar.gz=321af127d565e1baab5430bcc0a15538f7a76c58d918b59003c7220d4ef844df -dist/2026-08-18/cargo-beta-x86_64-unknown-illumos.tar.xz=41e33ecc4f3e317e94ef9f70caad18c449d4089777c31a40b560ad73490b11bc -dist/2026-08-18/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=2ebc1e00cb2369c3a0dc6d21b8d8293aef2e42964ddd51aa56dc81f221a64cff -dist/2026-08-18/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=79eb6a12e9b8fea72cd8e02dc39e633f51c485812e32a0048a5dad8b8644b4b0 -dist/2026-08-18/cargo-beta-x86_64-unknown-linux-musl.tar.gz=5d62ece374c942eab596efdb13205d7d23e16d32eed33e260ec01cf718c3a71c -dist/2026-08-18/cargo-beta-x86_64-unknown-linux-musl.tar.xz=33ca929e222d2f8b32988913bcb2bbf882ab9134b1590ad6e9b6ed6a4e81015d -dist/2026-08-18/cargo-beta-x86_64-unknown-netbsd.tar.gz=05f04d6023f28b372845c03da306941759fa1fdabfabe86b628e6fa7800e17d6 -dist/2026-08-18/cargo-beta-x86_64-unknown-netbsd.tar.xz=8b98637a31736cb9a8789f4c6ca0fc8e4fff0297f8efebee632c0cd521e2c029 -dist/2026-08-18/clippy-beta-aarch64-apple-darwin.tar.gz=5fe4bcaa4a8eb063132cbf24922d1502eb1974d255d2ec8a2743f6c226cd95a8 -dist/2026-08-18/clippy-beta-aarch64-apple-darwin.tar.xz=4df93e14e99505ec00ba4003c8b22330dbb801d02eac0f37f052c965d703cc28 -dist/2026-08-18/clippy-beta-aarch64-pc-windows-gnullvm.tar.gz=4abaa22dfbec4b506243b4bffced79568c50510d364ecbf2fe1e574cedb9faa7 -dist/2026-08-18/clippy-beta-aarch64-pc-windows-gnullvm.tar.xz=cea81f55e98d070e7644192319754c488a8e7758ea2b6dedf83a62ff4d6f0841 -dist/2026-08-18/clippy-beta-aarch64-pc-windows-msvc.tar.gz=e9b23658c3a1fe8ca459e0c40719412bf83d64896e19a5fd31d8de4bc826b778 -dist/2026-08-18/clippy-beta-aarch64-pc-windows-msvc.tar.xz=8343af10d4ebb040b7d0cf95574d10df986aa152fa1923ca740a9f41697422a6 -dist/2026-08-18/clippy-beta-aarch64-unknown-freebsd.tar.gz=be1a6654df4ec2038ccd08405eb2ec8bd30fa87813930b69557e2c9cf862d471 -dist/2026-08-18/clippy-beta-aarch64-unknown-freebsd.tar.xz=c13ca8153d949384cc99738c81d3e9022aa41fcf40f7c117143aeec48e21c9a2 -dist/2026-08-18/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=bfe2e44d96c499dd4eb93c4a4eef715321749dda1050bf8dcda52fd6515f463e -dist/2026-08-18/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=29b109b977dba9cbcffb74dcf6371f91ffdff5fc66f1f3f4abef9703d4b59e4c -dist/2026-08-18/clippy-beta-aarch64-unknown-linux-musl.tar.gz=710964e2d7b0432eb48d887805004fc521e380c898e308ba072a49bdf3363e3b -dist/2026-08-18/clippy-beta-aarch64-unknown-linux-musl.tar.xz=96f52e5b75225936d8beb48e895e43a8e8f7332312ac9a919916d1cb8552c74c -dist/2026-08-18/clippy-beta-aarch64-unknown-linux-ohos.tar.gz=d0a7c144e68c433175e489566cc9cedd5ae83fee367f4513edd06dfb85af37e4 -dist/2026-08-18/clippy-beta-aarch64-unknown-linux-ohos.tar.xz=55b5e8116ad9e29ae977fcf495d932e2d17d67ea048b734a733403b1bf32f136 -dist/2026-08-18/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=6b74750557ab040db72e8fd2daca67e7e75f8845d360afaaba8ea8c90b6d8f2d -dist/2026-08-18/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=e656572744817e497f2199270bd7ad7597056cfd1dbc4ab959c90290e5fea806 -dist/2026-08-18/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=000dc860666d8f1f27d1525dbf32bc0cc824205b91781e6c0854b550086a5789 -dist/2026-08-18/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=16e89c2a4a7a38a7eb1654c8a4e8f897c2c89f97e93afd5f2b68b8bc8ed366ab -dist/2026-08-18/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=2cfea19e1e8307759be2f7bf0bd4c575c46055dceabbce086f7c8793f73646d0 -dist/2026-08-18/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=e3c03d5d36d973da1ec3db60de8c8e0280230d217103ec8d34a8ae393d9912c6 -dist/2026-08-18/clippy-beta-i686-pc-windows-gnu.tar.gz=8fc7f489cfb38d98e0da8d1aa568887e95c85f1635db967adb5342f47e75bf06 -dist/2026-08-18/clippy-beta-i686-pc-windows-gnu.tar.xz=2d774e50c1a2a8ffa63ee819f38c4073e867ee86b3b3936afc9ad78fd6d6f7fc -dist/2026-08-18/clippy-beta-i686-pc-windows-msvc.tar.gz=c13eed86659d04d0c329e53f2daa9261960181f8f22ecaa05e83c801cd913cdf -dist/2026-08-18/clippy-beta-i686-pc-windows-msvc.tar.xz=71d3c6dc8c091245bab4d19383b75241623dfda4102c313ba6d0887ba9253f7f -dist/2026-08-18/clippy-beta-i686-unknown-linux-gnu.tar.gz=fe3963d203d7a42f27493c35166ac06b56c3dd9c34d28e99259059899dee7c2a -dist/2026-08-18/clippy-beta-i686-unknown-linux-gnu.tar.xz=a4407a9362f9d88f5475a8a1f948f1bae645553be19dcb2493072dab6ecb0004 -dist/2026-08-18/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=a803b0db04ffb55e4de3445d92d89217161daf345304f7a9e8230a2db37e798f -dist/2026-08-18/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=f3f03c257648f844b2f25ab2bf30b25f0bd964cd85e802cf92ccd86dee47ab92 -dist/2026-08-18/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=4d1f89b20d2b78ac50a865aacc3c3558a88889ad4e5b4c6dc95dc6dfba45c2f5 -dist/2026-08-18/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=cd89e3232cd92b71510627f2fcecb4ddb047995fb3c97effee1261b0779d7e31 -dist/2026-08-18/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=02070d386593a771d8a386683e4c905cb3eb0bdac88971e5edcbc9d8fe8e2ce6 -dist/2026-08-18/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=f297680488988d2e5a17784692ffecafa6f716fc7cd2f483b7d4bfc000e9ffbc -dist/2026-08-18/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=87d7d0fb031e473e969b2ed227102a4a5eb6267628d0c77505201613ea96f430 -dist/2026-08-18/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=9971af904468f255b5e26189b86586b82a5f548bb7b6df94a77bca1b222e8250 -dist/2026-08-18/clippy-beta-powerpc64-unknown-linux-musl.tar.gz=085f0d5146a60c1af737b83aae5c6b0d6edbb1187adc08b994592bace9690e32 -dist/2026-08-18/clippy-beta-powerpc64-unknown-linux-musl.tar.xz=d218a1d0203825acd3061885a1dcdc1067e853f37621533ef027de9ddabbc24f -dist/2026-08-18/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=b8fc87bd4da8652cc018f2fef37805961c588753de747ebdd4e607173834892e -dist/2026-08-18/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=2719977ab366d4cbf20bcf0dea4efbf6f7d479f1de1ee53550b7e0db9fef2ce1 -dist/2026-08-18/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=859cbd1aeda298301110f20b19d94eccf1b93019e9271a2298e6b6c88ea70e93 -dist/2026-08-18/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=d4e99335ad9e260d48a8916fd03b57576c0de9ac7bd53b3cb309f4cb9a548e79 -dist/2026-08-18/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=9f0d343ef1d303edcd695e8ce15eb98eda15c17427cf6be4d40f5d7a96200bb6 -dist/2026-08-18/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=5a58eb5ae9a0483971b1ae1ded6b6573ac42f105e0d535c56dcadce4c25c1164 -dist/2026-08-18/clippy-beta-riscv64gc-unknown-linux-musl.tar.gz=6a445ac80f3af92ccd8a3b1a1ec01dd96c87acb7c44745361e91006158b3483f -dist/2026-08-18/clippy-beta-riscv64gc-unknown-linux-musl.tar.xz=e2032fc84c9a380ea190640de7a1171974468be465bb0c8d7f89374d8a4b5556 -dist/2026-08-18/clippy-beta-s390x-unknown-linux-gnu.tar.gz=d0aaab88f485fa6736459cce8927e4daf9e8794e7c2e520cf64364258567a032 -dist/2026-08-18/clippy-beta-s390x-unknown-linux-gnu.tar.xz=c86f64909bd17001dcbc4daf0035ed582d876eaff810e75a07625b225f147ec8 -dist/2026-08-18/clippy-beta-sparcv9-sun-solaris.tar.gz=ba2e26b4add71aa42534d78ea1891777a91cf66f6bb9fe766cbccd60901eb897 -dist/2026-08-18/clippy-beta-sparcv9-sun-solaris.tar.xz=d098d8fcc5a795ed9b8e0196fcc94e427bd66cc3e9263c563faa26264226aa1a -dist/2026-08-18/clippy-beta-x86_64-apple-darwin.tar.gz=040b2fa856b4b978b7db6672bef0d7736df30a7ba38471f759f0f53d85c28c85 -dist/2026-08-18/clippy-beta-x86_64-apple-darwin.tar.xz=85e428d68a2b1f7ef5fbf94ccb8009de7ccf2b49493e507f5e730da9e425d3ae -dist/2026-08-18/clippy-beta-x86_64-pc-solaris.tar.gz=219ca608ad967d9fcf2f7a3764e52e5e8d6b60ff99eaa86c4fb571b96bd37acd -dist/2026-08-18/clippy-beta-x86_64-pc-solaris.tar.xz=e5dc215e559977a4772074094847a9b8da4283b5ad51fb73bb10c7a506e0115d -dist/2026-08-18/clippy-beta-x86_64-pc-windows-gnu.tar.gz=380c6ba6f747b36e4e011cd0d47c9091838b12aa510612c3fa6aefa782ff32d6 -dist/2026-08-18/clippy-beta-x86_64-pc-windows-gnu.tar.xz=8b2d086e6c00a2c0b0a856f7575c120faf75f5f645157a54b5ae77cf4410bb3c -dist/2026-08-18/clippy-beta-x86_64-pc-windows-gnullvm.tar.gz=fbcae84f6a5fef2f30a790d1a975cd8475035da251298b45ac4963cdaa9caebb -dist/2026-08-18/clippy-beta-x86_64-pc-windows-gnullvm.tar.xz=e4dbab41c356ef08493074bfbddd20ca06666a1e94d111998783b12e7c69c0a5 -dist/2026-08-18/clippy-beta-x86_64-pc-windows-msvc.tar.gz=e7bcc1e2bfe7b11808e110185ca23494f68213e2f0ee5588ca6adb8b43ab9f9e -dist/2026-08-18/clippy-beta-x86_64-pc-windows-msvc.tar.xz=3327ee1ac890f035160ca6e17c49ad2e78b4dbefab8133ea55dca70c2f498f63 -dist/2026-08-18/clippy-beta-x86_64-unknown-freebsd.tar.gz=bbbb6f42ac5e928ea72a4dac33406218de329a6fb36a54b5ff383a18888a0a1e -dist/2026-08-18/clippy-beta-x86_64-unknown-freebsd.tar.xz=b1e02c55a0a5969c786a0fb29576a56b6439ab00a24329dbd518e4fb8c71bd6e -dist/2026-08-18/clippy-beta-x86_64-unknown-illumos.tar.gz=e1a9eb87354cac8d97c8fa4a0972b67ae55599b1554ee7eb35a3e0b0b78a218f -dist/2026-08-18/clippy-beta-x86_64-unknown-illumos.tar.xz=fd47d0feeeadf79868feaa90f7b41497f6c87f54751d2fa57b1d8ff326fcd4ce -dist/2026-08-18/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=be8b1a104953fa0a37b57966d1972f1e268d38e5f7bf83c34f9fa00798f371bc -dist/2026-08-18/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=d2a0656ce333814b44ef5c6ef668a7df50cc87380936c30633ed68490a89ab88 -dist/2026-08-18/clippy-beta-x86_64-unknown-linux-musl.tar.gz=ee3481b87d2c0a2c5affcabbd5a538463574480870c0afe407589f8e1df48499 -dist/2026-08-18/clippy-beta-x86_64-unknown-linux-musl.tar.xz=9ce41c196580e20f8ee8bc369fc0bbe917145ae4ea39dd3a1ec67ffa22fa868b -dist/2026-08-18/clippy-beta-x86_64-unknown-netbsd.tar.gz=91ad76c2f79f61c422772ede44ce8f599a646a3c1da05fbfc5324beb97b2aeb8 -dist/2026-08-18/clippy-beta-x86_64-unknown-netbsd.tar.xz=fc14aa158d837ce9bdd0959a52f4d7538b362a1ab8bb0370fff08b0ff283ef7d -dist/2026-08-18/rust-beta-aarch64-pc-windows-gnullvm.msi=39ae595efd47c05544e5f7f36a4267dd339ece63f1d0f845d8e92f7ba0d0df01 -dist/2026-08-18/rust-beta-aarch64-pc-windows-msvc.msi=1aba33d2f85ac14e5e042b2eb55612ffa9945d11b41fd8a1e1756add7d15da21 -dist/2026-08-18/rust-beta-i686-pc-windows-gnu.msi=fa748daeb0befe69dd3434ec14447d684ca86e6c359c06781485312c93d7569b -dist/2026-08-18/rust-beta-i686-pc-windows-msvc.msi=c8eeed7b49523ad840bf29786037dc00bee0d742026e3d0f10286d437b9a1c3d -dist/2026-08-18/rust-beta-x86_64-pc-windows-gnu.msi=f61f5cb62ad64741f475dd9907fca3228707603e8627e8eed1e5097e09dd7b37 -dist/2026-08-18/rust-beta-x86_64-pc-windows-gnullvm.msi=2d49b873458e82c9ae91ecc0d2bbf42cdaaeb578945915777b4099d201f5c3bc -dist/2026-08-18/rust-beta-x86_64-pc-windows-msvc.msi=dd41ede2e8794fc2b85d195761fc775fc77e2e9cafe265026a5c7b9eb4f50df6 -dist/2026-08-18/rust-beta-aarch64-apple-darwin.pkg=95fe89d9e2c66ac7dc4454b1f00a55112057f5721fe7ce5be79e5e33d6f2af9f -dist/2026-08-18/rust-beta-x86_64-apple-darwin.pkg=e70190e1aef5edc5395a82f22f976055a8bacdbaea4c8e908dc0b06b8c5769ba -dist/2026-08-18/rustc-beta-src.tar.gz=f9179e80c6ffe453d24a9679500c41cb94538e2259cd79dbd43e6392376b0450 -dist/2026-08-18/rustc-beta-src.tar.xz=818fcd0a361460db2bf5ad529669c04f23fd75790ccf2900fe3e54d4db68da1c -dist/2026-08-18/rustfmt-nightly-aarch64-apple-darwin.tar.gz=8359cc560de936d29f7b13594ec54a1286e815d5154e55781d250c95efefdca2 -dist/2026-08-18/rustfmt-nightly-aarch64-apple-darwin.tar.xz=ec133fedfc39881527478364eae364c09eb866bea7b26cf8a607f712b0c4b8b1 -dist/2026-08-18/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.gz=eb6f8b751210b668b9bd50d4bd2a85138666fd9ddb3034084cd7e605dfd4eb10 -dist/2026-08-18/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.xz=d2fb7a64f3eef4baba3356baffb74aaa496efc39a6b30ed79ddefcc441038292 -dist/2026-08-18/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=25459d38e45d450da824ac60adcf22d5218635d41bdc65675955ca201b3c2c07 -dist/2026-08-18/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=72fedf763c73f88b4b314866e94866435f9037187cb879aef6907eb138e91fd3 -dist/2026-08-18/rustfmt-nightly-aarch64-unknown-freebsd.tar.gz=0683d2ac65a9f9a81012c82f74adb73b9c720d2ce8edd054018aaad7e64697e0 -dist/2026-08-18/rustfmt-nightly-aarch64-unknown-freebsd.tar.xz=5ed2b494f90358fd2a6294a00b802dcc27b1b7fb51bd62ebf602e6bb047cb825 -dist/2026-08-18/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=d9b00b9350cbf4b07223bbb58f0c77a79ef8a4761adcb33915e2db2779cb605d -dist/2026-08-18/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=0c596e26cc710ab63779b40b3fe476cf763ccd15d6fade17bcc22e46b1a24154 -dist/2026-08-18/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=a4445c0bcbb7aae83fdd5bc7fe7318c2146c1826caf48fce44424386835cd3f8 -dist/2026-08-18/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=aa302f6c50e0e109ae31785398952c0b9cdf24be41c80abd63ab8e7c95c52b20 -dist/2026-08-18/rustfmt-nightly-aarch64-unknown-linux-ohos.tar.gz=8034cd2b2e540e990f4a8de35b8cdfcb1c72c6228bdc66a470d1c4c8ee5f57e1 -dist/2026-08-18/rustfmt-nightly-aarch64-unknown-linux-ohos.tar.xz=58fb965551e248148bb56437e6553edc9204d68c0beeea587bb6645108869b24 -dist/2026-08-18/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=f1891d9684248d8193a9d8e67107885a0b9ada5fa1e9e38479923e39ea9928f7 -dist/2026-08-18/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=d54e511333b0d1e8e7c19f93ebcf0c56698faed1955318ffea6d2b4d1dd4d6ea -dist/2026-08-18/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=7b35463a8357816e7022bea356e92d847011c17a3295a0e2f4850a811f6dd1db -dist/2026-08-18/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=ca255881fe209ea1955386a633572239636d010156368e38ff2f6ad6efbf7ea2 -dist/2026-08-18/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=c2c1146a102ac34f76543ac08239411c2c1c043e091e3637deffeef4181e25ba -dist/2026-08-18/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=acb1a26de680d4e435877e5fedae2a0063e019ce414072c10615a9b6cef454e4 -dist/2026-08-18/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=761ae1d0ed7c4fee126d76d59e26edeb9599e01ec338f36b9e0f8b04de262391 -dist/2026-08-18/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=6ef0e2d34e32dd354116b12002efd911c7f734b8c7708108d541a79572f3aa7a -dist/2026-08-18/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=ce84297a9c0e9454d17cd3144eb68463e9b4281c9c08207763277bfd33b9cbca -dist/2026-08-18/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=8d3ecf716222af8d140b3580771fdcfe84194df3c4cb5809e9c0f1d010f3d91f -dist/2026-08-18/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=e9e9b19491a1edcfd6e96554e5867f4d1c00a5ac3d458368ed9c7ca82eb1cd13 -dist/2026-08-18/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=6d0ee5a0d6354607d40d0718e92c850aa47e2914d5c99c91c908b2bab5120b91 -dist/2026-08-18/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=d7c573130ca761dca1a5fde6c0c5811294ca6597ed3ba0e34c16209b7e63f41a -dist/2026-08-18/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=36f454c6a7c98876af766199ec1141c102dceb72de75dd2a29dec7597d4536ad -dist/2026-08-18/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=c440bedec3ba4f4fb86c5f2743eb681de7a7f9610b7a42cd912a9980d472149c -dist/2026-08-18/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=4a3ca8b699b176f1480a85c4c36ca869d4a069330c4d79248ae1428d4b522088 -dist/2026-08-18/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=a52ca1bbb2ff0940b131c99dd0caa4bf0f0a6c4de37730cee7dba449c41b219f -dist/2026-08-18/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=c67b4b8c8a7d6bfe425c04b5a528aa67f5cabfcabef7a5c0761db4335ac7ab79 -dist/2026-08-18/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=54777ec5f3ec8a92e6431bc7356657348d359e683ee2105d1155ea29f5ce841d -dist/2026-08-18/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=0400aa5c5c4948afc27d6ab7da6dbb9b609b446dcc88fa674ea92831bc8a90a6 -dist/2026-08-18/rustfmt-nightly-powerpc64-unknown-linux-musl.tar.gz=141fab1a35a405881d5f000b8f1a4f5db1aad8d7b7b980474868078410dec883 -dist/2026-08-18/rustfmt-nightly-powerpc64-unknown-linux-musl.tar.xz=430ce7d3e0ff163f62c560b6501307740407fe4f383f323777a54cb5e4bd5003 -dist/2026-08-18/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=d0205048d10bcbf43feb63a118e5773357da8b646f9754e80a5893b5532b9a87 -dist/2026-08-18/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=f15f429488bca14ec7e31a531be7b4f2366d50a5153ac3f8265eff5d4948d270 -dist/2026-08-18/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=8aedd4c25762ac9fbdadd8448f0af721fbd315bec419fbd5e8e98dad6e6b4b1a -dist/2026-08-18/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=ca853671fe6367d119aafd4c15d6371575b545c505b969ea89db3df87a51cc11 -dist/2026-08-18/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=2792f02d0729f1a7ec58331c310931ff8dc785ba59c617ca383797b87520bcea -dist/2026-08-18/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=90d4d96e16c158ca54d1028254353447580039b370fcd7a21ddabd391170c3bd -dist/2026-08-18/rustfmt-nightly-riscv64gc-unknown-linux-musl.tar.gz=85d51033a76ffd8d654c348d0288cec35806ff078d2d8c033794d3dae3d6d5c5 -dist/2026-08-18/rustfmt-nightly-riscv64gc-unknown-linux-musl.tar.xz=bdf31ec8ba7e306c424301a0a95b74305b2280bfde67e2d44dfd589092070e53 -dist/2026-08-18/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=2c73ea8c782f6f067d809b38ba95e25a7cb6a4d4d5a6746f6ce586a6707084bb -dist/2026-08-18/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=5ca41c228a27b0245f22a1623ad5ffeff166fb97bfdec1769fdd5bfff35c1763 -dist/2026-08-18/rustfmt-nightly-sparcv9-sun-solaris.tar.gz=febe662245a6c32aa49e715eb3908e910c1d9e5551141dcc1e29bbbe17c0facb -dist/2026-08-18/rustfmt-nightly-sparcv9-sun-solaris.tar.xz=4c5a4081e335f712834fa7edb512e3def45d06945bf563e6bbc02c4c82661ee7 -dist/2026-08-18/rustfmt-nightly-x86_64-apple-darwin.tar.gz=5af08000206f3eb5baf9ed5768ae573962692d4ca3af5ea43264d5cac10cc269 -dist/2026-08-18/rustfmt-nightly-x86_64-apple-darwin.tar.xz=348cf7b79ac548b9c830c1c91b6cb38f0bfefbfb5038c4a898bdb46e38f812a4 -dist/2026-08-18/rustfmt-nightly-x86_64-pc-solaris.tar.gz=0410ab96d92c1f5fdedd40b7c38b5b531c94e241de2e131002b73f627850c229 -dist/2026-08-18/rustfmt-nightly-x86_64-pc-solaris.tar.xz=c627bcd965c8be7496a6bb17509228d737b11b5c521746a01d4b6a24516eee98 -dist/2026-08-18/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=c2099b8a326297dd379ecd31cf2020610a9f5d8d92950335ecd7681225faff10 -dist/2026-08-18/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=086a7054834620d56a1242c126c24269b8440a25c07c0c8ff49155477ad31afe -dist/2026-08-18/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.gz=9386779ce495ea8fad7e5b29de837e77b972a3dd519af6db622af2f9f4488676 -dist/2026-08-18/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.xz=d7893bc04f62551ea7e24aaeb6d79b31b600f2bc4a01412929764b0021dd06d1 -dist/2026-08-18/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=42c06fde187281cee1fde78b7a96555e776d6e5082e08817591348940598a95d -dist/2026-08-18/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=1ef75c6b455cf046bfc72efc1c8db406c364a3f445ed460e5ca3092af3dab9f1 -dist/2026-08-18/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=4a2d0e7910ddac9c4afe2ac88194fce6ce809257f31a69589af1f4d0e0636a54 -dist/2026-08-18/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=0773f4684b9a56696ea378dc65c011e6cb296c9e939438e3d21f002e301045da -dist/2026-08-18/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=6c21d29bb79ea41acd2c56f2a4f5e8125bb15bcff2bb8acb3f7c87d1ee966627 -dist/2026-08-18/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=840190d0139a742cd8422813330241d74b96783dbc38c2833b128d7599a65347 -dist/2026-08-18/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=c2b427d6383bfed96f8a22a861ad58c19b79dfcc562136ab03ab46d7c75eeef3 -dist/2026-08-18/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=79a022906526fd663dfa429ee4c6ac5719d4d14c0fe11c2bed92fe2978220112 -dist/2026-08-18/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=0786d79adaafca96e857cf624daa2cae6a8a91155de1d97518bd2609073e056c -dist/2026-08-18/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=506f0055aa468f9261453fa7afa1b16000f2a0adb82f4ae306b1c9ec7e725ff7 -dist/2026-08-18/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=fb061689c906438646f70b76fa8db0dc4269cc85783806e74098b5f856b7bb13 -dist/2026-08-18/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=2af4814be862f5dfa71c9967ada639511fae01e56e3a5bd008f4cd2a2238a173 -dist/2026-08-18/rustc-nightly-aarch64-apple-darwin.tar.gz=55df1ca82348fd415ac6f470e91ccfbad719edc58ffffb1ab7474ca3f893b18f -dist/2026-08-18/rustc-nightly-aarch64-apple-darwin.tar.xz=919397ba2d0fafdb54cc3a15d7bd44c2477eee35b078d091e83d700a4aee915b -dist/2026-08-18/rustc-nightly-aarch64-pc-windows-gnullvm.tar.gz=87a9314b0b8c22e5f569b5786286944d9b8e343e0c147861be27933508e71950 -dist/2026-08-18/rustc-nightly-aarch64-pc-windows-gnullvm.tar.xz=23393b9fe0484bac67cad7a752202a4589d15b23416cdad4bc1ac2be59483d24 -dist/2026-08-18/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=ca448c196560cbea8b71eb507bb6b442ce1d92bf38a5b37233167faed8a49ce5 -dist/2026-08-18/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=b50b89b68bd6d0fe6b33d5b36329f4280084c938d7c46035a7647e113b6e6902 -dist/2026-08-18/rustc-nightly-aarch64-unknown-freebsd.tar.gz=e0ba0b49b170f0ed801e45f9decb566207897d99b625c11557c19c1cd1b2c305 -dist/2026-08-18/rustc-nightly-aarch64-unknown-freebsd.tar.xz=68f7ced91e30a4997424c9a8945bb224691664a286412dba047e8778df27f775 -dist/2026-08-18/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=b2d731e4546187b7f4ea76492ad1bb73ec322603843d49a39b197e9cb87aaa71 -dist/2026-08-18/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=0ff40c661fe771e73bb8620cdedbce33dbc5d5862e40373bc2d394a557c21ac1 -dist/2026-08-18/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=162ef1fc6f822d676e945d11a7162b5096c133a42deb038aaadad15164eeb7b6 -dist/2026-08-18/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=c6f918dc6cca5ad702aba57750f08c3c76f80ae53a799f9983bf3514e835d10d -dist/2026-08-18/rustc-nightly-aarch64-unknown-linux-ohos.tar.gz=fabe9610683c3ed4a12090a6bda9e918dd14f69d3475e4d15b769fa2eb91fed9 -dist/2026-08-18/rustc-nightly-aarch64-unknown-linux-ohos.tar.xz=926807f8dfed16eb6deb142f94b6ce46fb26d21c7346b1ff689d3f6e831d7aa8 -dist/2026-08-18/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=97f6ac3d02cefcd21f097ff4e663f8df8d87a31d07fa9f10851753bcb44ac75e -dist/2026-08-18/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=ef28e740d733e69d2b4e4058272c7b1fb352b2d080e80a2e11a7ba257736366d -dist/2026-08-18/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=97c543c70c28d8c069798889f756793ca672583508dac205187cb2721eb041dc -dist/2026-08-18/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=fa807d0f373683da3c98d49e5167dce2a962578dc19b205aeea8fcdad9c5ad82 -dist/2026-08-18/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=9492faf8bea9d7fa8ccfa757f979a76ef08ffb3189f673b2534abdeefaa54eaf -dist/2026-08-18/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=25238ee74921a5c4350f20638cc66a7ce51dbd48784312d556c84c2955507604 -dist/2026-08-18/rustc-nightly-i686-pc-windows-gnu.tar.gz=104518b6dddf82b291c362f9c5f1f2b29745ca846d1d1d00ebbe7914082c42c2 -dist/2026-08-18/rustc-nightly-i686-pc-windows-gnu.tar.xz=077a79233305d157fafc9918aff9f25e8fc19faaef8ad446a25f2c57b5ec86fb -dist/2026-08-18/rustc-nightly-i686-pc-windows-msvc.tar.gz=362519da71603e964cadc8b78cc7aa62e53a6a8956fe3db1efca089024b2900a -dist/2026-08-18/rustc-nightly-i686-pc-windows-msvc.tar.xz=4c65e07738dce9c01cf46395ad246b9e3de49f9b37bf6f8cdee44bc0b7d6a8cb -dist/2026-08-18/rustc-nightly-i686-unknown-linux-gnu.tar.gz=487345081f4eed3c8cf00eb73c850ff62214554b807f2e6984951d72dd324a64 -dist/2026-08-18/rustc-nightly-i686-unknown-linux-gnu.tar.xz=6fe9b5bbe02bd679cb1953cf44a153c9a534b903acf419983276a38e49d6940c -dist/2026-08-18/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=f907053ef2e214fa5b1ec1b531df6c4c809eab35be5ed1d158f9296e9b0e016c -dist/2026-08-18/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=42e38accce541fdd1c3f886a2fca2d1a9f63ac2ae9431cc7dcd127a44558a885 -dist/2026-08-18/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=68790cb993c600acd2517f491164e883e0a18efaa8027f2741560dc63df0a278 -dist/2026-08-18/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=de6c9c4533698a338bb46219eefb26d0c4cb01bf4f1c2c2ffe4b3b96b6166af7 -dist/2026-08-18/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=db3a467e6123469d030d64a5919f1172d614571cfd745bb7b9f23e27395b06d6 -dist/2026-08-18/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=59409e90d7a34387f617428b3f2c58bc6cd1c8bbf8a7589db97119293cb652b4 -dist/2026-08-18/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=5f41fe6610ff78a66315174f2ff6a687f60501c5a16e96e09fdbc2d46b9eec49 -dist/2026-08-18/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=4e1fd93779c24b894713de2a78a33ca50c82dbe7261838f03e51329a259680f7 -dist/2026-08-18/rustc-nightly-powerpc64-unknown-linux-musl.tar.gz=5e506f24af0ee0525e2853a7ed5b334254967cfb59d8d0d069b624104746d0de -dist/2026-08-18/rustc-nightly-powerpc64-unknown-linux-musl.tar.xz=4a45b2823afc85baaccdbb6b01fb65a8e3236735631de4f113de031440422b84 -dist/2026-08-18/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=76d60c5f368ccccf0b01d5a63172edec52cb5a9240cafcc75151061cd0e90387 -dist/2026-08-18/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=bbc30451f394f80bdb79123a1883c0bef4cb00c40dd15fad98a35622c0de0b6e -dist/2026-08-18/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=ee14def5f91bc833ab0c72658b4d196821ba5a1481a5a182477577d3e35bd6ed -dist/2026-08-18/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=0a5d855c1b557a7ac9387f97b9005e74c14c14bc7a95ca3c87861eaee16372fa -dist/2026-08-18/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=034c79fb5e4bee7ad29067d63bb456dbb64a67a494e50086f07d681212dc4ecf -dist/2026-08-18/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=f2fb76c3cae4542dc891f4cf06eebd786c5f3da028ed0ea484a381c372de2ebe -dist/2026-08-18/rustc-nightly-riscv64gc-unknown-linux-musl.tar.gz=f3d926753babb8b9bc8904ad9f5df639635be320f667bbcf1618c49c7e76b75d -dist/2026-08-18/rustc-nightly-riscv64gc-unknown-linux-musl.tar.xz=eb1228896c98ad4ade6b967b0643079033005218417290c72ed788f6756c4064 -dist/2026-08-18/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=c57a90a45053fbb53d645cd80f0577bef7068fd12f3875bc6462686334a5c1fe -dist/2026-08-18/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=9608cdf34d7d37bc075a030de31bb4b261cf0205589ccdeb6b2a091cf17772fa -dist/2026-08-18/rustc-nightly-sparcv9-sun-solaris.tar.gz=30a75702b6a61c5e61bce2e32b0a9561ae3e00fecd87bc8d88e1277b2e5c9fc8 -dist/2026-08-18/rustc-nightly-sparcv9-sun-solaris.tar.xz=fcf621dae0a9162f3727bffc20ef4af805cfd9866e1952a4873e488a54d9fb06 -dist/2026-08-18/rustc-nightly-x86_64-apple-darwin.tar.gz=89f18bbcfc47190c2569ed90af1eb7bcccb040190d2437d3c50e5f2c55afab60 -dist/2026-08-18/rustc-nightly-x86_64-apple-darwin.tar.xz=612cc0142c5c838c975d49b81d8557964cac360f2a7cf3bcb295fa1514154ca8 -dist/2026-08-18/rustc-nightly-x86_64-pc-solaris.tar.gz=5d6937928b1928a219c3cd8e7c274b5e7b706b0933368e8edb73a061f4cf4c8b -dist/2026-08-18/rustc-nightly-x86_64-pc-solaris.tar.xz=141598ad72363b070fc4843a991ecf3d8986622536698e1743191e82b1aba5f7 -dist/2026-08-18/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=0fcf7497f77d715542b3ddecf7a216b48ad832329ae0b1d12c5fbc01c9a6f00a -dist/2026-08-18/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=93cff41c7ce08537557c80f243b1d8a03d2fe86da9b94523c3a77da683babfae -dist/2026-08-18/rustc-nightly-x86_64-pc-windows-gnullvm.tar.gz=babc16bb58f82d99e7766c3e53037cb6669331b8cb24d4c3bdfff0ce259a55ed -dist/2026-08-18/rustc-nightly-x86_64-pc-windows-gnullvm.tar.xz=6de4b5f59f6f303a8f4d12cb3b2cd121e81e3373d96400279718fda3fdbad00e -dist/2026-08-18/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=068d8e709a0067f01dccda415e840d0ba3e3b23c93941ec2d49f31e6d7c4b6f7 -dist/2026-08-18/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=8a3756be311c70e5e0a96013c05ed722d32a1b34d0907d620f7b6cbbfa186b02 -dist/2026-08-18/rustc-nightly-x86_64-unknown-freebsd.tar.gz=0bcc22a6a5ae3098a567e18ab22f0577dfab3554085fd2f9999e78009d70269d -dist/2026-08-18/rustc-nightly-x86_64-unknown-freebsd.tar.xz=d03e5df866c860e45ab492ea85874f6d32c21978c73883dbe523b54c0113e5a1 -dist/2026-08-18/rustc-nightly-x86_64-unknown-illumos.tar.gz=9fd49f5f363d407549f284145b58124d78027d306b0f4e1ee66b1ac3041845a4 -dist/2026-08-18/rustc-nightly-x86_64-unknown-illumos.tar.xz=2641a0ee225272620be1a0e491c8e09a8fa6897de6c9f3a136656f89f9176dfa -dist/2026-08-18/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=e05f9bfebc9fbe968792a69b5fc2229a2a4b03179e5f03989801833f5adc766d -dist/2026-08-18/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=d363d6d9d78e0a65c91763866f54baa2a9d59f4f48fae07697c450b715326685 -dist/2026-08-18/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=2789540ecb7f9b6e0448d2596c1968a4b5640d20e00e0b4c83beb7d20f8997c3 -dist/2026-08-18/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=00730e7cdb24bfede2256b8c58d14626a3b9d8fa58a391945f42342d4b08ca6c -dist/2026-08-18/rustc-nightly-x86_64-unknown-netbsd.tar.gz=ea3961377ee8acdf8e32bfefcd3ff2188e4dc272c35f93a2f809b0130e313d77 -dist/2026-08-18/rustc-nightly-x86_64-unknown-netbsd.tar.xz=83a06931285b8ecbb6f7cee75f44e15c7b308716f8d5864cde2a533a8693dc26 -dist/2026-08-18/rust-nightly-aarch64-pc-windows-gnullvm.msi=f911335169b70dab3ae0251d327109a96c1a884dc5e2bd53f157c2453db5aa35 -dist/2026-08-18/rust-nightly-aarch64-pc-windows-msvc.msi=c0c356e9dd3d2260426e942332ed1be71ada04035424e447b456bef707fde106 -dist/2026-08-18/rust-nightly-i686-pc-windows-gnu.msi=d6e498b7c77c29913c239b98be256c05ac02c91de6570b563e4dda628765a420 -dist/2026-08-18/rust-nightly-i686-pc-windows-msvc.msi=05ecee49dd6751c323353b69617dac4e13fb485efa2ab84a35b6fb0e04d9f81a -dist/2026-08-18/rust-nightly-x86_64-pc-windows-gnu.msi=00b1eaaac8412a125911bafe9eee25ae6e9dc1a2e3b680eebf9aa8a6dc5a318d -dist/2026-08-18/rust-nightly-x86_64-pc-windows-gnullvm.msi=87d187b541d90a7537014f7a03a6c53ce19c49c8a85ed3c8b83f1f74e8c73dfd -dist/2026-08-18/rust-nightly-x86_64-pc-windows-msvc.msi=e3a11247f04d54c505fb2c6bce1b9a8de53a6baaf67322ac832d5e4896a67450 -dist/2026-08-18/rust-nightly-aarch64-apple-darwin.pkg=ac481df372d9b7827993416223ba12d8505060ae5f66267135203ab86e3e897e -dist/2026-08-18/rust-nightly-x86_64-apple-darwin.pkg=0cccf72b516978d7ceb0187e6c40ba2213dd62ef4d364f197c44a6c29a1b4a9e -dist/2026-08-18/rustc-nightly-src.tar.gz=f6bbe8ac8c45dc92eedb208f8c3d451b156b4c818d87be16dce083b33c313af7 -dist/2026-08-18/rustc-nightly-src.tar.xz=14e366ab22e3ab6fa0a7146be747797663c00db3d1d04834d1b55187a9efdfc7 +dist/2026-08-30/rustc-beta-aarch64-apple-darwin.tar.gz=63da74142f0e917ccbc13cf182bae60d9ec3d545b712ac6150fe8b4e633a2c7a +dist/2026-08-30/rustc-beta-aarch64-apple-darwin.tar.xz=0c20c4730544923b2ba9ab4ccf98cd22db6759d1d6cc2e5b8c99662b953163ac +dist/2026-08-30/rustc-beta-aarch64-pc-windows-gnullvm.tar.gz=1d67701059998ff993a42c3781b2b735bf537d9db46bdb0b94e6cd9313f69b0c +dist/2026-08-30/rustc-beta-aarch64-pc-windows-gnullvm.tar.xz=093d13372b7bc06246e63a1e18aac59464e71939b951e14ae0ce500f467be92c +dist/2026-08-30/rustc-beta-aarch64-pc-windows-msvc.tar.gz=d1a51ad8e37b8f482c994527f7062a4b3ac9d1734be81b677a5e270ff121747e +dist/2026-08-30/rustc-beta-aarch64-pc-windows-msvc.tar.xz=f019195e5c72d6b6e699416d8851555965ccf5f108bddae999e9bf37fec19693 +dist/2026-08-30/rustc-beta-aarch64-unknown-freebsd.tar.gz=f9b8e19c81bb9cbb2c75d841f043b084aa9c3c239b359c761d02d255c16ec928 +dist/2026-08-30/rustc-beta-aarch64-unknown-freebsd.tar.xz=fd02f9f057e75b2f6e5c763dcad6dfd9ec39c8e03a40f2cffb82823edbb2da26 +dist/2026-08-30/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=1f44bbb85ebb6d4c218016661afa545a8e038f1b937e49f81bebd915ba10c608 +dist/2026-08-30/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=e2e2bf7f32709df924efe7b5f530781ea1428ce163e92270a3ee476b7b3a3d1a +dist/2026-08-30/rustc-beta-aarch64-unknown-linux-musl.tar.gz=5452dc6c27dab927dab0afb5be5f300f1cc9af3c7ccfb88dd605227851fd65d7 +dist/2026-08-30/rustc-beta-aarch64-unknown-linux-musl.tar.xz=1f7c588a39f096f7578fc6bca93f0c85ae40976cf26a51913070119a8b910e07 +dist/2026-08-30/rustc-beta-aarch64-unknown-linux-ohos.tar.gz=8aa1b28d25e4c7a21d3fcb85254d1e2c169ff55b3536a290edacecb6c051ab4b +dist/2026-08-30/rustc-beta-aarch64-unknown-linux-ohos.tar.xz=27208aaaebbcea8e819d7d9fbf20dd994cc24f727dbee339d34e6a995e2b9864 +dist/2026-08-30/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=73f04b6601665531d79900f59a8f92f3e7a90f196d62e1ea10e20a3e6ca6f8f4 +dist/2026-08-30/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=64b0fb006d621f6003527b41e9e31f9141f3df09a0dfe979ee68054d1346016e +dist/2026-08-30/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=19e1f450d4aa8d169898170c9bcd2ab7fba9d3453a631c57a5148236805f101e +dist/2026-08-30/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=f7715866e5e05360279365dc39eefc96436a53f429cd5b283662a81634f7371f +dist/2026-08-30/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=2e765b6a53cabb0077ad4f8f563862d115c9f152165dc92615a727bdf0d2998b +dist/2026-08-30/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=09a111ae1c8861099a39d495fcea86c65780bb2b7a6c7bc19fff56915b4f11a5 +dist/2026-08-30/rustc-beta-i686-pc-windows-gnu.tar.gz=02d8f06789c7f48a19e31ddc7c3f8dab995197f7857d410f6df60dad1067b8cf +dist/2026-08-30/rustc-beta-i686-pc-windows-gnu.tar.xz=91bf9711b7551cb3caf6660824ad5c04f27ed9a0fd086211b3aed56628311d45 +dist/2026-08-30/rustc-beta-i686-pc-windows-msvc.tar.gz=70525d3d60e2ebddb9e7b3341314caa0df4e34bdfcb47bae46927fa13a6ed327 +dist/2026-08-30/rustc-beta-i686-pc-windows-msvc.tar.xz=59d9ecfad856f135df42afd957024ede0a3eb263a7ec4ffbf517e16696054d83 +dist/2026-08-30/rustc-beta-i686-unknown-linux-gnu.tar.gz=317c5379344a6e473a29e432d4aab7399ff3dbe86a72dd279c0c82c495d98c65 +dist/2026-08-30/rustc-beta-i686-unknown-linux-gnu.tar.xz=af6b78184886cff946f408dcd27ce4332fe39b514c49a6c285aa12ee8a895194 +dist/2026-08-30/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=0894c6b942bad197888f596f7d518595f5db700cc21089b39d9b923c0bc2c902 +dist/2026-08-30/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=d10527ec270b021405f4c7c8853296837efa3d4f1804d7e9aaf22c7f76b3ac8d +dist/2026-08-30/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=82edc27720b2001ef4ccfaa8638c839bd76ca9294723516749544a794a963f76 +dist/2026-08-30/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=efa4d683554b36de9d19d1aa6a6bcd39223e4b8726d5108895071169f976abf6 +dist/2026-08-30/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=453f91a3f885305cdc98ae91bb06fe0cd3bc2f2cad2db05ffc51a9957c5d7dd5 +dist/2026-08-30/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=acb98b89f961c5b309f54e6dd647f68c105f0f95aabbddbe6363055ab842fb4f +dist/2026-08-30/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=791dc39fa441ecbd5e976da99d988796ad5382f62a85856722dba4fdc4f81491 +dist/2026-08-30/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=005c0e756b757b0d49b6ec9777a9997799d5328f826a4d168a67994591323037 +dist/2026-08-30/rustc-beta-powerpc64-unknown-linux-musl.tar.gz=d3b6748b0471837b8f2f7118e739f4870f2875fb061253c71dbeadcb5a88253d +dist/2026-08-30/rustc-beta-powerpc64-unknown-linux-musl.tar.xz=9c681f8f3efd7f8130ee8c2a40c39d83f6bd58858e134c8df8bba2b65fc3da1a +dist/2026-08-30/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=3924195349e7b1b31f6334f0d07d66ca4f3c423fb57b8bdded25fa1746b4d1b1 +dist/2026-08-30/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=3f0decdada02b892f63920829a4af3541f149d44b162b3a98d2aa006f2bf47cb +dist/2026-08-30/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=c8c0a5745dfcecc41a52876a9658badf7a35417173f143f50a6d304eb99c4dd6 +dist/2026-08-30/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=47992ff2ff6725eac8e6322c1d76df258a54fc928cbcc8d175acfe16b5a4058f +dist/2026-08-30/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=91747193505f48d0eba8653bf14855c81999afefb632207eac3d7d6f355fd2bd +dist/2026-08-30/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=95f5717569d3b07ed6808c82a5a3849284ce9b404792806fc06356a11ae54895 +dist/2026-08-30/rustc-beta-riscv64gc-unknown-linux-musl.tar.gz=ff705b94a62127be2bbbaf20a036fd4d9c3fcc23b852bf50b814120637eb28d9 +dist/2026-08-30/rustc-beta-riscv64gc-unknown-linux-musl.tar.xz=da5837ddd0b7ab0b10be836fcf757ce117bbe54e57d7ce696c38e8779be64328 +dist/2026-08-30/rustc-beta-s390x-unknown-linux-gnu.tar.gz=7282b673f837c2998f70a47e44c67d2d88d75f55be6c363a43706f37acde0676 +dist/2026-08-30/rustc-beta-s390x-unknown-linux-gnu.tar.xz=2890fbd6092fac747d44f525623e77c87d5924a878d20be664e20068f729f01c +dist/2026-08-30/rustc-beta-sparcv9-sun-solaris.tar.gz=b1526015253711f6b54e5e2081e5503461ca94e66edffa3226899c357350475d +dist/2026-08-30/rustc-beta-sparcv9-sun-solaris.tar.xz=dc7adedded9d7c4022057709f33de27a6ace3d08a264f17bee7c8e1a92e975b8 +dist/2026-08-30/rustc-beta-x86_64-apple-darwin.tar.gz=9f06cb6793158449b822f07b86a2a57c73d12ad05dee33d188027ae20559f197 +dist/2026-08-30/rustc-beta-x86_64-apple-darwin.tar.xz=d506f9e4bfe7d3d223a88392d5416ac0203924e31b6e3f68a32adc1578d74e0b +dist/2026-08-30/rustc-beta-x86_64-pc-solaris.tar.gz=60825508456e01c09e82986c2c3574dd954e2fbdb16f20db1751437eb2294414 +dist/2026-08-30/rustc-beta-x86_64-pc-solaris.tar.xz=7aa295d6f6ab2eca3d72e1703bc533ac01908dd5080a859c7ab01003d0634d9d +dist/2026-08-30/rustc-beta-x86_64-pc-windows-gnu.tar.gz=01bda7ca1de22ac2881f0da5bd1db0c31500eab3e4b5273d16b581193788e32c +dist/2026-08-30/rustc-beta-x86_64-pc-windows-gnu.tar.xz=65229fa0b642f511ecae17f456d5a67aac0338adcb07ad0746eaec97cd0b2d25 +dist/2026-08-30/rustc-beta-x86_64-pc-windows-gnullvm.tar.gz=90021d8fc771da2febbc00152c6dd7c3b58845a9a522f74573a2acab9f55a016 +dist/2026-08-30/rustc-beta-x86_64-pc-windows-gnullvm.tar.xz=cec531ec82cd3630818985aa6e2e2afdd553e195c87c26873b914c2a159929a2 +dist/2026-08-30/rustc-beta-x86_64-pc-windows-msvc.tar.gz=2d41c0c375f565315155c80e0d241bd8ea132e994b5d87ded8a21302f29d5ab4 +dist/2026-08-30/rustc-beta-x86_64-pc-windows-msvc.tar.xz=6d82171d5e4453c466313f6541fbb62dc74d0c7863651413c687b7f4c27b2a4e +dist/2026-08-30/rustc-beta-x86_64-unknown-freebsd.tar.gz=0509d78b60e4743b1953f12a70a91adc7ef48cf886826dcb16e87695999c7699 +dist/2026-08-30/rustc-beta-x86_64-unknown-freebsd.tar.xz=a5714f58f8651919a51c8ce28536ce83f86fd7ac72bf067dd97189c1d389c07b +dist/2026-08-30/rustc-beta-x86_64-unknown-illumos.tar.gz=883ab0b98ded267ff1b7a8fd0d9ffc7529ff6a5e6b1e73c2168faf1c90d92ef0 +dist/2026-08-30/rustc-beta-x86_64-unknown-illumos.tar.xz=58178ca6b6c9ced54a0f7991fbd94f6d92c32eacffbf774444429ea46b1f58d3 +dist/2026-08-30/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=2a164be1423d98988d4c3e9c7635af9150a961b5fb3d2052517987266978fc65 +dist/2026-08-30/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=66764b74fe55573ea5884ac7ac98fd7e5bff95f4ee0f389e3f5ee07eb75e1623 +dist/2026-08-30/rustc-beta-x86_64-unknown-linux-musl.tar.gz=4b7216393d167874d030e24efd637717f8451c89506c4964220632556522e881 +dist/2026-08-30/rustc-beta-x86_64-unknown-linux-musl.tar.xz=645c594846ac499aa29bef08dacf4402f2479413fb98ab255419bbcbaa39440b +dist/2026-08-30/rustc-beta-x86_64-unknown-netbsd.tar.gz=a1044a20bd4e0894f94d0d2a2f2601bd9e8315be561bb196360950fc959c9ab0 +dist/2026-08-30/rustc-beta-x86_64-unknown-netbsd.tar.xz=c90e60e75e4d2420bb58df22483f028c92eead983b2a5f73e1c87f66196a80d1 +dist/2026-08-30/rust-std-beta-aarch64-apple-darwin.tar.gz=9f02f6d297a31bb6a6bca2648f7e6e381d386365ec2548619f200fce3d1d7109 +dist/2026-08-30/rust-std-beta-aarch64-apple-darwin.tar.xz=d8f4620f3672cae11fdb841a86d44215aeba2e656244286056f7742e966797e3 +dist/2026-08-30/rust-std-beta-aarch64-apple-ios.tar.gz=547510c49fc9c4d993ca76d7d2a38e6e0fc791a8b838fb30e246df78c3480ce8 +dist/2026-08-30/rust-std-beta-aarch64-apple-ios.tar.xz=b54fc751131000c13c58b2863ed238a6d6f750fdb1b1a5e6e1110e05bedc5f7e +dist/2026-08-30/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=c2c93323193b2f6d796934916c002c0d98203745c98458678d70eaff2546566d +dist/2026-08-30/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=ab88ae96f66a15ce8fb00296e8f7f292d31f941e89455529ee7544220187cdec +dist/2026-08-30/rust-std-beta-aarch64-apple-ios-sim.tar.gz=dff0cf3e961505ada60f6fad68cc5f5881b725bb7ef0f0d23b6ae4fb8722f5a1 +dist/2026-08-30/rust-std-beta-aarch64-apple-ios-sim.tar.xz=b6c00ebacb1758e8f3b830a054df06d120e270c4b2a0ef88866b06be2bb95e53 +dist/2026-08-30/rust-std-beta-aarch64-apple-tvos.tar.gz=7f6c1cb3f8b5870449fdbfe1139f27c93b810b1f52da01a93abb8c8656ecc14d +dist/2026-08-30/rust-std-beta-aarch64-apple-tvos.tar.xz=e40b47e96b7ad06f7e13fa0272b4b8014eb4799bd4c7237f35df513eb7eed7cf +dist/2026-08-30/rust-std-beta-aarch64-apple-tvos-sim.tar.gz=158c8066d75a93d770ca620ffb64b92d39630b401a909f17e99765b9871ec25c +dist/2026-08-30/rust-std-beta-aarch64-apple-tvos-sim.tar.xz=635d4e479727b51957b0bbfa14ac5ce7b3282ae146aa04a92ff28963cbf9635f +dist/2026-08-30/rust-std-beta-aarch64-apple-visionos.tar.gz=28f4a6e679995ac6b4037f29c9cdc161183012edb39e484d31ce24ef044128d5 +dist/2026-08-30/rust-std-beta-aarch64-apple-visionos.tar.xz=b3d6255fb1e052747ddf5c3b3484040cbf03dbc882e92cde98c8656442f84cc5 +dist/2026-08-30/rust-std-beta-aarch64-apple-visionos-sim.tar.gz=09facc091183c715daf223d9bd158d6333c6e3f837627bf318f2c0e1be0851b9 +dist/2026-08-30/rust-std-beta-aarch64-apple-visionos-sim.tar.xz=4943e00b8e0496786ec9c2bfa526da1f44aa162f874f7084f51c95c3ec3a44b1 +dist/2026-08-30/rust-std-beta-aarch64-apple-watchos.tar.gz=ba3e478886aa3b34101334e3ab9a3543a0f5e3d44f44efa48bc7b56c14a3951a +dist/2026-08-30/rust-std-beta-aarch64-apple-watchos.tar.xz=2e4e7035ab8464d8ba3775b66433b1888044394bf18343bbbb16304ada735368 +dist/2026-08-30/rust-std-beta-aarch64-apple-watchos-sim.tar.gz=7f8ffe07832cc648c8be54b79bc6923594a34e254245e07fe706fccd52b28195 +dist/2026-08-30/rust-std-beta-aarch64-apple-watchos-sim.tar.xz=343aef2c9816bd2007837916a8ee5101c1b0b97692066c5cf844a7230a42a346 +dist/2026-08-30/rust-std-beta-aarch64-linux-android.tar.gz=94b3a90192944d2483e2c4e3bf02a03e43b00540c16873d869a75b6e6d7a675e +dist/2026-08-30/rust-std-beta-aarch64-linux-android.tar.xz=e26b35a45e9d2331b4ee37f6f9b70f927dc89cd4b956ec76c556577c7b0fa1e4 +dist/2026-08-30/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=24eef069090edc04f787002c971bccbc328775b54d98e3ab63b247a4c1e0e99c +dist/2026-08-30/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=88cf54b25e9a76e303413bb6d32e064d784e6b83dc282a42d45983d57842ca08 +dist/2026-08-30/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=726999c2b5dbec5ca64e56abbce4d246dcb265d709df96d48a4653e863531ac7 +dist/2026-08-30/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=22e04ac2cd44daff5e5873f8492a1a3345f83034021923ff223cb3905c81e16b +dist/2026-08-30/rust-std-beta-aarch64-unknown-freebsd.tar.gz=9593926d80f8b3adfa59b2073f48234001d70c08225d03e0f128f0188d2878c3 +dist/2026-08-30/rust-std-beta-aarch64-unknown-freebsd.tar.xz=f43da9dc7737f5881391e92013f773c6fc3888dece33eac141797617d590ecc1 +dist/2026-08-30/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=9d177fcaf3805830b0b0a1661d3306509f5620195877185b0630193220a95feb +dist/2026-08-30/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=b1c017c1cc05c334f74dbf747d29e692cbf4bdb9c08d5778067266d7816841f4 +dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=b443b40dbe16c1c0805778d34a652b16dd891e5d641ece48f988be00d4ae8c25 +dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=295de2ccd9c9ffaf6648e76a4bd358289fc78ed0ed162d38a69632a6bfae240a +dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=8fdf744594d28f7425df836f3ad3289ea052e26aa98e0d9659c8f03a85d9713a +dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=e87932897c88f458d35e53873b2c019f2cebbf11e634689f8e9b97c9320adcd3 +dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=33e0b8fbe21128edbaa3c2da91fac703107964f818624dd87a03179c9a6b4a62 +dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=8c79addb67a5c8b8181fa25df85516bdc4fa69003c2f8c9e8a6c6c60eaba6920 +dist/2026-08-30/rust-std-beta-aarch64-unknown-none.tar.gz=39cafc68fb5044aa42fa274fc7c49bc210472d5cd97ed82cd09c98b73042f66d +dist/2026-08-30/rust-std-beta-aarch64-unknown-none.tar.xz=78c289e2984f4b99bb9caa4d61833dc94b0588be7aac2309c4c9cf5d75b56703 +dist/2026-08-30/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=b6012253ae93c1a13ea4e8cab50873c206056fd9325d26de402e45669950994d +dist/2026-08-30/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=d9fb182de0cffbb3a74fe309ba65d79323901da154e9766a88a569247f260d2a +dist/2026-08-30/rust-std-beta-aarch64-unknown-uefi.tar.gz=f54892f078518f520b32bf76a932cce2c450289cd70c826542477401109eb3dc +dist/2026-08-30/rust-std-beta-aarch64-unknown-uefi.tar.xz=672c8e38330262341209232c73bb600f2949b3d5a1f5c93d0a95e18539fb94de +dist/2026-08-30/rust-std-beta-arm-linux-androideabi.tar.gz=887d61d7764ea35bcb2fdd608940a0d3b0d888cd2b8c94f33d242ae71d2269d7 +dist/2026-08-30/rust-std-beta-arm-linux-androideabi.tar.xz=29f1dea85c828ae819c5ebca3d76dd451cf72e9498f9f207f3272162cc159cd1 +dist/2026-08-30/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=b735d7f9cfac1d3a7ad22e0b79979f78aeded3c538dee686728ff9e8c64d6787 +dist/2026-08-30/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=878c84e83139426b209f0ae84a898e005f499d38700f5d8446a6aa4ad81feabf +dist/2026-08-30/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=bdaf3e6c1fba51bd37e7d23b547642885b97e3e66e3e5805f60ee03332e1548d +dist/2026-08-30/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=26446f3d1d9e235e11ebe6e21e3c8bb23efe5e8d31671bf2d573af5e39ae7ba3 +dist/2026-08-30/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=21a1317f24f27d3c567c08c8306f3c97a38dad185bde37229e7c279adb52875f +dist/2026-08-30/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=51ad360481ab758d3023dc615351afba30cf99a162e3f207f5275b5995258412 +dist/2026-08-30/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=57d7204c68646f489e1db251e69d5fbb329e71954100a9a58bc4eea5bd526c34 +dist/2026-08-30/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=01b476bcd78cfc757d9687ad65cad8c15f4bc5bd2e3149a04314e1604257169a +dist/2026-08-30/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=3b94aba1d51f5a6f039a555122d358bdd8e8f3a1a13e3622842a56acd9e48765 +dist/2026-08-30/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=c814c2d7b7de9f97457932139960d40d869ae6783528a6e0d7edf3af0d34da2d +dist/2026-08-30/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=2783998a08bf439cc4f6113a2d7f454791a8437bc9bf9b8d3a9d991bf830eddf +dist/2026-08-30/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=bf7bb1f7e676b0f70786ba671a687701879a7b34f3ebee99e6faab139444c0ca +dist/2026-08-30/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=0d39dc704bb80630048ca2b6b3706c4e9bbf8c16a1eb24c41e2c818e2c89222d +dist/2026-08-30/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=98058d9812f279e9797e6e2163d706dfa6676647d6abd64efae52d9602978bfb +dist/2026-08-30/rust-std-beta-armv7-linux-androideabi.tar.gz=906e3d6b21ca38b6358a9c381aba7aa8e2894a2abe649d12dcef91cc5ab83dca +dist/2026-08-30/rust-std-beta-armv7-linux-androideabi.tar.xz=bd9c5e2dc8542dd0ebcdb53b40422d364aec9399b93b731879c5cada4947583b +dist/2026-08-30/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=a4f1149965d18e306ae5fb29382daa6b0e17b1667d8eae08f0342267d7aa6857 +dist/2026-08-30/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=58121e6668b93a7bd853dff02ff26fe0c4f5e721f23acb7f092cbdac35835a87 +dist/2026-08-30/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=7e3ce83fea162bd4eab433bf35402ecc2099a46afeb66b86ea5e54f0b53a93d5 +dist/2026-08-30/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=4737ebecd9ded896ce25f72c7d2397759bd9243d7399bd6955b90e3fdb4c27d2 +dist/2026-08-30/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=26d2c719cb467295e3effaeae939241325d6fdfd6d32784e90b6c955cf294ffc +dist/2026-08-30/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=d2ec9ee496d74deafee30846ce577333154d4c4221943d53129f3a4c8365118e +dist/2026-08-30/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=60007d5b87b54b4f500ce686b1c6740ab7641dda28676a9c56df7b9a36c34141 +dist/2026-08-30/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=1befc6a2e3b6d7e23bc132ad6fcf4e59934d386e2e467dbbc5ec425d628db846 +dist/2026-08-30/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=6ee69a47a0ce552fb9b69edeca089004c84de1d380ea45554964be8dc5b854d7 +dist/2026-08-30/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=6a594a15e7a1962f4417997d1b1fcdfe72a3786f019242567a915237a8f12112 +dist/2026-08-30/rust-std-beta-armv7a-none-eabi.tar.gz=af06b8910b044e0c804802c316904d53d0a6072d601353927bf5d733cbb10664 +dist/2026-08-30/rust-std-beta-armv7a-none-eabi.tar.xz=dda99a3c47b6fdaa000172e3a9f52876d168499a24e33716a1277a2c1d3e303b +dist/2026-08-30/rust-std-beta-armv7a-none-eabihf.tar.gz=42799d4c5f6b596b6f4c565358adacd2982433cf26f16bde99047f63b07ab97a +dist/2026-08-30/rust-std-beta-armv7a-none-eabihf.tar.xz=0cb9cfeae9a30ec848ef007dd9144398c66be3a755ffe94d9898f2da9057170c +dist/2026-08-30/rust-std-beta-armv7r-none-eabi.tar.gz=b248ea8f35a5557e53882f362ab00211f15124688f56e57474c66bece0bc5c77 +dist/2026-08-30/rust-std-beta-armv7r-none-eabi.tar.xz=9427d716b04a5b178788fead61b3b41abb4acf482bc3def3c1f9b3513243b156 +dist/2026-08-30/rust-std-beta-armv7r-none-eabihf.tar.gz=b8f8e1359af035a33afde195fe4c3de23412c950e216d1ecf6a80fe471f5eadc +dist/2026-08-30/rust-std-beta-armv7r-none-eabihf.tar.xz=1a8aa055f437a8e6dc258d60697f10664b2e28e74ee450d256fd38243730a101 +dist/2026-08-30/rust-std-beta-armv8r-none-eabihf.tar.gz=3b512dfdc3365c1e7d19e42755506a2aca6efa880d754d7838e69b19f6a8d607 +dist/2026-08-30/rust-std-beta-armv8r-none-eabihf.tar.xz=f12bca87642b53c9ef4672ad070913a411de0b772a1f4437b9a258a989d8298c +dist/2026-08-30/rust-std-beta-i586-unknown-linux-gnu.tar.gz=af08b969901c84b02a2501a667bd5cb89454a0817ba66c9fd9a00b03503c922c +dist/2026-08-30/rust-std-beta-i586-unknown-linux-gnu.tar.xz=ec871b92b19cef0f63baea61298575f50ee568046470d0bc12bfc7bee830e846 +dist/2026-08-30/rust-std-beta-i586-unknown-linux-musl.tar.gz=b6805cd6642b6b1de3e637581313cb26241526112114adca8157179948f967e4 +dist/2026-08-30/rust-std-beta-i586-unknown-linux-musl.tar.xz=5c2827bdd87154ce42ad9939dae78a022d3c3045f9b8698f60292e5ba0a0ff14 +dist/2026-08-30/rust-std-beta-i686-linux-android.tar.gz=c568edbc22aba9c2e2360bcf821e9c60894ef3836fc7846cff4c178b2d746fc9 +dist/2026-08-30/rust-std-beta-i686-linux-android.tar.xz=0bd654f6591c99d139bb83ab7e2699327697feddb12edec50bf4f834c0edcffc +dist/2026-08-30/rust-std-beta-i686-pc-windows-gnu.tar.gz=701a3087c3810884d3a83345d2ae8b3de6b1514fbf97bbed99a0421abf2fa2b1 +dist/2026-08-30/rust-std-beta-i686-pc-windows-gnu.tar.xz=b8e8bb023d34012e82d708a0d6e4a558c32f0e489b3eb381b88919aa554578fb +dist/2026-08-30/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=a36eafa511ea809368df67889b2fc0b5a18ed7c2a1e9b21118b160f2b8a63a5b +dist/2026-08-30/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=f1b0c50faf927e5ba97cf0533287cd132f1e3a2b9cb0338f7a56e1ed4311b0bb +dist/2026-08-30/rust-std-beta-i686-pc-windows-msvc.tar.gz=847c2c7aed2ca9f03bc2a8a46ce9b2e48e968e8bb9d947349f83ecde27464631 +dist/2026-08-30/rust-std-beta-i686-pc-windows-msvc.tar.xz=e49a11c577a0e860cfac07eaf0fe1a0f502ada16ec7c05c02d0c60293c8aff8d +dist/2026-08-30/rust-std-beta-i686-unknown-freebsd.tar.gz=c2435372ce00925ed17120ba1586b5d3dac6b4ce979e02698d87a74ad71a7a7e +dist/2026-08-30/rust-std-beta-i686-unknown-freebsd.tar.xz=113874727b99b497e5b346e908407f41b7b2f85cae272cc555dd3699fe8de8fb +dist/2026-08-30/rust-std-beta-i686-unknown-linux-gnu.tar.gz=78385dde39126b0eb524a3681bb8607c016110985ef0b2f2da00c86a5961d64d +dist/2026-08-30/rust-std-beta-i686-unknown-linux-gnu.tar.xz=52480e55a90a54d3174232b4b76f6aaef9055da0ed49733b19ea6c3b8a6db1ea +dist/2026-08-30/rust-std-beta-i686-unknown-linux-musl.tar.gz=350e1a7c2925462c4c2a8b796874f17fd0e284680f2dc2e930017b585ed661c0 +dist/2026-08-30/rust-std-beta-i686-unknown-linux-musl.tar.xz=fd62e7c69e1d0388aaeba25a9a65c8e327e60dbbc3f57948b9f7000981eb4172 +dist/2026-08-30/rust-std-beta-i686-unknown-uefi.tar.gz=41dd818f059414729cd8978a4b79995b765493885dd89a0587be88b83f844aa0 +dist/2026-08-30/rust-std-beta-i686-unknown-uefi.tar.xz=6fb74e7c1b4b20c8b28966e2ee89ab9b1208fb43f57d8f9fe91e5c5bdfa9e046 +dist/2026-08-30/rust-std-beta-loongarch32-unknown-none.tar.gz=5cf23bf844fd1157b9360303459beed6fb1ca77a2bdefd7d394a1d50385670f8 +dist/2026-08-30/rust-std-beta-loongarch32-unknown-none.tar.xz=d952d3f950b776c68528bba94c76a06fb2d55d363fcedeecb1155d6de3a31d3b +dist/2026-08-30/rust-std-beta-loongarch32-unknown-none-softfloat.tar.gz=1967abcc458e9f5efc46f052733490cde533ea074a3ddc0d2fcbf002be4ddc79 +dist/2026-08-30/rust-std-beta-loongarch32-unknown-none-softfloat.tar.xz=bcc63e232b44d653196104d93629ead81c19c1facd03d97207da744c353167d7 +dist/2026-08-30/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=d8946832080fa2e13498bbe7e0cc5611f1c93da1a7b5e3b19c836d03fe784c15 +dist/2026-08-30/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=fda84558d60dae4383d6556545bfd0f292f4ca7226db012948c3c2c32b514c6f +dist/2026-08-30/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=63e4aaee66fdf0444becbab59ecbd7a1955d27e5e7420507bfe78e482558a4e7 +dist/2026-08-30/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=6bc088d81bf425614dea2f31fb0bcf229566cfd912078ba997e272492f5dfeb8 +dist/2026-08-30/rust-std-beta-loongarch64-unknown-none.tar.gz=aed26cd5efdefbc5b636d3a31566c816eda9dde7061efff48b327254b2fc9653 +dist/2026-08-30/rust-std-beta-loongarch64-unknown-none.tar.xz=dd470e7c8ed1a37cd140161988578a31297de2f3739a1d0a1994618f61c4c290 +dist/2026-08-30/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=be92ce71185bb0bf4d0b220806e6d0251c80eb70d6ef133c205e8121863d0f41 +dist/2026-08-30/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=1417b6cf3730f228ac07f045b8ee6506c2df0d8ae7b262e61ea7625c2ee866af +dist/2026-08-30/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=1b10411f90f9ceb94ba6e901ea347a7b14c784250b26c7ebf578ea0f0f774c34 +dist/2026-08-30/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=5998d419985fe62e015ff1d01f83907a7606c28364c0edbf540db598dd446ec6 +dist/2026-08-30/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=efba4705562534e2f6ef97857cef856c4d1c88281cb307c7f6696bac05eac943 +dist/2026-08-30/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=d716a06bf4bc9ad2f2d3ae17997cc3b377b8dbd1dfefaf93ae7d4f8c6a913af8 +dist/2026-08-30/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=7576dd106e174a21eaad65bf48351233ad8cdec1c5f172f6531efc1edeb40f59 +dist/2026-08-30/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=e187119c3fda1b444c340f4d123f95fb23274b624683c844676a15ca2457c209 +dist/2026-08-30/rust-std-beta-powerpc64-unknown-linux-musl.tar.gz=43e4647b626a5c8eb34ef930c70b89ae1efc4d7cb93ea35ea91ab82d52e20ae5 +dist/2026-08-30/rust-std-beta-powerpc64-unknown-linux-musl.tar.xz=ca4204801a3326475c726e3916d9a89c1b8f4f9eb8f2115dac4f005f080355de +dist/2026-08-30/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=a5d389199f5e64c7f25a97cbd80082a9b07481d79bdea6052ccac4d5e46ee390 +dist/2026-08-30/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=8979ec9fa392b43e9e0e166a68dfb4a0fdf23e28bb54abcd305b5e0e99811a72 +dist/2026-08-30/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=39b9c96f6c01f8ad15e7b5e3cb1550258d9380ea43126c25745c38b7fdb57583 +dist/2026-08-30/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=cf68b7783e218d0b5fac2bc6a431b3c8dedbf016c10c510558771cbdb8c473a0 +dist/2026-08-30/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=adac96c3877930f85c8a9ae7a3afce44bf9030c1bf389dc3e21e7ab0c83c9cf7 +dist/2026-08-30/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=138e96b975fd2bcf54525775a02ab05e1f9ad80095d01116f33693b4359bf0d6 +dist/2026-08-30/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=e7be47333fba57452ed7bf22bdb165a60ea243f9a593df5e8eac32796b0d5d7f +dist/2026-08-30/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=9b4ed1df7fc906cac3f1c9bbb5e546b58e9c6402b9573c4f69c160df8c5e00b8 +dist/2026-08-30/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=43898c8585bea709bcd682eeea33e914ab8be343ca27dfb82c3524e5ece2d37c +dist/2026-08-30/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=af236521d4556f90cc003dd17f692de787befc62e8c2df11242262f7c2afff22 +dist/2026-08-30/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=2f8125c2d07bb57d821662f06b7eaf00d8b98a7386be372cbd6cd517eb6c6e7b +dist/2026-08-30/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=1a86efb62f35f60d7b1860c37430e039cecfdad2053f6e449577200d715cbe58 +dist/2026-08-30/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=6f09dc0d0bb9775d0f4b52277913e5fe8795c3d77e178e1682af563f3ab3a030 +dist/2026-08-30/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=0de9f4b1fe08f33dba23effeefa4695a4201094cc587bfdebfb4408e9d58cc8b +dist/2026-08-30/rust-std-beta-riscv64a23-unknown-linux-gnu.tar.gz=dd2e782f2bda2c8f220727b85f8d702efb70977c2232c48bc5d9858264501de3 +dist/2026-08-30/rust-std-beta-riscv64a23-unknown-linux-gnu.tar.xz=d1ba75a8d572591380bba39dd6fed42025f481642993329dc7c20479ea92a6b8 +dist/2026-08-30/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=d01ef2e3a1ec1c69b3a80aad302d066ea4fe406ff752c9b65f7ef1beebba0c22 +dist/2026-08-30/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=fb919571c31f43ef03b35908bf9ca85ba6bcc053ca289380ba2552c4e64104ba +dist/2026-08-30/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=b187f1deba8ea1bb3d3e793c3cb2a6b7f309940e4edbe8b406a023bce82d8785 +dist/2026-08-30/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=741cbbf9d91e955303f253ecd885168737dc01369feb33f738290668be01b146 +dist/2026-08-30/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=ed5c5a046e9896c7d9ad35c76db1c0216ed31c0661d30e29f3f7b5c8211aeb48 +dist/2026-08-30/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=1ae3c3dd12bc5e669d953521862fff3cec12b6f9f71bb8e3e7b24290d05114cd +dist/2026-08-30/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=3d3bd0667e139054169ec2ece3d16219269c858ffef37c4e9615b5bcf1e3c83b +dist/2026-08-30/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=d350e91efad53a550ef8c825e7f7ce12e99bf250afd9a93ed9fd155b72287947 +dist/2026-08-30/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=eac3ec8b4eb9a3b9a127d2e6fffc4b4a752449eb7595950c9af0dc83ea969b72 +dist/2026-08-30/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=d081593cc03f52a6937fb3bef0a2103a02b43cb4705d1747b8b513e1f0983834 +dist/2026-08-30/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=17db3b6de8e015e9c572899bedea98996a47d725c59664e338053ed590e4e33b +dist/2026-08-30/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=2e79e7c3eb7515581a8bbee2d02dd8242d7d3d1529eb067a387338b2ae5a63e6 +dist/2026-08-30/rust-std-beta-sparcv9-sun-solaris.tar.gz=72474e747dbdc104c817c90e96e209cf4adc2a441aea37d9c6dc3f89ceaa1a5b +dist/2026-08-30/rust-std-beta-sparcv9-sun-solaris.tar.xz=65cb719203ec265623fffd66f905257c0eb284c0795e736adcc8dfd31750378d +dist/2026-08-30/rust-std-beta-thumbv6m-none-eabi.tar.gz=25f399a7944d8db8a44c49c0adfe7800fa4b12585c49fe2ed69a1b417571b786 +dist/2026-08-30/rust-std-beta-thumbv6m-none-eabi.tar.xz=02183d46df50acf3edbd6778eccf24e357f9d49d87ae0d8808ef47f98cfbfd51 +dist/2026-08-30/rust-std-beta-thumbv7a-none-eabi.tar.gz=839004d3d6ac180bec0e467a7bbd2ea1ddb47a0f29a92f8b2a074f628cfd0395 +dist/2026-08-30/rust-std-beta-thumbv7a-none-eabi.tar.xz=7b9b6c32078adb895fd07f3f72b2db25e9358bfa4a0470d7cfdc3cc7b5a827d4 +dist/2026-08-30/rust-std-beta-thumbv7a-none-eabihf.tar.gz=5e962fec3cc8661e9a62f15c688ac76bc83685e19c163d3b899ec423766429de +dist/2026-08-30/rust-std-beta-thumbv7a-none-eabihf.tar.xz=8db16b6186b89b3e9e0c5560a12bb09d08263e04aa0f9ee878d25dba9852447b +dist/2026-08-30/rust-std-beta-thumbv7em-none-eabi.tar.gz=0150636fdc64ec355916eec21d1dec8f5e73881dd21cb78907a2f06c14a896e8 +dist/2026-08-30/rust-std-beta-thumbv7em-none-eabi.tar.xz=9e4dc0a8492ea92703df7e00994c0e1728d2eb3152947e9b8550d6ae05a76d0d +dist/2026-08-30/rust-std-beta-thumbv7em-none-eabihf.tar.gz=fe3fd11562d4c428ae2757d42f17ee17bf9485c7e7fda2f6a54406ac6ae14444 +dist/2026-08-30/rust-std-beta-thumbv7em-none-eabihf.tar.xz=97735c5e6f77e59ca7540eb303eaa2432f632f867fc7567f1d25540504e889b6 +dist/2026-08-30/rust-std-beta-thumbv7m-none-eabi.tar.gz=e8afd6861c77eff9e8296e1846c01c06d6b83a858bf76099a79588f167999efb +dist/2026-08-30/rust-std-beta-thumbv7m-none-eabi.tar.xz=0421b81a17afc3af31e46a8bfe32a9b178a6a29ba58e25d71be991d1ab84babf +dist/2026-08-30/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=9612f99fa78f59fcaed30feb3c8660c3ff7e731011226d6114cc49e3f765bb2d +dist/2026-08-30/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=405ab112b26871dc310a7fe3c67d821544f48b4acace5d406c491529555cc890 +dist/2026-08-30/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=884b25035258fc7cfc7b2a0e95358553a3c7812954ec7a18dde82fd77cad24b4 +dist/2026-08-30/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=3648213c47d2e29931f4837914b3aa5d00575ffda7d75654c6d3cd1aece8474a +dist/2026-08-30/rust-std-beta-thumbv7r-none-eabi.tar.gz=680435027aab539feae6b3904717139e20640eb783c7da2ee31f3d06c1c6ac1d +dist/2026-08-30/rust-std-beta-thumbv7r-none-eabi.tar.xz=8fad51ba8f85f7762f40382c1a177c86f8b7ae1a23e41871f560449f34ac099a +dist/2026-08-30/rust-std-beta-thumbv7r-none-eabihf.tar.gz=0a187507505715a5a4497c0422adba69c03e496618e20023d46aa1a261a7e793 +dist/2026-08-30/rust-std-beta-thumbv7r-none-eabihf.tar.xz=b8bdb79d81f1fd5dbdc090b3306f4ec33673dcfe24350c44e1544d00bb8bbe42 +dist/2026-08-30/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=430646899a6bba8c9233eec0987224e2ed42b6cee3aa37ce12bd8aae66097a21 +dist/2026-08-30/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=36576d200890f00ba9e22cbdb337262ef12dc99271c8006832ebe0752c333ccb +dist/2026-08-30/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=2b3cdc315cfbb7bb1a55705cd30934ceb14b7b098ac9e9b86af2091acc1b46ed +dist/2026-08-30/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=ecbee4d541806d2f4559e53e4da549293f4bb881c2f5d99107043251a1f80790 +dist/2026-08-30/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=8f925d1d913c67ffd9d28c8d02b47aade2388472015f4917a0f3166a8a789bb7 +dist/2026-08-30/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=c9ba654ccafd0cf8e876770f3133ae143da10f37058978cb67a547f64aa5812f +dist/2026-08-30/rust-std-beta-thumbv8r-none-eabihf.tar.gz=615b2c19357545860fb64ec3b6715c004a4bf29299d8d2130b022acdc7c46ccc +dist/2026-08-30/rust-std-beta-thumbv8r-none-eabihf.tar.xz=27d47d56201190afbaf2e2339d3f56964ff59972a90c994ea551438ed4703eea +dist/2026-08-30/rust-std-beta-wasm32-unknown-emscripten.tar.gz=8ccf1bbfc69d4e8e452294a838adf848d32d57621350a7791d8ac8e1e72f8336 +dist/2026-08-30/rust-std-beta-wasm32-unknown-emscripten.tar.xz=5bd2be0368720436ace1cf02569ca50fa222f936bdda7761954108756151b3bb +dist/2026-08-30/rust-std-beta-wasm32-unknown-unknown.tar.gz=fbdcf8103c16966255aa5a1a65ed02fe6e39862ef2b6e6eade8af07d51654392 +dist/2026-08-30/rust-std-beta-wasm32-unknown-unknown.tar.xz=5c4f71b3be2808511727536c13b6af98fb61661c092031df3f24c568f8bd31d2 +dist/2026-08-30/rust-std-beta-wasm32-wasip1.tar.gz=254037cb663a97b20471a3c87f95d62d1be7b2810a35e53acb219a552e8b58fc +dist/2026-08-30/rust-std-beta-wasm32-wasip1.tar.xz=5f651662f78216db6d2db5a8ac7f8ed04349a82530c08aab2fe3b43b8ea8bf8a +dist/2026-08-30/rust-std-beta-wasm32-wasip1-threads.tar.gz=6093fe10ebfc96c45909e85ae72f98e4f8093cdf2ce9bd720ac1a1aabddbd60c +dist/2026-08-30/rust-std-beta-wasm32-wasip1-threads.tar.xz=175403a655dc2afa2f7b41bdaaac4cb371a6c5cd99a043178fa93f97ab02f604 +dist/2026-08-30/rust-std-beta-wasm32-wasip2.tar.gz=5248648157e3ec5c37d12a40caae0adac59aaae47438585e79a7fc91c294ddf3 +dist/2026-08-30/rust-std-beta-wasm32-wasip2.tar.xz=46705306104b7c5d25a15c0f3cc94f5e208d4da2b07eb516d63533194e901b5c +dist/2026-08-30/rust-std-beta-wasm32v1-none.tar.gz=746d7fa3e93d255a395baaf67d3d318e6419732698ab0089692bdbed5ec4a13b +dist/2026-08-30/rust-std-beta-wasm32v1-none.tar.xz=97d8daf857aa2da8f8daff5f7137c4cf442f3cf05a019b5608a20a4cf5e5d291 +dist/2026-08-30/rust-std-beta-x86_64-apple-darwin.tar.gz=8a5ca2b36f9f4b2ba1dfde1539e95c30a20173137b9822e7d0ec5b2c12aa89ec +dist/2026-08-30/rust-std-beta-x86_64-apple-darwin.tar.xz=2daa0aa9b738f036815b667c664e152750acbb9d14ab41e4ea994000867caae6 +dist/2026-08-30/rust-std-beta-x86_64-apple-ios.tar.gz=4eb04a86e00e50becf154d88eac41feeda32c76730297fd05178a1e941dce0ec +dist/2026-08-30/rust-std-beta-x86_64-apple-ios.tar.xz=80dd8be8e4c1a83b66a0cce6cb5bdea61640e471e755c314a549b56dad10d2d6 +dist/2026-08-30/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=5080a59c173281ec57ff14c32401cb769b1a577ae7710cc54c820120b35c5564 +dist/2026-08-30/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=fae0fb63364548777b9e644e83e3c6d7aeab37953efea5ac27cd2558c828a551 +dist/2026-08-30/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=fdc91ac8f59e98eac84f79059a486c2ada66890f22b7e66ef7e0b899f65b36e9 +dist/2026-08-30/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=9ead7033def70e9f455e4079d8a8b1c870f8871b80ae721a41f11e53106a6b64 +dist/2026-08-30/rust-std-beta-x86_64-linux-android.tar.gz=c143b388083353883d88d109db9131c1196d2874a0195b66aaa4427365bd4563 +dist/2026-08-30/rust-std-beta-x86_64-linux-android.tar.xz=f877fbc3b099bccfc531661cf4a5d67a69c0cf426b7d6d3269b4aefb85304f9e +dist/2026-08-30/rust-std-beta-x86_64-pc-solaris.tar.gz=719cb1ac855967c03120c7408d05d88ff101e34de40a65f2d37828f496a84eb6 +dist/2026-08-30/rust-std-beta-x86_64-pc-solaris.tar.xz=647430147f7b7903111ef24a90d2f326198ca70bfa0bb0ee5b1e76d297e9a81e +dist/2026-08-30/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=520d157e438e557e8f37792b9c59c913a732c77149b534a1c7d2769b52e932dd +dist/2026-08-30/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=830bf07e7f1b80e535ddfc2c269c8bd4ca3c63853faa6ba39c7360b0fad976d6 +dist/2026-08-30/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=74c1ea656656a624eb84650a833f6d4d3428230435c67ce0a92798a524c55124 +dist/2026-08-30/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=8866757f9e3508bd74c724c754511413697229daf50da755411ddc8f9de78fbc +dist/2026-08-30/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=8b3ed1fbdf18c25a2900568f9c974154750a187d5385e06537fc54c607e8e305 +dist/2026-08-30/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=f5250ac89f4ee3b68b86e125e64b2209360040189b39e34671aee03b9de3abad +dist/2026-08-30/rust-std-beta-x86_64-unknown-freebsd.tar.gz=711017150d461a85f3dcf28a37c7fa354ae08dbfa9ffa049576e71b224d7c189 +dist/2026-08-30/rust-std-beta-x86_64-unknown-freebsd.tar.xz=5f8a081aa1b6e7ab3bf88b6548ed55a0c1021b26060ee2655da38556b54a0e06 +dist/2026-08-30/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=40d0e66f5b6c1831684ec5c6946e2467e9c81c38d5a7ceffbdc9441397d6c214 +dist/2026-08-30/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=2632a2393f2f51884db1c07a3f193f19942bd20ab7a3bce6f654444028188aab +dist/2026-08-30/rust-std-beta-x86_64-unknown-illumos.tar.gz=bfe5417f3575d1fd0302e6caef380e33c71fc07ab1b9a98fc80d66cf8997006f +dist/2026-08-30/rust-std-beta-x86_64-unknown-illumos.tar.xz=bff9b2786581d340b0e801b085bdfb40d19309e07a99a97f92cf2016d77db81f +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=76d75f97d7b0f3421029d078473529de626d1413d5ac8c0473325c15f2765573 +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=1ec3eb585a38de48d12e05f78c82394493c9c640f8c6fdf487cc8c29ca88742d +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnuasan.tar.gz=7d12531568c430c670d4933955b767985504a88c3da513b832b857f28e59fbf2 +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnuasan.tar.xz=ade92cb3f5ca0088d93eeac74ec29b8532d285a730eb87350086e9cda4f7d60b +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnumsan.tar.gz=6280a11a0e153f98dfbd4892a90ee60f086c812ded8177e21e6fa3fd9f733441 +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnumsan.tar.xz=51792543085e26437577f4c3cabd226571c9f9d5b85d142a4d7ec19b992c4bf2 +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnutsan.tar.gz=85bdd806ddf39fe35df389895b3c531df21b26dd60945f2b92a3f7f7627dfe77 +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnutsan.tar.xz=076be1c27da9f50254ed8ae748c0ebe01a21af0c47920e035ee25121327cc607 +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=e0c5acc46aac350663adc8b6b73e097299a94574785baf5487181b321979b34a +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=f9470afacdce7db3d057bf13af6b6e45574b4c6cd8a1c75adbce2732ab61515e +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=f207346769473385b1efd771abcc0e2a95d73dc93e5039a0ce4cc329daf1e83b +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=25d752aed1d312ab614cd065826c688440aaca70cc7e67c4578ca82398f951f6 +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=fc511b73ed5c0da3303efb8b5e01d6e4465cf028543a9ebcd5b1ba273e3e5104 +dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=9ada977527a2fb632cfecd9414226664b47514adc988fbb0e3cb86cf1f81f81b +dist/2026-08-30/rust-std-beta-x86_64-unknown-netbsd.tar.gz=9268af9ae7ed919e0955a1162376ed84c65906304f3dcc64762a6f8dc764031c +dist/2026-08-30/rust-std-beta-x86_64-unknown-netbsd.tar.xz=49f7e2808660320fcde2f1ffe23d4e5d44f26c9d08124a97ffbd715d24c0d21e +dist/2026-08-30/rust-std-beta-x86_64-unknown-none.tar.gz=7f2dea659c4d5ff038118307cd2fc6286a95a6dc12a85686bd958806e3d49647 +dist/2026-08-30/rust-std-beta-x86_64-unknown-none.tar.xz=e96d78c8025876bdb25613fb81cf27b54803ab0a809d761909fc56e626153e1c +dist/2026-08-30/rust-std-beta-x86_64-unknown-redox.tar.gz=7874b37200d60c3986588f6178a623817acbcb66bbbfb9b81c9e4ae348cbc0bf +dist/2026-08-30/rust-std-beta-x86_64-unknown-redox.tar.xz=a6d454739b2fcd6728a7c19afc6e95e6ce2dfb02a569619a071b02b3fb7a6e33 +dist/2026-08-30/rust-std-beta-x86_64-unknown-uefi.tar.gz=6b4c4371089aa7d2be7dea927dfc623c9958998cf02952b8455dc4f05c466ba4 +dist/2026-08-30/rust-std-beta-x86_64-unknown-uefi.tar.xz=1dd395befcbdd4f379a2f78e498c15113e07934b46dfede8dc1075276d7c7cf2 +dist/2026-08-30/cargo-beta-aarch64-apple-darwin.tar.gz=9e761054280cc664f95355b3ff7c9828d6b98fcb63c6cc65b3ef07f78fa98a2c +dist/2026-08-30/cargo-beta-aarch64-apple-darwin.tar.xz=473eed6c6004b83a306c4fcf34002560c292050a6c25247a8c1cbe3ad05b93b4 +dist/2026-08-30/cargo-beta-aarch64-pc-windows-gnullvm.tar.gz=079698fcd5ee509d6b733e7119a8023d9b5e538ea526b64fb286cfdbb85fe16d +dist/2026-08-30/cargo-beta-aarch64-pc-windows-gnullvm.tar.xz=86018bbd5e4ce4a2ed6fe33c520fbdaa1e1cb93a86cc47f8fb8a84f139fbf77b +dist/2026-08-30/cargo-beta-aarch64-pc-windows-msvc.tar.gz=136513f5d9caa1d9a982c5731f07c52ed33ffcca18cf8c76f65b15193788f4df +dist/2026-08-30/cargo-beta-aarch64-pc-windows-msvc.tar.xz=faaa5028d993cfe8ad0c86b03e8ce2718bf20e8cee68d8185ecfa39cfa3870ad +dist/2026-08-30/cargo-beta-aarch64-unknown-freebsd.tar.gz=f9c7edc721b9e36377248325ec7944df39cf2ca005fb02a91a4994d717ad4783 +dist/2026-08-30/cargo-beta-aarch64-unknown-freebsd.tar.xz=581acbb17a497d6b76b99cc94833a33d72e104f2efff7d408d69550f912da462 +dist/2026-08-30/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=33647f90516de973cbfda8c553497ae5721e4412c4aecbdba1af4ff414093ca6 +dist/2026-08-30/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=9741da1d26464d27e5566220ac240ece0c94d95e0458e8e945c1d29cc198746b +dist/2026-08-30/cargo-beta-aarch64-unknown-linux-musl.tar.gz=92e567bb8a7eeee6e001bd47b39263473d69a6591a9e64f9f48736a3ee631669 +dist/2026-08-30/cargo-beta-aarch64-unknown-linux-musl.tar.xz=69bd4e038b62ca7a94d85b3673286fe9a2ff57d4fd750e35cc0f4edf2e74b701 +dist/2026-08-30/cargo-beta-aarch64-unknown-linux-ohos.tar.gz=58627d33a59fcd84a33e71e121f267e675d78a181fdabd8bfd645b0c21e36c33 +dist/2026-08-30/cargo-beta-aarch64-unknown-linux-ohos.tar.xz=4dd725fb1d9eb9f7f1434edf563642dd4357b4622b7990ca835c62db9b26bf55 +dist/2026-08-30/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=86ca22788c633215cdd0ca96986136504dc7525c1d6d12da5d2d37944986ea21 +dist/2026-08-30/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=99f26d926f354f3a72fb422bcd8a2f0b8379ac727d5c3f16b57b433fe9f5d656 +dist/2026-08-30/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=681839287ba9bcccbff125e21f9b1381915ebf1e2748d558cf4ff1dcace861fe +dist/2026-08-30/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=cf1e4cb9ebb5c86ad2090a9f08862fc85ee00f0c0a4dce50df4e688112e2b3d7 +dist/2026-08-30/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=9cd65395b781a22ec66e2e49e78d5a972360c93b5da7ed22b837635c68899a0f +dist/2026-08-30/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=b3c6b3a99f537303f2419cf7379cbdbacb899a956ad0653b0726d558f893f481 +dist/2026-08-30/cargo-beta-i686-pc-windows-gnu.tar.gz=055b916329d7848a521f63cbe6c373a4ad94a36e9c2cefe155283bb67b2c655a +dist/2026-08-30/cargo-beta-i686-pc-windows-gnu.tar.xz=728142c61e80ed2884a41446fb5ef9784ae66c6a5ae01d34548ad3722bf17547 +dist/2026-08-30/cargo-beta-i686-pc-windows-msvc.tar.gz=902d87163289b5f7c8876d79b4bcf6a524f445007afb41478c3d446c47e8efd9 +dist/2026-08-30/cargo-beta-i686-pc-windows-msvc.tar.xz=f8c2377f283109ba8db1d15925ebf549a0297d33245d67efc2f178fbbc13a766 +dist/2026-08-30/cargo-beta-i686-unknown-linux-gnu.tar.gz=acb2edc9a1e93476848d22725017ca6c80906875cb3c3cd5f23972a9a96c109d +dist/2026-08-30/cargo-beta-i686-unknown-linux-gnu.tar.xz=6600fd8770b01333c808210c5fe794cac10f302e4d256d1c76d1ad3b86b2c63c +dist/2026-08-30/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=98b4d2d3c9684c4477cbab01edad84970f9bbef0032249800f48cb4aa6259eae +dist/2026-08-30/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=3ab812af126bc73f9da76ed94436b856b3a5b778a0594773217ede933c136e89 +dist/2026-08-30/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=d5058dc322f0f947bd5b8ac8644df85ff760797283d4cd62a08c6137fb1b31b8 +dist/2026-08-30/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=34dfe36b152df195bf161ebf151e7166096b8cf9581b8972b49b17cd9be6f101 +dist/2026-08-30/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=7402338613366b038279a45a2390a403fd7479cca7e38fae1614e3356b1ed17b +dist/2026-08-30/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=6637409067ce9667b02142a3866bacac5b378a7d3f4c1198ad63b8dd44e13683 +dist/2026-08-30/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=bef6d62721d7cb4a5e8d16b4ce8dd0b64100991ff86e4228ccfd2baef6bc1d13 +dist/2026-08-30/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=ab6ebfc224a8b5732b009ea5fcd082f6765ba92c1912b4507ad6b7020d366f31 +dist/2026-08-30/cargo-beta-powerpc64-unknown-linux-musl.tar.gz=07db627041a31120cb4c416ba8d8cd9497e496830568f06770aaf3bd2388cf89 +dist/2026-08-30/cargo-beta-powerpc64-unknown-linux-musl.tar.xz=c5438cb0e1df9c6dbfcb31d9b578d8421dffea54ce84fbb16619b57eaac22fac +dist/2026-08-30/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=9ec047abc63b03ade31cad80b0e3c247855ebbdeb42081f0e7d1cd0fa2d6a591 +dist/2026-08-30/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=59850205528f58ec1df682519b33d149dacfd34c6820188344166be741b6496a +dist/2026-08-30/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=b51d3d280d5c7db88697f5cf62a16bdf87debc3a36e169e1613b19c787684460 +dist/2026-08-30/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=42fed8ea76cdef7ef55cea3f5afa7b65bbbd0f64a7dd91c5128b4d0a459a1d61 +dist/2026-08-30/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=674a081bb7e9264aadd9877cd56e354023bacbd3d7645f47b5e56fd929b2893c +dist/2026-08-30/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=cad87b60d098bdc83f26039d2a7b01cecd72b454414423786e69d7830fbc2f11 +dist/2026-08-30/cargo-beta-riscv64gc-unknown-linux-musl.tar.gz=0020a7c5575ac0aed412219257ac4ed7af155ce4696382ee4a5b20113331b8e5 +dist/2026-08-30/cargo-beta-riscv64gc-unknown-linux-musl.tar.xz=ceb3b28ee22ad4b7e893583774680f5be45be9376fb56d23d48ac6201bc972e8 +dist/2026-08-30/cargo-beta-s390x-unknown-linux-gnu.tar.gz=59836d761c03a77477236199be5b0bd06d2ba5ab1d0f39176e1d7c8434eb45e2 +dist/2026-08-30/cargo-beta-s390x-unknown-linux-gnu.tar.xz=38dd22d489aecdf755bb667b4e79d2cb2ec8b6c2710d01686d600f1273e8d59e +dist/2026-08-30/cargo-beta-sparcv9-sun-solaris.tar.gz=c9df6b1cf54638837c2ab060d81241b1cc9c0fe415927c3df281a6c27a46fa5b +dist/2026-08-30/cargo-beta-sparcv9-sun-solaris.tar.xz=e1da5f2fc4dfa042c2819cc20ec8a7fe223aec9a3632899d83965b69c0742048 +dist/2026-08-30/cargo-beta-x86_64-apple-darwin.tar.gz=466f22d638541dfd8a067ae8b01d1d5ba3fe53e77191da3f3f676d4a90d88cca +dist/2026-08-30/cargo-beta-x86_64-apple-darwin.tar.xz=239a1222ddc7c24648f902799dfd258ae334a37f3f58675e94a62879fa51d302 +dist/2026-08-30/cargo-beta-x86_64-pc-solaris.tar.gz=7623f134d775dc42c669f1f23dbd22415036927efe13b183edfc303003d714e1 +dist/2026-08-30/cargo-beta-x86_64-pc-solaris.tar.xz=126bd01ff0c9bb942e211a8fdf6712199979c35d1b6b2b19bbd2a21fbbea966d +dist/2026-08-30/cargo-beta-x86_64-pc-windows-gnu.tar.gz=bfb4fedc712bceeaf74cf23245fd3efdd68728d77db8e04a32ddc329995bdd97 +dist/2026-08-30/cargo-beta-x86_64-pc-windows-gnu.tar.xz=b703ae1050c9a7ebb6b6ddb0523c59b2e5b38466716346e85e7c63c26588927b +dist/2026-08-30/cargo-beta-x86_64-pc-windows-gnullvm.tar.gz=562f4d368d2d854ac580e07738411afb563373e247514e944bcd98f9967319ae +dist/2026-08-30/cargo-beta-x86_64-pc-windows-gnullvm.tar.xz=f165e4bfef2e6bafeb4825961c0fc41ac7ac23d7457feb444dfb8c1e1e0d012c +dist/2026-08-30/cargo-beta-x86_64-pc-windows-msvc.tar.gz=9a3c7ad87e5f3b98d02167c449437c0aba21d174a6ecfa2f0e4817b8c93ad91c +dist/2026-08-30/cargo-beta-x86_64-pc-windows-msvc.tar.xz=831c421d5c5d187047920ccf7ce76300f4d9e3a36960e347d179f31b08f9b49f +dist/2026-08-30/cargo-beta-x86_64-unknown-freebsd.tar.gz=3dd99be35b587a0334d71bc92dfe15e06ff0a052d66782a2425895684dcfe669 +dist/2026-08-30/cargo-beta-x86_64-unknown-freebsd.tar.xz=e4220bc3ccfb034fb1b40d506c9a9637153c943e0a0f9dea4bd56065df2698cd +dist/2026-08-30/cargo-beta-x86_64-unknown-illumos.tar.gz=98de23e890441294de89857063f2810f81df29c02cb9da755793f78eaa8ca8fd +dist/2026-08-30/cargo-beta-x86_64-unknown-illumos.tar.xz=9dbc424c16bed26b8d2ea662c41f156ef14636cbc2006c36af151ea68c932551 +dist/2026-08-30/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=2d2cdc1af3afe2816da895ed1ef0f27a31ee31f938a9385864c0c8e1385a2ec9 +dist/2026-08-30/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=62bcbf31738317455017be5dadb592ce9a6b937bf61303c30c56d4f6d8f1ac3c +dist/2026-08-30/cargo-beta-x86_64-unknown-linux-musl.tar.gz=32247e6fb942d39444cab2b35ce2b64a44c84b2fa934acb781ea9c682f60f14b +dist/2026-08-30/cargo-beta-x86_64-unknown-linux-musl.tar.xz=8c155d690af2600d9a4dcf00d62b6a5f52524e999d25d02eb873a6ab28f373e5 +dist/2026-08-30/cargo-beta-x86_64-unknown-netbsd.tar.gz=c588c5407c06a36da78587b6ee7baddc72b45ecb6fac9290e333fd0eadab1152 +dist/2026-08-30/cargo-beta-x86_64-unknown-netbsd.tar.xz=09c84a0118c5d533b442f39c33265a04abb72133c94f662654095f984f0e85e8 +dist/2026-08-30/clippy-beta-aarch64-apple-darwin.tar.gz=cc03b3970d8e2f5b055fab29f46e9120fdd520f6db45a6213a699a9a4367997e +dist/2026-08-30/clippy-beta-aarch64-apple-darwin.tar.xz=7c6c789f64225fdc45aad2c8eb596aa679e855abb5c4d79573a458f2da7309ac +dist/2026-08-30/clippy-beta-aarch64-pc-windows-gnullvm.tar.gz=b404caee9abf7e945985ccd5379f0e2f41c3b7dbe6e999d722b55fdf9d08c6ac +dist/2026-08-30/clippy-beta-aarch64-pc-windows-gnullvm.tar.xz=36c9f84de6b071aa5f1c0bae438ae3ef132c4add9d35ee5a69e8a754501b568e +dist/2026-08-30/clippy-beta-aarch64-pc-windows-msvc.tar.gz=bebf9f956d1974779ab06d7bdd25a7ea053811523ba2ff4ae18267bad7c80494 +dist/2026-08-30/clippy-beta-aarch64-pc-windows-msvc.tar.xz=fb4274e7618fe49031cb6f4021a0e7dc4bf1ee8900eb45cef118600c8137ad4f +dist/2026-08-30/clippy-beta-aarch64-unknown-freebsd.tar.gz=79e922d0c5bbd69c86d7a459552e47511481eb5faee8a7a2eb893ccc5f7b6788 +dist/2026-08-30/clippy-beta-aarch64-unknown-freebsd.tar.xz=ed65f1ac492dafebfae2ee367135e1f56f57af9b2d284739fa57b18793e7386a +dist/2026-08-30/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=d4aa6c22318d181ff4ef17f0ef2b8aea6641efac232f8a074cf4948e76c68802 +dist/2026-08-30/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=1d679549e6cb70f5acac81d255aabfbb6afef0c94973747e791f27e1097dfb8a +dist/2026-08-30/clippy-beta-aarch64-unknown-linux-musl.tar.gz=0fecf358ff0e7725ec6df42b194a1912b91b358aad683fc48d36b1768c88042f +dist/2026-08-30/clippy-beta-aarch64-unknown-linux-musl.tar.xz=443cb8a078231aa3bba0b8082cd5f20ce36caee120d1060e8f3cf73fd05d8907 +dist/2026-08-30/clippy-beta-aarch64-unknown-linux-ohos.tar.gz=f8b624585864c6bd679db4d505b8c84d46682b8cccb29fcd5bc5fcc74c7a79e7 +dist/2026-08-30/clippy-beta-aarch64-unknown-linux-ohos.tar.xz=8e09d294c73ff186be62d2db49a06240b6d66c674c81c2471646222a5d607e01 +dist/2026-08-30/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=106efc64c2e21abc149264e3a98c4b836c1430d0240f3489d5605a2cc17760fb +dist/2026-08-30/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=b45eaa6f6586aca7e622c5ad60ae9ec92ddd935dff5d6c94ba3a78e0dc6dc304 +dist/2026-08-30/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=8bb3d211d9d17c5acb2867cd154f3dcecdbfb36d723c05f35d91f2e33ea00067 +dist/2026-08-30/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=08c78ecc4b5489c5480fe6d3832298686f782f9e45bb265946b9bb1176733f54 +dist/2026-08-30/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=1875b1f3c267c634cd48933c98891a53b350f7142462cb56bfc6513326024c89 +dist/2026-08-30/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=a647ca6600707b40a1e97f7fd0e39bf43c863ea60224eb28beee0622f74253e3 +dist/2026-08-30/clippy-beta-i686-pc-windows-gnu.tar.gz=772d98712f108d6d7eb7730e26ec04e66a972daf3ac5352c30160e20c1861ba6 +dist/2026-08-30/clippy-beta-i686-pc-windows-gnu.tar.xz=d75cdb626c3104552b122e79d2ed07bad9ec04f084f58bde332d029feb3ae90d +dist/2026-08-30/clippy-beta-i686-pc-windows-msvc.tar.gz=e7ecdd93739741d769a1fb4ea33b9dd3c935008d7ad5e773d3673d5ea7dbd6d6 +dist/2026-08-30/clippy-beta-i686-pc-windows-msvc.tar.xz=8b1223c943d378e201e83d61298527e2d7307f96ce609c6e1a5483f086490bec +dist/2026-08-30/clippy-beta-i686-unknown-linux-gnu.tar.gz=f326afa8e228964581df0c4a0096eb33fc132df0254b2648f43f6589466e72bd +dist/2026-08-30/clippy-beta-i686-unknown-linux-gnu.tar.xz=7e868c12873c5e451ebdfe67e4474538a9d3f46d5dde8ad4139c8f5056a44685 +dist/2026-08-30/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=e185f345c34e54bc100b1df955c047b53db30b9b3b054a2cf5a264f0e3ae2405 +dist/2026-08-30/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=270c4f7d7763180bfb8a7dea1d97259398c9b7c6560fdd3b58192748ffb40cf2 +dist/2026-08-30/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=22d484c3ae2ade651e12ce943780b51da3b0dd6bf04c6f8403540cc7f382ced0 +dist/2026-08-30/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=a669d05d6efc4e77f05b417d00272f2a0221e05b37f921b9e0f9769a8b48830e +dist/2026-08-30/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=3d782e904a64856dcae5de5d2be509f2ccc3109e9067ddd540bc8e1049ea3ceb +dist/2026-08-30/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=dd867a9fca45df5ee0d3ef602802f8accaf9fcc1ab1fe52b74ea72e03b91d67f +dist/2026-08-30/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=a890aa398977d62b10513350e2c918fb41ffa76a2733b2f08ec829f15b8dfd0d +dist/2026-08-30/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=c8ae48e109ae2f4daf3c878056641acacc457618afe42c9af53eaa4bf9a4faff +dist/2026-08-30/clippy-beta-powerpc64-unknown-linux-musl.tar.gz=010d6114089273e267645340437d74b962c7f16ad21914b689100241e1e5879d +dist/2026-08-30/clippy-beta-powerpc64-unknown-linux-musl.tar.xz=1ff705f8d502081d85e8f85a177b4d00a3f102475c6148f7609040efe8f95cf0 +dist/2026-08-30/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=226cdb2a14e6f7ac8962326d6f0a4459a99d5f43ed6516f296da74a4c96504e5 +dist/2026-08-30/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=6f0d5341554b0b12be7138962ad1f02cf534b197923f791e8489e09c2ec0fa31 +dist/2026-08-30/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=aa41e1b12199dbe2597c1614908911bc936b77e4697d6f47a73e99b3fc6d3cbb +dist/2026-08-30/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=f0084a572996014050b886ea7defe6c6f3dbb8055c840c9f3e0f09474f1cd87e +dist/2026-08-30/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=35d0c03ff88bbc60059f1014c65f8803a5e649fcef0ffecf90c73db0b5e29d04 +dist/2026-08-30/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=f2233e50c2c976941b30f41859494c3b47a4a92022b50f924eb3aafbb10ad1c6 +dist/2026-08-30/clippy-beta-riscv64gc-unknown-linux-musl.tar.gz=8f34275dea87439be7c820cf5c239168c5641711e439afe873615ebc26e92f20 +dist/2026-08-30/clippy-beta-riscv64gc-unknown-linux-musl.tar.xz=7346c56c1ff8cadbb633d0890dfea12918344f035075a5ade3fb44869da7ce26 +dist/2026-08-30/clippy-beta-s390x-unknown-linux-gnu.tar.gz=064c99e94f0dd2da50e8445cba0f6bd3b6de9a78f860fde838097f26f93c0a86 +dist/2026-08-30/clippy-beta-s390x-unknown-linux-gnu.tar.xz=b5237ae854270214b81270f1a6dcd26fab19470b98450b8503a1647d83f19d66 +dist/2026-08-30/clippy-beta-sparcv9-sun-solaris.tar.gz=e8cb900135fcaecc87565e6279f3b50db957370b73f7bdaee39401bb2236ec93 +dist/2026-08-30/clippy-beta-sparcv9-sun-solaris.tar.xz=a1315c1d6b3ab19a6351527f07d62bc375d937571af49f1130b030440f96ad74 +dist/2026-08-30/clippy-beta-x86_64-apple-darwin.tar.gz=4adb22b7d502339fa505fe7ecf18167fd7a054e15211d28f78d7f27c05fcfb4c +dist/2026-08-30/clippy-beta-x86_64-apple-darwin.tar.xz=0e9c5bd310a8c6d797cc741a3368c4e18ebdd138fb0035bcec94ca3563fee966 +dist/2026-08-30/clippy-beta-x86_64-pc-solaris.tar.gz=ec8ea5558cd47e0324ab46fc8d7f06b55e3a5b015e1b06f7d8372ef63846e2e5 +dist/2026-08-30/clippy-beta-x86_64-pc-solaris.tar.xz=2ce6978bb89c20fd4d92d9a513c60ed8a4ecf243d68e9ed5e76a06f46374725c +dist/2026-08-30/clippy-beta-x86_64-pc-windows-gnu.tar.gz=269d4722bf8604755727de19c3e92932976797ee07a382a4241d598e11f1dcc3 +dist/2026-08-30/clippy-beta-x86_64-pc-windows-gnu.tar.xz=bd37185b9ea6c75df3fa873bb7bb961ea48cd7eb2e1e537df78fa23560a4e542 +dist/2026-08-30/clippy-beta-x86_64-pc-windows-gnullvm.tar.gz=7a84636be94207fe6bad2a162bb9f412944f07d87e65aaea8defa01500be420d +dist/2026-08-30/clippy-beta-x86_64-pc-windows-gnullvm.tar.xz=6f3cd9590fde49d3d32473d7363b8bd9e1298adb87dbef2fc8ba2aa6565cf7f8 +dist/2026-08-30/clippy-beta-x86_64-pc-windows-msvc.tar.gz=9d33b21d67155a006f8ba2de17892812519ce9ddbb6531656b314c710363f7d1 +dist/2026-08-30/clippy-beta-x86_64-pc-windows-msvc.tar.xz=a6805eaf9f9d0d5d9f98d6fafb4b4e96accfb2676acca907ee704f84745c5768 +dist/2026-08-30/clippy-beta-x86_64-unknown-freebsd.tar.gz=b8e66bc833089b1b23cd0e73c2e1b3409864d2b00c7ba533378b45eba07a8dc9 +dist/2026-08-30/clippy-beta-x86_64-unknown-freebsd.tar.xz=593633c48f833329e86613601cbb4db25071eb19b33a4561f7104c0cba86f03a +dist/2026-08-30/clippy-beta-x86_64-unknown-illumos.tar.gz=dbfa333d2cf958b0d39983bdf3fd2d55623903d82f34d70d06ad31561f51cf97 +dist/2026-08-30/clippy-beta-x86_64-unknown-illumos.tar.xz=53a0ec434ba0664dcd967d02a13daab11c23eb294b3e80befb80667f8983c586 +dist/2026-08-30/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=17a88086e382454d70bf08e33149b8e0ba97a34500b9f56dbbfd9ff4c3fc535d +dist/2026-08-30/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=b0237d0782a9b8938769e85dbbcf1a6eec91554f665b90acf00a60f4dd0714bf +dist/2026-08-30/clippy-beta-x86_64-unknown-linux-musl.tar.gz=2d7ff9aa37dbcfdec585dea69555c973430b7e6f4f6b55e450cb34c05b59baef +dist/2026-08-30/clippy-beta-x86_64-unknown-linux-musl.tar.xz=9ae39943b49d89ef53153b2921fe7dd6ed244acd5e39297ba7cf108c38ec644b +dist/2026-08-30/clippy-beta-x86_64-unknown-netbsd.tar.gz=7c8c9387e3f75a917dd721cf96a118cd8924baae1b476e9da545aa6c4cf06609 +dist/2026-08-30/clippy-beta-x86_64-unknown-netbsd.tar.xz=0d85f1338a69ad620c923bec29c3fcad6225f957578f0a41a11568c154e091aa +dist/2026-08-30/rust-beta-aarch64-pc-windows-gnullvm.msi=99a2ea82e19f436cdf4dec0f0aaf315c16a3229fb6d9b103ee9d1a2c06b74090 +dist/2026-08-30/rust-beta-aarch64-pc-windows-msvc.msi=c0a27c16075e29239e68b31d76946a41a452acce1140c1e509a189c2e3f56eff +dist/2026-08-30/rust-beta-i686-pc-windows-gnu.msi=8f742fd4920a3fcf5d41dc113f885e441f8681d83a745a5b12195c2782a4c93b +dist/2026-08-30/rust-beta-i686-pc-windows-msvc.msi=513fb7fe5d4289ddbb58260863ba3821d2cb2a3baabc0bea1a65ef2885c413ec +dist/2026-08-30/rust-beta-x86_64-pc-windows-gnu.msi=2d9f279983d1a50913e7777de880899143190413292801266b95ac2ed69a4e4e +dist/2026-08-30/rust-beta-x86_64-pc-windows-gnullvm.msi=5bf8e7568a27395a4b879dd6534c141a92cdf12536d1201a175d84453963699b +dist/2026-08-30/rust-beta-x86_64-pc-windows-msvc.msi=23463fbf570caf314427b3ff8e666a2d9b3cfdf7947aced459187eb59c645e48 +dist/2026-08-30/rust-beta-aarch64-apple-darwin.pkg=e933472ceac42d94982728bedda2976bc77da11805a236cd93cab0c159dafe5e +dist/2026-08-30/rust-beta-x86_64-apple-darwin.pkg=bb9d97c74eb28bae220ed548e46b91c478d66301801c51d4d170d45989d24cc1 +dist/2026-08-30/rustc-beta-src.tar.gz=baa6964c75882e0393efbed2f19e8303b46101336adfdf44bede282dae15ef0d +dist/2026-08-30/rustc-beta-src.tar.xz=f835b92620f3802afdaa41fa49de6e253c9db0de0234070833011ce65c14d0e2 +dist/2026-08-30/rustfmt-nightly-aarch64-apple-darwin.tar.gz=22d6733e4325fe6fa25399b651e77cd5ed1a7f370f7558aaa08e8b6447f55264 +dist/2026-08-30/rustfmt-nightly-aarch64-apple-darwin.tar.xz=fcc49f0698c09f8ff89ca044d0426dad2399da253d287c3aaabebf103b4a2820 +dist/2026-08-30/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.gz=34a0e1f6d068d30cca9099c44736657de307ea3041970fde751aeda3781d02f7 +dist/2026-08-30/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.xz=8f7955c05e2a5324fba961df617ca2d70d473565cd3389fcd52814e9cd5c4f65 +dist/2026-08-30/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=7df7e3f128e4d4f88a5777e9e736fce117f5f47ef8cb505713aba9db09b8cecc +dist/2026-08-30/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=094323c8a19c6840d13d9e3a1668c94dc249ff0c720634da1fef8cf844cded71 +dist/2026-08-30/rustfmt-nightly-aarch64-unknown-freebsd.tar.gz=bd932f456a46de862f1aa3fc5b936a5e364a714a6cb8b71c7cf3920f180177a0 +dist/2026-08-30/rustfmt-nightly-aarch64-unknown-freebsd.tar.xz=4c14e353f8f5982ba3b3828578e412f433ca3f16e94c9aa0f6efdf2949b53215 +dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=efb14d13c092a4dfd1d2229aaf850cb2e6c56bac9c31ec322e22f515050567da +dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=7df63718528c050a0e306ab08979ca787b6f0522a442d34355cf683f3bb259f0 +dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=b0a231d0eb6bb006bfc144a954be07ed9886202967843b0e8475b19429902884 +dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=b98a8ba107231b4d8832d6f1cb679661e9ee0faf13c81dc3eaa576853580582c +dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-ohos.tar.gz=dec01a69341b8d512eb17ec28687b4ee43174de63e31a90b91e99b9eaf17e345 +dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-ohos.tar.xz=e598a9559c169794bec2443e7842e62728e09fcaa6614b1a3f5ebd6803f0ef6a +dist/2026-08-30/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=18a5a8ca79e449f7daf52f534cd2ab137e33204280ac7da35e0bd31f6ba2674e +dist/2026-08-30/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=00e6e3d4d555ee786545b5f0a542d7b5bb9260781a80e4598d50bdf856457a4a +dist/2026-08-30/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=421735da37fcf7a85c2bccb27b13c15105f98a95333734c1d383e18b7a01842c +dist/2026-08-30/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=a3936b0c6a67da7180c10554dbe6427beaf05480c40b3a57cc07082085987cc1 +dist/2026-08-30/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=817768d8aae4d3d09b952631982051eba84b889e87367c2d740a14e35261fb4f +dist/2026-08-30/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=5d905fdbcc0d3d2f5949c0e32980172fa8216a51974945248e293f8c81b58203 +dist/2026-08-30/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=e2cae9d3e6b6c6cf72bf0e12510358984adb5f5279f49af8f4a29869614f0a84 +dist/2026-08-30/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=bfb5472037dd5d1031384c70d58bf841ff4a9e33716b55d8384c47d27a31ac04 +dist/2026-08-30/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=b18fa3d4a5469b7736655c842af84ad44a07fbd6146669c6f2b5f5c3f26a4e33 +dist/2026-08-30/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=c7978ac60291efc21bc77c2aed4d14c0bbfd6dbccb461f0499202fe8b8dd0818 +dist/2026-08-30/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=e1e69785fadaa294f92d7f5e42b046a47c4b508a806804048c3c2b1cfcda25d1 +dist/2026-08-30/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=c6371931d1bbc56f94f17d55ef0e8a756388606599a6f8828b1269504b57f0ac +dist/2026-08-30/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=e2763a910eb0305fbad6200fdb70e21c80f6ce61a29c9ef6cfdd134e54fa149e +dist/2026-08-30/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=b8ff26519a2b6087969497e02e1a958b283b2dbd5741c5f9a531bfadb7f55b4e +dist/2026-08-30/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=f83eba99f2c4ca3c8e72debd3abfc81c4e8e12b78f33030a2ec0bca467ff1026 +dist/2026-08-30/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=9da6df6e5b98e59dad134fa7eb6fc74cdd7590799e5d77b885675d3301cb5ae5 +dist/2026-08-30/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=ab48c3b5e6a1c920d2776ada7f2c7a262c6456c70c4051c55f24067768f36011 +dist/2026-08-30/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=d6a6ff842d3004c14a39349c62453b5279085bcf44f2c3f101bba074249b6393 +dist/2026-08-30/rustfmt-nightly-powerpc64-unknown-linux-musl.tar.gz=7790a116d7598a29c083e8defa140b3c69dff2fa8632abe16c0814e3fdceb771 +dist/2026-08-30/rustfmt-nightly-powerpc64-unknown-linux-musl.tar.xz=090ff92dbd36a9d051e48545672099c40917f5cc781fad0075d1db73bacc9b6b +dist/2026-08-30/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=6a448b720e8b8904a7f6b160891dc711165b043aa2f2700f1001220841da7383 +dist/2026-08-30/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=47850b2456b8f28493268987e10ee2197f6bc49517b9338c469346e42c4ea524 +dist/2026-08-30/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=51fa8c6d2e9144b5086ebcd91580a7b2338e42294a0db614c2a5b40c2817f074 +dist/2026-08-30/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=09af68ab10528ac45be29d2d7671a5cbbd0c508d842c811448d1b1a0818e4ebe +dist/2026-08-30/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=4ba0481a7d6111f1197c44f9475ccfe814a32cd13ff218b7a6f96fa6b188dc07 +dist/2026-08-30/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=cb078f0a92905a6ce410866e2c0f93ecdc12fc2b17716e8ab503531b72cd2f41 +dist/2026-08-30/rustfmt-nightly-riscv64gc-unknown-linux-musl.tar.gz=5c8f989fc890a8d40b88d03002819dba392def655ff4a297eae83e24635599be +dist/2026-08-30/rustfmt-nightly-riscv64gc-unknown-linux-musl.tar.xz=ac6a2d15f43100e71a401f334eadc59d76e554fc7e2e4c67870c24f05c7ac682 +dist/2026-08-30/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=78f43dc32a140e6b84c5b50e319b5d779d8d3a6a63172df5b0a7df984cda2919 +dist/2026-08-30/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=cdc738d4e7db3489ec4be89db19fb6beeefedc09f0f99bfc3f4177e5a0e29e39 +dist/2026-08-30/rustfmt-nightly-sparcv9-sun-solaris.tar.gz=8b04309e8d8ed92f52ee9656b0c3b694681c9c867bbadb781c14df8d2f25a189 +dist/2026-08-30/rustfmt-nightly-sparcv9-sun-solaris.tar.xz=fa880983d380d71b52468551aeea00502c04a1c84c1976b82ad137031b63e61e +dist/2026-08-30/rustfmt-nightly-x86_64-apple-darwin.tar.gz=0faa8f222a300d58a8d815a49625202da2c93b89d655de9f8105fac8fa3b49c2 +dist/2026-08-30/rustfmt-nightly-x86_64-apple-darwin.tar.xz=860418646c51c8a4309b5f64700e9cddbaad55edd33776bce10341d069a4842b +dist/2026-08-30/rustfmt-nightly-x86_64-pc-solaris.tar.gz=70dd11166440c56c5d39ad393f22904b0d043c4e128ceed9b35276b1f7c88814 +dist/2026-08-30/rustfmt-nightly-x86_64-pc-solaris.tar.xz=0c0224c46c41018eee3fd6373a3a50869faca604acf5985627a43d381bd023bc +dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=e3ae658cd8daf76fba66422c5b63d335a73c6d1abd0b0f6b88c385467779f876 +dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=372750b8dca20904cc7716f6c999a581ecbf67537bbc1a340226cc4d1cf5f01f +dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.gz=3edebbe5ca7cc0e9cdac3dbd715caea022c890f2e16dc0798f8517c324dccc8b +dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.xz=bb6cb837ef4e0355b946a9e8af2d8a4e9a89e06f68f6a0f92adfdf56eef1d583 +dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=7b5a4c70a3223e4987e216f9853833c87d347c5e4daf6328eda4f2e434e3dcc8 +dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=4040814b80224dd9ee4ad051a491c5c7cb345ed41c2bce1070c13faf785cffb9 +dist/2026-08-30/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=529dcbadb35869dd2dd39e4b81929dcd5fc74d983e5544b61e66a663dfc40fda +dist/2026-08-30/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=20c86d4a327b5b227dddd1d9a900f5314f25728b5f1cbbf970d7a8bf2c8b039c +dist/2026-08-30/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=b6951008db1f2b95e35dd207bdf95040bb0bc6875a710a744d81a9769e24f91d +dist/2026-08-30/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=c502feb9fb19f971450201f5d396d9e622169884ab2fa42b14ca4685e2ec485e +dist/2026-08-30/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=76acd957f09291ee38b993aea1511d7ed4247fedeed07b90368efdd4cd216e3a +dist/2026-08-30/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=5a9b8925bfbe5c244e6f1c84ca821bad2227ec374db11f0d593830f2419742c8 +dist/2026-08-30/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=da93547e78b5b8d587e35d15df2eb789ad4f075bb82d4605b5f4abe49b7fe49d +dist/2026-08-30/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=688e31843695905b5e67b2a186fa4e509c860befc70ee533195710f784787b64 +dist/2026-08-30/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=229cd762e308882adbfaee3c50e1a32bf88a3e1c488ab9998558a90716340a45 +dist/2026-08-30/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=47e7a7cf0eebb9c62185e5506ff1aef012709b36c7433181d774b8cd1a75567c +dist/2026-08-30/rustc-nightly-aarch64-apple-darwin.tar.gz=25ffe92502f44e574a72b9493ee0b1a4e0e873c1c931f1a07aa0e478ceb170e1 +dist/2026-08-30/rustc-nightly-aarch64-apple-darwin.tar.xz=9d494a6b72761dee6ec3c0ec085d5b29838565ef45bbb67b097caf0aa4750304 +dist/2026-08-30/rustc-nightly-aarch64-pc-windows-gnullvm.tar.gz=576b8ba2a8aab889df0e673d434402c38d22efcaa4a8cd2f005c01063cd80601 +dist/2026-08-30/rustc-nightly-aarch64-pc-windows-gnullvm.tar.xz=dbd428ee786b17c9a91039a2274e01d1adf14d6af747f78c32d68a62a5752e35 +dist/2026-08-30/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=395f1fd4b0286f70d4d48d5b1aae4a8f7ceb0e0a916fdfb69cbe2c00a1cd31c6 +dist/2026-08-30/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=33fbd7251609d17dcedff1de1d6b34e5aa257411229e9e7c0066d51b3b22d23c +dist/2026-08-30/rustc-nightly-aarch64-unknown-freebsd.tar.gz=954f471480070c222a6316e1646770b6472c007b89f68ea61a713b153210b960 +dist/2026-08-30/rustc-nightly-aarch64-unknown-freebsd.tar.xz=9f19a67717d4710b3e445fbe84591da5fc5be7b6c6f07e5e5bbcf978243c4070 +dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=d1cdfc3cbcb3f131b4307b83389da6c0385f733ef6c68e569f280c1d10bc6a18 +dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=c967d3a8cf286f5197759160f90f823eb82c0dcfbdae4e43580c4e4336fee294 +dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=667e1683c157443a221f00467c927651756a593f5bec5f438b55aaadd740dd27 +dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=e4680cff6ef155809ede44b4c4a5f23ade8f920fd54e877ed93b6166010930cb +dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-ohos.tar.gz=fd6c0c4450fe0b8f586452046c80b424935c1fa83181358c70c19b25ddb0dbed +dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-ohos.tar.xz=b2c7e0cf7f1b71e141b248e62b7d10f0999f48fffcd6dc07318c3205c79ca505 +dist/2026-08-30/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=df20767bfd43a0fd4c5665ab4c0d0f0511b3356918f54b7c3074f6a1b7298aad +dist/2026-08-30/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=c43366c230813ae776aa094e3422a445b4a3d513f98ba6d7b78cb5ad2d0a2a8e +dist/2026-08-30/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=0c0c872b14aa8dc461989326b53c2692b46bc24bb8125d4f90e5b977f5db3bcc +dist/2026-08-30/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=82e0eceb946f0a69f2d766c3fe2a5467852caddff960a66c5fcf9d14fa6daf92 +dist/2026-08-30/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=4783a2cc2a99596fd187bad7f486f97018ffce918c34b4b022fd88f27053c967 +dist/2026-08-30/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=c078badef6ab76e69f0fcbe6ca76f1037cb64d67e5a1feecee898ef6aca91521 +dist/2026-08-30/rustc-nightly-i686-pc-windows-msvc.tar.gz=340b68ba0802676c99da1784b0f03eb9e3cd7f78cf40fa579f97601c07dacb24 +dist/2026-08-30/rustc-nightly-i686-pc-windows-msvc.tar.xz=ac4c0562021b4f3076b39856eb16ab288f3d16d25c557cf954ce66f389449f9e +dist/2026-08-30/rustc-nightly-i686-unknown-linux-gnu.tar.gz=5ac857921af0b1b8d290a059eeb1d510ad4cc5f450b513b26a11be67885558ee +dist/2026-08-30/rustc-nightly-i686-unknown-linux-gnu.tar.xz=a01fb1c1721998e3bffe377a15663e911bcaaf497fc2a7f1dbef06125466febd +dist/2026-08-30/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=46d1aa393ee0f736bf46cb6d8e975e66774a797a78918fc106cb1baf2115c1ee +dist/2026-08-30/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=66ea19498d78291393f20ad6313fdb2359b7a685bb358d28c498042f957b7ce9 +dist/2026-08-30/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=27e138e7e0ecff208f09780f6cb51d4447fb75b5891c2e961c3b380670bf43e2 +dist/2026-08-30/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=16bade7c4f0644f4474622591f1ae83be1c7d6ad86aa23f1cd0bc29959e41555 +dist/2026-08-30/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=44207e156b7d05f8ffd05394cd0a5f2c4cf290e8a7d4be07a95e6242be738f85 +dist/2026-08-30/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=98c9309ccd0bc473ab1c373232c0ad483ce959a9b7b31cfc0b948c0dcff4ae55 +dist/2026-08-30/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=bcaf935990ad326f9469b18514330bb219fac62773b1ca44cfd9f2639e22442e +dist/2026-08-30/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=68242588d61346c4001c4bade2daec0611f3f079fe1d1e5debf08746d8ca2217 +dist/2026-08-30/rustc-nightly-powerpc64-unknown-linux-musl.tar.gz=34e4d626d1e484c3d8bbe2be39a6324b0a02cfc60b7bf13c561e6c41eb6b3917 +dist/2026-08-30/rustc-nightly-powerpc64-unknown-linux-musl.tar.xz=8b35dd518df6b7225dc7b8da30ef9fce97181bf3781e69fbd5fca67833c54457 +dist/2026-08-30/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=66aca4805b3450a90bde12ddf6f2b9139fcab333bf4a33825d9bedf3842fccaa +dist/2026-08-30/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=6861be8d2ca2fe398e461ec1d68eb4b6e5a589b5eb39b60ca4083579a54ccc07 +dist/2026-08-30/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=7644e739c1afbe9a7be15878444e56340dbadea64f06799066e8d14c1e736ebf +dist/2026-08-30/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=fe4e05894da7fb3bff0d4cc725e0e80dc78fa55d97bbb0588ce5383fdec72407 +dist/2026-08-30/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=e59bb87d54ca41779b984fad84ad20144e4bb224ca187ca6a51ee1d15ec5bff4 +dist/2026-08-30/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=d997aa633692996dac26f68a246b3dff4a597595a08808dd965e01f05bc502b6 +dist/2026-08-30/rustc-nightly-riscv64gc-unknown-linux-musl.tar.gz=3d5692e095f9b23a05aa57b1de83fee4a6ab9ba1ba85f0d6a7a59997814f762c +dist/2026-08-30/rustc-nightly-riscv64gc-unknown-linux-musl.tar.xz=85b6a0d7e0405537ef929819b957a37723010e8cefa82c558a7d0c42e645fa59 +dist/2026-08-30/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=668c203cfeed5b0286a5928d9b98e289f0ec32fbaf21fe61534ac9bb5c9236fb +dist/2026-08-30/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=8fd2005a2f7233db1399af86d9c8b48b959b3627faa5c8a3dde1d6db67f72562 +dist/2026-08-30/rustc-nightly-sparcv9-sun-solaris.tar.gz=d8767b7abc10f45dcc53258adf4ca2c062d3f063f830791b6c475537a7009704 +dist/2026-08-30/rustc-nightly-sparcv9-sun-solaris.tar.xz=58ed2a29ed983d6dc632ea7dd68532fef902dbc44a68e2cd668323fa9676438d +dist/2026-08-30/rustc-nightly-x86_64-apple-darwin.tar.gz=27bd68fc60a35b8f56b538cfe9d3cafe156dba2b8cb25bc04d488505882157b6 +dist/2026-08-30/rustc-nightly-x86_64-apple-darwin.tar.xz=a452c953f1641c6d2ffaf59d129f38b7fa2c6f8c29882c3d82408b50e4c4c95e +dist/2026-08-30/rustc-nightly-x86_64-pc-solaris.tar.gz=c12868cc994812742945591b906f761f9a5ca0d09a809da69f3b0f7de731a707 +dist/2026-08-30/rustc-nightly-x86_64-pc-solaris.tar.xz=9974a6f3bf2b784771114ae846f7fb54746525e5dd921f4832410e40a00502b3 +dist/2026-08-30/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=6ce5a31fd706d532679c5db6bfca375fb21f34df077bd7e182f6e38cfb852561 +dist/2026-08-30/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=72cb129e77c6c8f48e82a82d894a5fdced57d74c8a7ade88589c3baf1385ef26 +dist/2026-08-30/rustc-nightly-x86_64-pc-windows-gnullvm.tar.gz=e896320dd35b2b43943a29491bacfc696d5e68c3c9a7c0a4fbab6cc57ca5afe7 +dist/2026-08-30/rustc-nightly-x86_64-pc-windows-gnullvm.tar.xz=93b8fcf4ed8aaa3a9ad1ed14086ed4bf44cc38db920f86eef0c1f42da37c9665 +dist/2026-08-30/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=5368d930648a6f04b20967d6183e53925bb930d047271b3683cf3d663d893f23 +dist/2026-08-30/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=e696551fc4f4b0573c60750826ee93113a95a4ee7361af3752e49c5a386abf69 +dist/2026-08-30/rustc-nightly-x86_64-unknown-freebsd.tar.gz=c2ef207e1ebd2c408c91a63cffd5986ae01cf265e535947d12bc43a2015eae5f +dist/2026-08-30/rustc-nightly-x86_64-unknown-freebsd.tar.xz=5025d42e80e6d377a9dba466ef3e81ab817ff6e098c2bbde4923afedf0fd7893 +dist/2026-08-30/rustc-nightly-x86_64-unknown-illumos.tar.gz=876fbafdf17e645e870d4b6afcd5465ee155e910309cc91bad10dc885d178b0a +dist/2026-08-30/rustc-nightly-x86_64-unknown-illumos.tar.xz=f380f5b0a7ec8c537b8bd53528b3a407cd69449baf0d6c513f03c2de047ba3fd +dist/2026-08-30/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=4e010b6ff2f3923b31c44cfcd74d33389dd2de01521e4f22b90c58294fa490fa +dist/2026-08-30/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=d87f9b9bc000e028ce81b49d64352c59eccc99cbf282c9c3bc834a72d9aeaff1 +dist/2026-08-30/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=2332302e83712fa814b119bea274fdb1f70494fc7e8ea6a23c88f20bac3ac6fe +dist/2026-08-30/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=2a43c8666489856bf8ce91729c2eeceb88a3d38bc6cacccc8c598373afad1247 +dist/2026-08-30/rustc-nightly-x86_64-unknown-netbsd.tar.gz=094c2005eef2f8ca0e466da77af70f7b1cc6c837e8b2e933c26d66b8bee3e06d +dist/2026-08-30/rustc-nightly-x86_64-unknown-netbsd.tar.xz=a68f04797c3ae9db0e31d9670fa9ce17efd5ca3054bdc4de06ca97b143cb59f3 +dist/2026-08-30/rust-nightly-aarch64-pc-windows-gnullvm.msi=4334c750cc57337150cf11dad2b10c5d65f1866e7f672093550322fa696d888f +dist/2026-08-30/rust-nightly-aarch64-pc-windows-msvc.msi=b2c56f022de67eb6045b1137709a5055c139d88e9fae8175b932a7da1f2fc1d7 +dist/2026-08-30/rust-nightly-i686-pc-windows-msvc.msi=bb18feb2dfdd9495289b70a6bb41584489dfe14de19961fe32fe6d249ff60c7a +dist/2026-08-30/rust-nightly-x86_64-pc-windows-gnu.msi=18d50140987657604cbf1a980b2249243afc6a734f725475a25a3f96c0edf72c +dist/2026-08-30/rust-nightly-x86_64-pc-windows-gnullvm.msi=83cb268a0ee1c120357082f9711d2a5eb05e58d433bd52dabfabfcbb31df6200 +dist/2026-08-30/rust-nightly-x86_64-pc-windows-msvc.msi=b19b6e4ef4b022f183c45ebba60ea8b6bcbcb06c60345231fc602dc1aae0ba5a +dist/2026-08-30/rust-nightly-aarch64-apple-darwin.pkg=2fa1f66fd223a57405047c498614d71fd3bf087a98063e2f652c9899d2a5960a +dist/2026-08-30/rust-nightly-x86_64-apple-darwin.pkg=20a2d983a8ef414f2c61773f056bed1d300c24e5f65252c1a0b01fc230030e28 +dist/2026-08-30/rustc-nightly-src.tar.gz=a1768b2d3627caf5f7fbdf5918fc1586180a7a2f2076403d1cb4ab11ea3eaec6 +dist/2026-08-30/rustc-nightly-src.tar.xz=b03a014a5a4f8bb1d0fb14d9f01e3a5cb9df64c4d4208463f4a6b977d2287d9e diff --git a/tests/codegen-llvm/private-const-fn-only-used-in-const-eval.rs b/tests/codegen-llvm/private-const-fn-only-used-in-const-eval.rs index 6dd20cb17c431..3382da5d9a607 100644 --- a/tests/codegen-llvm/private-const-fn-only-used-in-const-eval.rs +++ b/tests/codegen-llvm/private-const-fn-only-used-in-const-eval.rs @@ -27,7 +27,9 @@ const fn func2() {} // CHECK: define{{.*}}func2{{.*}} // `func3` isn't needed at runtime but the compiler can't tell for the reason mentioned above. -pub const POLY_CONST_1: () = if C { func3() }; +pub const POLY_CONST_1: () = if C { + func3() +}; const fn func3() {} // CHECK: define{{.*}}func3{{.*}} From 41258df4130f7c8eaab4d3177d156b1661587456 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 30 Aug 2026 16:19:50 +0200 Subject: [PATCH 09/26] Move more `rustdoc-html` tests using `--test` into the right folder --- .../doctest}/async-move-doctest.rs | 2 + .../doctest/async-move-doctest.stdout | 6 +++ .../doctest}/comment-in-doctest.rs | 2 + .../doctest/comment-in-doctest.stdout | 6 +++ .../doctest}/demo-allocator-54478.rs | 7 +++- .../doctest/demo-allocator-54478.stdout | 6 +++ .../doctest}/doc-cfg-target-feature.rs | 3 +- .../doctest/doc-cfg-target-feature.stdout | 39 +++++++++++++++++++ .../doctest}/doc-test-attr-18199.rs | 5 ++- .../doctest/doc-test-attr-18199.stdout | 6 +++ .../doctest}/edition-doctest.rs | 4 +- .../rustdoc-ui/doctest/edition-doctest.stdout | 7 ++++ .../doctest}/edition-flag.rs | 2 + tests/rustdoc-ui/doctest/edition-flag.stdout | 6 +++ .../doctest}/force-target-feature.rs | 5 ++- .../doctest/force-target-feature.stdout | 27 +++++++++++++ .../doctest}/ice-type-error-19181.rs | 3 ++ .../doctest/ice-type-error-19181.stdout | 5 +++ .../doctest}/no-run-still-checks-lints.rs | 3 +- .../doctest/no-run-still-checks-lints.stdout | 29 ++++++++++++++ .../doctest}/process-termination.rs | 4 +- .../doctest/process-termination.stdout | 8 ++++ .../doctest}/sanitizer-option.rs | 4 +- .../doctest/test-option-check-2.rs} | 5 ++- .../doctest/test-option-check-2.stdout | 8 ++++ .../doctest/test-option-check.rs} | 2 + .../doctest/test-option-check.stdout | 6 +++ .../lints/renamed-lint-still-applies.rs | 10 ----- 28 files changed, 200 insertions(+), 20 deletions(-) rename tests/{rustdoc-html/async => rustdoc-ui/doctest}/async-move-doctest.rs (77%) create mode 100644 tests/rustdoc-ui/doctest/async-move-doctest.stdout rename tests/{rustdoc-html => rustdoc-ui/doctest}/comment-in-doctest.rs (89%) create mode 100644 tests/rustdoc-ui/doctest/comment-in-doctest.stdout rename tests/{rustdoc-html => rustdoc-ui/doctest}/demo-allocator-54478.rs (93%) create mode 100644 tests/rustdoc-ui/doctest/demo-allocator-54478.stdout rename tests/{rustdoc-html/doc-cfg => rustdoc-ui/doctest}/doc-cfg-target-feature.rs (78%) create mode 100644 tests/rustdoc-ui/doctest/doc-cfg-target-feature.stdout rename tests/{rustdoc-html => rustdoc-ui/doctest}/doc-test-attr-18199.rs (74%) create mode 100644 tests/rustdoc-ui/doctest/doc-test-attr-18199.stdout rename tests/{rustdoc-html => rustdoc-ui/doctest}/edition-doctest.rs (87%) create mode 100644 tests/rustdoc-ui/doctest/edition-doctest.stdout rename tests/{rustdoc-html => rustdoc-ui/doctest}/edition-flag.rs (63%) create mode 100644 tests/rustdoc-ui/doctest/edition-flag.stdout rename tests/{rustdoc-html => rustdoc-ui/doctest}/force-target-feature.rs (64%) create mode 100644 tests/rustdoc-ui/doctest/force-target-feature.stdout rename tests/{rustdoc-html => rustdoc-ui/doctest}/ice-type-error-19181.rs (65%) create mode 100644 tests/rustdoc-ui/doctest/ice-type-error-19181.stdout rename tests/{rustdoc-html => rustdoc-ui/doctest}/no-run-still-checks-lints.rs (55%) create mode 100644 tests/rustdoc-ui/doctest/no-run-still-checks-lints.stdout rename tests/{rustdoc-html => rustdoc-ui/doctest}/process-termination.rs (80%) create mode 100644 tests/rustdoc-ui/doctest/process-termination.stdout rename tests/{rustdoc-html => rustdoc-ui/doctest}/sanitizer-option.rs (86%) rename tests/{rustdoc-html/test_option_check/test.rs => rustdoc-ui/doctest/test-option-check-2.rs} (54%) create mode 100644 tests/rustdoc-ui/doctest/test-option-check-2.stdout rename tests/{rustdoc-html/test_option_check/bar.rs => rustdoc-ui/doctest/test-option-check.rs} (65%) create mode 100644 tests/rustdoc-ui/doctest/test-option-check.stdout delete mode 100644 tests/rustdoc-ui/lints/renamed-lint-still-applies.rs diff --git a/tests/rustdoc-html/async/async-move-doctest.rs b/tests/rustdoc-ui/doctest/async-move-doctest.rs similarity index 77% rename from tests/rustdoc-html/async/async-move-doctest.rs rename to tests/rustdoc-ui/doctest/async-move-doctest.rs index e18ec353533df..f491a9a04f851 100644 --- a/tests/rustdoc-html/async/async-move-doctest.rs +++ b/tests/rustdoc-ui/doctest/async-move-doctest.rs @@ -1,5 +1,7 @@ //@ compile-flags:--test +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ edition:2018 +//@ check-pass // Prior to setting the default edition for the doctest pre-parser, // this doctest would fail due to a fatal parsing error. diff --git a/tests/rustdoc-ui/doctest/async-move-doctest.stdout b/tests/rustdoc-ui/doctest/async-move-doctest.stdout new file mode 100644 index 0000000000000..4790438d4602f --- /dev/null +++ b/tests/rustdoc-ui/doctest/async-move-doctest.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/async-move-doctest.rs - (line 10) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/comment-in-doctest.rs b/tests/rustdoc-ui/doctest/comment-in-doctest.rs similarity index 89% rename from tests/rustdoc-html/comment-in-doctest.rs rename to tests/rustdoc-ui/doctest/comment-in-doctest.rs index e580aa2bb72c6..2caec5db9c920 100644 --- a/tests/rustdoc-html/comment-in-doctest.rs +++ b/tests/rustdoc-ui/doctest/comment-in-doctest.rs @@ -1,4 +1,6 @@ //@ compile-flags:--test +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass // comments, both doc comments and regular ones, used to trick rustdoc's doctest parser into // thinking that everything after it was part of the regular program. combined with the librustc_ast diff --git a/tests/rustdoc-ui/doctest/comment-in-doctest.stdout b/tests/rustdoc-ui/doctest/comment-in-doctest.stdout new file mode 100644 index 0000000000000..5cb97c53f37fd --- /dev/null +++ b/tests/rustdoc-ui/doctest/comment-in-doctest.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/comment-in-doctest.rs - (line 12) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/demo-allocator-54478.rs b/tests/rustdoc-ui/doctest/demo-allocator-54478.rs similarity index 93% rename from tests/rustdoc-html/demo-allocator-54478.rs rename to tests/rustdoc-ui/doctest/demo-allocator-54478.rs index 80acfc0ff58a1..073d83e11120e 100644 --- a/tests/rustdoc-html/demo-allocator-54478.rs +++ b/tests/rustdoc-ui/doctest/demo-allocator-54478.rs @@ -1,4 +1,9 @@ // https://github.com/rust-lang/rust/issues/54478 + +//@ compile-flags:--test +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + #![crate_name="foo"] // Issue #54478: regression test showing that we can demonstrate @@ -15,8 +20,6 @@ // decided to change `rustdoc` to behave more like the compiler's // default setting, by leaving off `-C prefer-dynamic`. -//@ compile-flags:--test - //! This is a doc comment //! //! ```rust diff --git a/tests/rustdoc-ui/doctest/demo-allocator-54478.stdout b/tests/rustdoc-ui/doctest/demo-allocator-54478.stdout new file mode 100644 index 0000000000000..f32d9a5b7d932 --- /dev/null +++ b/tests/rustdoc-ui/doctest/demo-allocator-54478.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/demo-allocator-54478.rs - (line 25) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/doc-cfg/doc-cfg-target-feature.rs b/tests/rustdoc-ui/doctest/doc-cfg-target-feature.rs similarity index 78% rename from tests/rustdoc-html/doc-cfg/doc-cfg-target-feature.rs rename to tests/rustdoc-ui/doctest/doc-cfg-target-feature.rs index b66e86e36af8b..99a133a6829c5 100644 --- a/tests/rustdoc-html/doc-cfg/doc-cfg-target-feature.rs +++ b/tests/rustdoc-ui/doctest/doc-cfg-target-feature.rs @@ -1,6 +1,7 @@ //@ only-x86_64 +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ compile-flags:--test -//@ should-fail +//@ failure-status: 101 // #49723: rustdoc didn't add target features when extracting or running doctests diff --git a/tests/rustdoc-ui/doctest/doc-cfg-target-feature.stdout b/tests/rustdoc-ui/doctest/doc-cfg-target-feature.stdout new file mode 100644 index 0000000000000..d71b1032e60ec --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-cfg-target-feature.stdout @@ -0,0 +1,39 @@ + +running 1 test +test $DIR/doc-cfg-target-feature.rs - foo (line 14) ... FAILED + +failures: + +---- $DIR/doc-cfg-target-feature.rs - foo (line 14) stdout ---- +warning: the feature `cfg_target_feature` has been stable since 1.27.0 and no longer requires an attribute to enable + --> $DIR/doc-cfg-target-feature.rs:14:12 + | +LL | #![feature(cfg_target_feature)] + | ^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(stable_features)]` on by default + +warning: 1 warning emitted + +Test executable failed (exit status: 101). + +stderr: + +thread 'main' ($TID) panicked at $DIR/doc-cfg-target-feature.rs:7:1: +assertion failed: false +stack backtrace: + 0: __rustc::rust_begin_unwind + 1: core::panicking::panic_fmt + 2: core::panicking::panic + 3: rust_out::main::_doctest_main__home_imperio_rust_rust_tests_rustdoc_ui_doctest_doc_cfg_target_feature_rs_14_0 + 4: rust_out::main + 5: >::call_once +note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. + + + +failures: + $DIR/doc-cfg-target-feature.rs - foo (line 14) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/doc-test-attr-18199.rs b/tests/rustdoc-ui/doctest/doc-test-attr-18199.rs similarity index 74% rename from tests/rustdoc-html/doc-test-attr-18199.rs rename to tests/rustdoc-ui/doctest/doc-test-attr-18199.rs index 64016e32eeeb1..8350f244fccac 100644 --- a/tests/rustdoc-html/doc-test-attr-18199.rs +++ b/tests/rustdoc-ui/doctest/doc-test-attr-18199.rs @@ -1,6 +1,9 @@ -//@ compile-flags:--test // https://github.com/rust-lang/rust/issues/18199 +//@ compile-flags:--test +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + #![doc(test(attr(feature(staged_api))))] /// ``` diff --git a/tests/rustdoc-ui/doctest/doc-test-attr-18199.stdout b/tests/rustdoc-ui/doctest/doc-test-attr-18199.stdout new file mode 100644 index 0000000000000..a182a3b911af6 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-test-attr-18199.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/doc-test-attr-18199.rs - foo (line 9) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/edition-doctest.rs b/tests/rustdoc-ui/doctest/edition-doctest.rs similarity index 87% rename from tests/rustdoc-html/edition-doctest.rs rename to tests/rustdoc-ui/doctest/edition-doctest.rs index f43c074f806bd..066475dae7bf0 100644 --- a/tests/rustdoc-html/edition-doctest.rs +++ b/tests/rustdoc-ui/doctest/edition-doctest.rs @@ -1,4 +1,6 @@ -//@ compile-flags:--test +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass /// ```rust,edition2018 /// #![feature(try_blocks)] diff --git a/tests/rustdoc-ui/doctest/edition-doctest.stdout b/tests/rustdoc-ui/doctest/edition-doctest.stdout new file mode 100644 index 0000000000000..40d0df0575a76 --- /dev/null +++ b/tests/rustdoc-ui/doctest/edition-doctest.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/edition-doctest.rs - foo (line 24) - compile fail ... ok +test $DIR/edition-doctest.rs - foo (line 5) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/edition-flag.rs b/tests/rustdoc-ui/doctest/edition-flag.rs similarity index 63% rename from tests/rustdoc-html/edition-flag.rs rename to tests/rustdoc-ui/doctest/edition-flag.rs index c57c8d50b2357..51235634dbf4a 100644 --- a/tests/rustdoc-html/edition-flag.rs +++ b/tests/rustdoc-ui/doctest/edition-flag.rs @@ -1,5 +1,7 @@ //@ compile-flags:--test //@ edition:2018 +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass /// ```rust /// fn main() { diff --git a/tests/rustdoc-ui/doctest/edition-flag.stdout b/tests/rustdoc-ui/doctest/edition-flag.stdout new file mode 100644 index 0000000000000..4833a6dcf9adf --- /dev/null +++ b/tests/rustdoc-ui/doctest/edition-flag.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/edition-flag.rs - main (line 6) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/force-target-feature.rs b/tests/rustdoc-ui/doctest/force-target-feature.rs similarity index 64% rename from tests/rustdoc-html/force-target-feature.rs rename to tests/rustdoc-ui/doctest/force-target-feature.rs index fa71bbeea2747..c3f9798147074 100644 --- a/tests/rustdoc-html/force-target-feature.rs +++ b/tests/rustdoc-ui/doctest/force-target-feature.rs @@ -1,6 +1,9 @@ //@ only-x86_64 //@ compile-flags:--test -C target-feature=+avx -//@ should-fail +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +#![feature(doc_cfg)] /// (written on a spider's web) Some Struct /// diff --git a/tests/rustdoc-ui/doctest/force-target-feature.stdout b/tests/rustdoc-ui/doctest/force-target-feature.stdout new file mode 100644 index 0000000000000..861a742075623 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-target-feature.stdout @@ -0,0 +1,27 @@ + +running 1 test +test $DIR/force-target-feature.rs - SomeStruct (line 10) ... FAILED + +failures: + +---- $DIR/force-target-feature.rs - SomeStruct (line 10) stdout ---- +Test executable failed (exit status: 101). + +stderr: + +thread 'main' ($TID) panicked at $DIR/force-target-feature.rs:3:1: +oh no +stack backtrace: + 0: std::panicking::begin_panic::<&str> + 1: rust_out::main::_doctest_main__home_imperio_rust_rust_tests_rustdoc_ui_doctest_force_target_feature_rs_10_0 + 2: rust_out::main + 3: >::call_once +note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. + + + +failures: + $DIR/force-target-feature.rs - SomeStruct (line 10) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/ice-type-error-19181.rs b/tests/rustdoc-ui/doctest/ice-type-error-19181.rs similarity index 65% rename from tests/rustdoc-html/ice-type-error-19181.rs rename to tests/rustdoc-ui/doctest/ice-type-error-19181.rs index 02c6404762222..accb9e2cab1f4 100644 --- a/tests/rustdoc-html/ice-type-error-19181.rs +++ b/tests/rustdoc-ui/doctest/ice-type-error-19181.rs @@ -1,4 +1,7 @@ //@ compile-flags:--test +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + // https://github.com/rust-lang/rust/issues/19181 // rustdoc should not panic when target crate has compilation errors diff --git a/tests/rustdoc-ui/doctest/ice-type-error-19181.stdout b/tests/rustdoc-ui/doctest/ice-type-error-19181.stdout new file mode 100644 index 0000000000000..7326c0a25a069 --- /dev/null +++ b/tests/rustdoc-ui/doctest/ice-type-error-19181.stdout @@ -0,0 +1,5 @@ + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/no-run-still-checks-lints.rs b/tests/rustdoc-ui/doctest/no-run-still-checks-lints.rs similarity index 55% rename from tests/rustdoc-html/no-run-still-checks-lints.rs rename to tests/rustdoc-ui/doctest/no-run-still-checks-lints.rs index 73e311b72d5e5..cae6331f4723d 100644 --- a/tests/rustdoc-html/no-run-still-checks-lints.rs +++ b/tests/rustdoc-ui/doctest/no-run-still-checks-lints.rs @@ -1,5 +1,6 @@ //@ compile-flags:--test -//@ should-fail +//@ failure-status: 101 +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" #![doc(test(attr(deny(warnings))))] diff --git a/tests/rustdoc-ui/doctest/no-run-still-checks-lints.stdout b/tests/rustdoc-ui/doctest/no-run-still-checks-lints.stdout new file mode 100644 index 0000000000000..86d1b4d3094b6 --- /dev/null +++ b/tests/rustdoc-ui/doctest/no-run-still-checks-lints.stdout @@ -0,0 +1,29 @@ + +running 1 test +test $DIR/no-run-still-checks-lints.rs - foo (line 7) - compile ... FAILED + +failures: + +---- $DIR/no-run-still-checks-lints.rs - foo (line 7) stdout ---- +error: unused variable: `a` + --> $DIR/no-run-still-checks-lints.rs:8:5 + | +LL | let a = 3; + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: the lint level is defined here + --> $DIR/no-run-still-checks-lints.rs:6:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/no-run-still-checks-lints.rs - foo (line 7) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/process-termination.rs b/tests/rustdoc-ui/doctest/process-termination.rs similarity index 80% rename from tests/rustdoc-html/process-termination.rs rename to tests/rustdoc-ui/doctest/process-termination.rs index 73a86e57424a2..02ac594b3f0d4 100644 --- a/tests/rustdoc-html/process-termination.rs +++ b/tests/rustdoc-ui/doctest/process-termination.rs @@ -1,4 +1,6 @@ -//@ compile-flags:--test +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass /// A check of using various process termination strategies /// diff --git a/tests/rustdoc-ui/doctest/process-termination.stdout b/tests/rustdoc-ui/doctest/process-termination.stdout new file mode 100644 index 0000000000000..3e15b9a5df80a --- /dev/null +++ b/tests/rustdoc-ui/doctest/process-termination.stdout @@ -0,0 +1,8 @@ + +running 3 tests +test $DIR/process-termination.rs - check_process_termination (line 16) ... ok +test $DIR/process-termination.rs - check_process_termination (line 22) ... ok +test $DIR/process-termination.rs - check_process_termination (line 9) ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/sanitizer-option.rs b/tests/rustdoc-ui/doctest/sanitizer-option.rs similarity index 86% rename from tests/rustdoc-html/sanitizer-option.rs rename to tests/rustdoc-ui/doctest/sanitizer-option.rs index 7b0038138f09f..5f29f1b8bac7e 100644 --- a/tests/rustdoc-html/sanitizer-option.rs +++ b/tests/rustdoc-ui/doctest/sanitizer-option.rs @@ -1,7 +1,9 @@ //@ needs-sanitizer-support //@ needs-sanitizer-address //@ compile-flags: --test -Z sanitizer=address -C unsafe-allow-abi-mismatch=sanitizer -// +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + // #43031: Verify that rustdoc passes `-Z` options to rustc. Use an extern // function that is provided by the sanitizer runtime, if flag is not passed // correctly, then linking will fail. diff --git a/tests/rustdoc-html/test_option_check/test.rs b/tests/rustdoc-ui/doctest/test-option-check-2.rs similarity index 54% rename from tests/rustdoc-html/test_option_check/test.rs rename to tests/rustdoc-ui/doctest/test-option-check-2.rs index af7a5827690f0..2e74da1eca794 100644 --- a/tests/rustdoc-html/test_option_check/test.rs +++ b/tests/rustdoc-ui/doctest/test-option-check-2.rs @@ -1,6 +1,9 @@ -//@ compile-flags: --test +//@ compile-flags: --test --test-args=--test-threads=1 //@ check-test-line-numbers-match +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass +#[path = "test-option-check.rs"] pub mod bar; /// This is a Foo; diff --git a/tests/rustdoc-ui/doctest/test-option-check-2.stdout b/tests/rustdoc-ui/doctest/test-option-check-2.stdout new file mode 100644 index 0000000000000..ab2db4938dfab --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-option-check-2.stdout @@ -0,0 +1,8 @@ + +running 3 tests +test $DIR/test-option-check-2.rs - Bar (line 18) ... ok +test $DIR/test-option-check-2.rs - Foo (line 11) ... ok +test $DIR/test-option-check.rs - bar::foooo (line 8) ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-html/test_option_check/bar.rs b/tests/rustdoc-ui/doctest/test-option-check.rs similarity index 65% rename from tests/rustdoc-html/test_option_check/bar.rs rename to tests/rustdoc-ui/doctest/test-option-check.rs index 7c2309a79d4b9..e5d3350e3f981 100644 --- a/tests/rustdoc-html/test_option_check/bar.rs +++ b/tests/rustdoc-ui/doctest/test-option-check.rs @@ -1,5 +1,7 @@ //@ compile-flags: --test //@ check-test-line-numbers-match +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass /// This looks like another awesome test! /// diff --git a/tests/rustdoc-ui/doctest/test-option-check.stdout b/tests/rustdoc-ui/doctest/test-option-check.stdout new file mode 100644 index 0000000000000..38f949612a47a --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-option-check.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/test-option-check.rs - foooo (line 8) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/lints/renamed-lint-still-applies.rs b/tests/rustdoc-ui/lints/renamed-lint-still-applies.rs deleted file mode 100644 index a4d3a4b497117..0000000000000 --- a/tests/rustdoc-ui/lints/renamed-lint-still-applies.rs +++ /dev/null @@ -1,10 +0,0 @@ -// compile-args: --crate-type lib -#![deny(broken_intra_doc_links)] -//~^ WARNING renamed to `rustdoc::broken_intra_doc_links` -//! [x] -//~^ ERROR unresolved link - -#![deny(rustdoc::non_autolinks)] -//~^ WARNING renamed to `rustdoc::bare_urls` -//! http://example.com -//~^ ERROR not a hyperlink From 2a534f5f34829daed828deb0a3106159bb249ab9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 31 Aug 2026 19:08:02 +1000 Subject: [PATCH 10/26] `BUILTIN_ATTRIBUTE_MAP` improvements Rename it `BUILTIN_ATTRIBUTE_SET` because it's a set, and use `contains` instead of `get` where appropriate. --- compiler/rustc_attr_parsing/src/attributes/doc.rs | 2 +- compiler/rustc_attr_parsing/src/interface.rs | 4 ++-- compiler/rustc_attr_parsing/src/validate_attr.rs | 4 ++-- compiler/rustc_feature/src/builtin_attrs.rs | 10 +++++----- compiler/rustc_feature/src/lib.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 4 ++-- src/doc/rustc-dev-guide/src/feature-gate-check.md | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index e315d6abea395..6cce64d700a63 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -43,7 +43,7 @@ fn check_keyword(cx: &mut AcceptContext<'_, '_>, keyword: Symbol, span: Span) -> fn check_attribute(cx: &mut AcceptContext<'_, '_>, attribute: Symbol, span: Span) -> bool { // FIXME: This should support attributes with namespace like `diagnostic::do_not_recommend`. - if rustc_feature::BUILTIN_ATTRIBUTE_MAP.contains(&attribute) { + if rustc_feature::BUILTIN_ATTRIBUTE_SET.contains(&attribute) { return true; } cx.emit_err(DocAttributeNotAttribute { span, attribute }); diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index aef7dd48ec664..240f437828259 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -10,7 +10,7 @@ use rustc_attr_ir::target::Target; use rustc_attr_ir::{AttrArgs, AttrItem, AttrPath, Attribute, AttributeKind, HashIgnoredAttrId}; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level, MultiSpan}; -use rustc_feature::{BUILTIN_ATTRIBUTE_MAP, Features}; +use rustc_feature::{BUILTIN_ATTRIBUTE_SET, Features}; use rustc_lint_defs::{LintId, RegisteredTools}; use rustc_session::Session; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; @@ -376,7 +376,7 @@ impl<'sess> AttributeParser<'sess> { ); self.check_attribute_stability(&attr_path, attr_span, accept.stability); if let [part] = parts.as_slice() { - debug_assert!(BUILTIN_ATTRIBUTE_MAP.contains(part)); + debug_assert!(BUILTIN_ATTRIBUTE_SET.contains(part)); } let Some(args) = ArgParser::from_attr_args( diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index f225458ebc0e6..4719ee5103877 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -11,7 +11,7 @@ use rustc_ast::{ }; use rustc_attr_ir::AttrPath; use rustc_errors::{Applicability, Diagnostic, PResult}; -use rustc_feature::BUILTIN_ATTRIBUTE_MAP; +use rustc_feature::BUILTIN_ATTRIBUTE_SET; use rustc_lint_defs::builtin::ILL_FORMED_ATTRIBUTE_INPUT; use rustc_parse::parse_in; use rustc_session::diagnostics::report_lit_error; @@ -27,7 +27,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) | AttrKind::DocComment(..) => return, } - let builtin_attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name)); + let builtin_attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_SET.get(&name)); // Check input tokens for built-in and key-value attributes. if let Some(name) = builtin_attr_info { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index cc5b8ff2238ea..7403a0eb0adbd 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -417,15 +417,15 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[ ]; pub fn is_builtin_attr_name(name: Symbol) -> bool { - BUILTIN_ATTRIBUTE_MAP.get(&name).is_some() + BUILTIN_ATTRIBUTE_SET.contains(&name) } -pub static BUILTIN_ATTRIBUTE_MAP: LazyLock> = LazyLock::new(|| { - let mut map = FxHashSet::default(); +pub static BUILTIN_ATTRIBUTE_SET: LazyLock> = LazyLock::new(|| { + let mut set = FxHashSet::default(); for attr in BUILTIN_ATTRIBUTES.iter() { - if !map.insert(*attr) { + if !set.insert(*attr) { panic!("duplicate builtin attribute `{}`", attr); } } - map + set }); diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 859b2025619e4..a3821ab940b15 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -129,7 +129,7 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option CheckAttrVisitor<'tcx> { [sym::allow | sym::expect | sym::warn | sym::deny | sym::forbid, ..] => {} [name, rest @ ..] => { - if let Some(_) = BUILTIN_ATTRIBUTE_MAP.get(name) { + if BUILTIN_ATTRIBUTE_SET.contains(name) { if rest.len() > 0 && AttributeParser::is_parsed_attribute(slice::from_ref(name)) { diff --git a/src/doc/rustc-dev-guide/src/feature-gate-check.md b/src/doc/rustc-dev-guide/src/feature-gate-check.md index 0b4fc0cd680c0..7726122b02f38 100644 --- a/src/doc/rustc-dev-guide/src/feature-gate-check.md +++ b/src/doc/rustc-dev-guide/src/feature-gate-check.md @@ -100,7 +100,7 @@ Beyond syntax, rustc also gates attributes and `cfg` options. ### Built-in attributes -- [`rustc_ast_passes::check_attribute`] inspects attributes against `BUILTIN_ATTRIBUTE_MAP`. +- [`rustc_ast_passes::check_attribute`] inspects attributes against `BUILTIN_ATTRIBUTE_SET`. - If the attribute is `AttributeGate::Gated` and the feature isn’t enabled, `feature_err` is emitted. From 9670dfaf1574b3417e0404af4524c686d6be7aef Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 31 Aug 2026 19:11:02 +1000 Subject: [PATCH 11/26] Use `GateFn` in `AttributeStability` Also fix a typo and wrap some overlong comment lines. --- compiler/rustc_feature/src/builtin_attrs.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 7403a0eb0adbd..89d87937cea5d 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -61,13 +61,15 @@ pub fn find_gated_cfg(pred: impl Fn(Symbol) -> bool) -> Option<&'static GatedCfg #[derive(Clone, Debug, Copy)] pub enum AttributeStability { - /// An attribute that is unstable behind a specified feature fagte + /// An attribute that is unstable behind a specified feature gate. Unstable { /// The feature gate, for example `rustc_attrs` for rustc_* attributes. gate_name: Symbol, - /// Check function to be called during the `PostExpansionVisitor` pass, which will be one of the `Features::*` functions - gate_check: fn(&Features) -> bool, - /// Notes to be displayed when an attempt is made to use the attribute without its feature gate. + /// Check function to be called during the `PostExpansionVisitor` pass, which will be one + /// of the `Features::*` functions + gate_check: GateFn, + /// Notes to be displayed when an attempt is made to use the attribute without its feature + /// gate. notes: &'static [&'static str], }, /// A stable attribute, can be used on all release channels From cd09177a9a809a90d285bb06203ab1c6ca7a0b15 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 31 Aug 2026 19:15:22 +1000 Subject: [PATCH 12/26] Derive `StableHash` for three feature structs --- Cargo.lock | 1 + compiler/rustc_feature/Cargo.toml | 1 + compiler/rustc_feature/src/unstable.rs | 35 ++++---------------------- 3 files changed, 7 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7cb05bce70ec4..ce8b4ca03046b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4068,6 +4068,7 @@ name = "rustc_feature" version = "0.0.0" dependencies = [ "rustc_data_structures", + "rustc_macros", "rustc_span", "serde", "serde_json", diff --git a/compiler/rustc_feature/Cargo.toml b/compiler/rustc_feature/Cargo.toml index 454fa20032aca..093e6dd91d11b 100644 --- a/compiler/rustc_feature/Cargo.toml +++ b/compiler/rustc_feature/Cargo.toml @@ -6,6 +6,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start rustc_data_structures = { path = "../rustc_data_structures" } +rustc_macros = { path = "../rustc_macros" } rustc_span = { path = "../rustc_span" } serde = { version = "1.0.125", features = ["derive"] } serde_json = "1.0.59" diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 187ce8d639fb4..55e6af1d42ffb 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -5,7 +5,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use rustc_data_structures::AtomicRef; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher}; +use rustc_macros::StableHash; use rustc_span::{Span, Symbol, sym}; use super::{Feature, to_nonzero}; @@ -43,18 +43,19 @@ macro_rules! status_to_enum { /// /// The former is preferred. `enabled` should only be used when the feature symbol is not a /// constant, e.g. a parameter, or when the feature is a library feature. -#[derive(Clone, Default, Debug)] +#[derive(Clone, Default, Debug, StableHash)] pub struct Features { /// `#![feature]` attrs for language features, for error reporting. enabled_lang_features: Vec, /// `#![feature]` attrs for non-language (library) features. enabled_lib_features: Vec, /// `enabled_lang_features` + `enabled_lib_features`. + #[stable_hash(ignore)] // Ignored because it's the sum of the other two fields enabled_features: FxHashSet, } /// Information about an enabled language feature. -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, StableHash)] pub struct EnabledLangFeature { /// Name of the feature gate guarding the language feature. pub gate_name: Symbol, @@ -65,7 +66,7 @@ pub struct EnabledLangFeature { } /// Information about an enabled library feature. -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, StableHash)] pub struct EnabledLibFeature { pub gate_name: Symbol, pub attr_sp: Span, @@ -120,32 +121,6 @@ impl Features { } } -impl StableHash for Features { - fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - // `enabled_features` is skipped because it's the sum of the lang and lib features. - let Features { enabled_lang_features, enabled_lib_features, enabled_features: _ } = self; - enabled_lang_features.stable_hash(hcx, hasher); - enabled_lib_features.stable_hash(hcx, hasher); - } -} - -impl StableHash for EnabledLangFeature { - fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - let EnabledLangFeature { gate_name, attr_sp, stable_since } = self; - gate_name.stable_hash(hcx, hasher); - attr_sp.stable_hash(hcx, hasher); - stable_since.stable_hash(hcx, hasher); - } -} - -impl StableHash for EnabledLibFeature { - fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - let EnabledLibFeature { gate_name, attr_sp } = self; - gate_name.stable_hash(hcx, hasher); - attr_sp.stable_hash(hcx, hasher); - } -} - macro_rules! declare_features { ($( $(#[doc = $doc:tt])* ($status:ident, $feature:ident, $ver:expr, $issue:expr), From b18fed12d8f2f304ee14dfcf516a861556def40a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 31 Aug 2026 19:17:18 +1000 Subject: [PATCH 13/26] Return a slice instead of `&Vec` in two methods It's more idiomatic. --- compiler/rustc_feature/src/unstable.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 55e6af1d42ffb..d08054d89ee81 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -88,11 +88,11 @@ impl Features { /// - Feature gate name. /// - The span of the `#[feature]` attribute. /// - For stable language features, version info for when it was stabilized. - pub fn enabled_lang_features(&self) -> &Vec { + pub fn enabled_lang_features(&self) -> &[EnabledLangFeature] { &self.enabled_lang_features } - pub fn enabled_lib_features(&self) -> &Vec { + pub fn enabled_lib_features(&self) -> &[EnabledLibFeature] { &self.enabled_lib_features } From 799c6d0902f86e9f3356ad5fe78883e05c066701 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 31 Aug 2026 19:22:11 +1000 Subject: [PATCH 14/26] Various comment improvements Fix typos, wrap overlong lines, add missing comments, etc. --- compiler/rustc_feature/src/accepted.rs | 2 +- compiler/rustc_feature/src/removed.rs | 2 +- compiler/rustc_feature/src/unstable.rs | 14 +++++++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index a6e6f4f78323c..37a3594e374ea 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -278,7 +278,7 @@ declare_features! ( /// Allows some increased flexibility in the name resolution rules, /// especially around globs and shadowing (RFC 1560). (accepted, item_like_imports, "1.15.0", Some(35120)), - // Allows using the `kl` and `widekl` target features and the associated intrinsics + /// Allows using the `kl` and `widekl` target features and the associated intrinsics (accepted, keylocker_x86, "1.89.0", Some(134813)), /// Allows `'a: { break 'a; }`. (accepted, label_break_value, "1.65.0", Some(48594)), diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 96dbd346e4fc6..0253f16666628 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -211,7 +211,7 @@ declare_features! ( (removed, no_coverage, "1.74.0", Some(84605), Some("renamed to `coverage_attribute`"), 114656), /// Allows `#[no_debug]`. (removed, no_debug, "1.43.0", Some(29721), Some("removed due to lack of demand"), 69667), - // Allows the use of `no_sanitize` attribute. + /// Allows the use of `no_sanitize` attribute. /// The feature was renamed to `sanitize` and the attribute to `#[sanitize(xyz = "on|off")]` (removed, no_sanitize, "1.91.0", Some(39699), Some(r#"renamed to sanitize(xyz = "on|off")"#), 142681), /// Note: this feature was previously recorded in a separate diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index d08054d89ee81..ca70389815141 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -100,7 +100,7 @@ impl Features { &self.enabled_features } - /// Returns a iterator of enabled features in stable order. + /// Returns an iterator of enabled features in stable order. pub fn enabled_features_iter_stable_order( &self, ) -> impl Iterator + Clone { @@ -490,7 +490,7 @@ declare_features! ( (unstable, diagnostic_on_unknown, "1.96.0", Some(152900)), /// Allows macros to customize macro argument matcher diagnostics. (unstable, diagnostic_on_unmatched_args, "1.97.0", Some(155642)), - // Used by macros to not show their bodies in error messages. No-op with `-Z macro-backtrace`. + /// Used by macros to not show their bodies in error messages. No-op with `-Z macro-backtrace`. (unstable, diagnostic_opaque, "1.99.0", Some(158813)), /// Allows `#[doc(cfg(...))]`. (unstable, doc_cfg, "1.21.0", Some(43781)), @@ -553,7 +553,8 @@ declare_features! ( (incomplete, generic_const_parameter_types, "1.87.0", Some(137626)), /// Allows any generic constants being used as pattern type range ends (incomplete, generic_pattern_types, "1.86.0", Some(136574)), - /// Allows registering static items globally, possibly across crates, to iterate over at runtime. + /// Allows registering static items globally, possibly across crates, to iterate over at + /// runtime. (unstable, global_registration, "1.80.0", Some(125119)), /// Allows using guards in patterns. (incomplete, guard_patterns, "1.85.0", Some(129967)), @@ -654,7 +655,7 @@ declare_features! ( (unstable, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554)), /// Allows `for` binders in where-clauses (incomplete, non_lifetime_binders, "1.69.0", Some(108185)), - /// Target feaures on nvptx. + /// Target features on nvptx. (unstable, nvptx_target_feature, "1.91.0", Some(150254)), /// Allows using enums in offset_of! (unstable, offset_of_enum, "1.75.0", Some(120141)), @@ -676,10 +677,12 @@ declare_features! ( (unstable, proc_macro_hygiene, "1.30.0", Some(54727)), /// Allows the use of raw-dylibs on ELF platforms (incomplete, raw_dylib_elf, "1.87.0", Some(135694)), + /// Allows the `Reborrow` and `CoerceShared` traits. (unstable, reborrow, "1.91.0", Some(145612)), /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024. (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)), - /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant + /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural + /// variant. (incomplete, ref_pat_eat_one_layer_2024_structural, "1.81.0", Some(123076)), /// Allows using the `#[register_tool]` attribute. (unstable, register_tool, "1.41.0", Some(66079)), @@ -766,6 +769,7 @@ declare_features! ( (unstable, xtensa_target_feature, "1.98.0", Some(157063)), /// Allows `do yeet` expressions (unstable, yeet_expr, "1.62.0", Some(96373)), + /// Allows the `yield` keyword for coroutines/generators. (unstable, yield_expr, "1.87.0", Some(43122)), // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. From 6146d3aacc810466c9f367d7da467067a465a1ed Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 31 Aug 2026 19:24:08 +1000 Subject: [PATCH 15/26] Use `NonZero` consistently Avoid mixing it with `NonZeroU32`. --- compiler/rustc_feature/src/removed.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 0253f16666628..bcdffe75259a9 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -1,6 +1,6 @@ //! List of the removed feature gates. -use std::num::{NonZero, NonZeroU32}; +use std::num::NonZero; use rustc_span::sym; @@ -17,7 +17,7 @@ macro_rules! opt_nonzero_u32 { None }; ($val:expr) => { - Some(NonZeroU32::new($val).unwrap()) + Some(>::new($val).unwrap()) }; } @@ -34,7 +34,7 @@ macro_rules! declare_features { issue: to_nonzero($issue), }, reason: $reason, - pull: opt_nonzero_u32!($($pull)?), + pull: opt_nonzero_u32!($($pull)?), }),+ ]; }; From ca967fa4e7867a10192f9b63bf3401bc194cb635 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 31 Aug 2026 19:25:17 +1000 Subject: [PATCH 16/26] Add a missing backtick --- compiler/rustc_feature/src/removed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index bcdffe75259a9..403617f7bfa6f 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -266,7 +266,7 @@ declare_features! ( (removed, pushpop_unsafe, "1.2.0", None, None), (removed, quad_precision_float, "1.0.0", None, None), (removed, quote, "1.33.0", Some(29601), None), - (removed, ref_pat_everywhere, "1.80.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024"), 125168), + (removed, ref_pat_everywhere, "1.80.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024`"), 125168), (removed, reflect, "1.0.0", Some(27749), None), /// Allows using the `#[register_attr]` attribute. (removed, register_attr, "1.65.0", Some(66080), From ef2ae3a7e0a69bad0e5aa38aef445432f2ffea0c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 31 Aug 2026 19:28:42 +1000 Subject: [PATCH 17/26] Streamline a check --- compiler/rustc_feature/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index a3821ab940b15..5b9b899fc463f 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -70,8 +70,7 @@ impl UnstableFeatures { let is_unstable_crate = |var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name)); - let bootstrap = env_var_rustc_bootstrap.ok(); - if let Some(val) = bootstrap.as_deref() { + if let Ok(val) = env_var_rustc_bootstrap.as_deref() { match val { val if val == "1" || is_unstable_crate(val) => return UnstableFeatures::Cheat, // Hypnotize ourselves so that we think we are a stable compiler and thus don't From 60be5628af1f9202097d63613e9c68f1f5990378 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 31 Aug 2026 19:31:30 +1000 Subject: [PATCH 18/26] Simplify `find_gated_cfg` Every caller passes a predicate that just does a name comparison. --- compiler/rustc_attr_parsing/src/attributes/cfg.rs | 2 +- compiler/rustc_driver_impl/src/lib.rs | 4 +--- compiler/rustc_feature/src/builtin_attrs.rs | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index d7f2243faaab9..e9ace7088d8f0 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -436,7 +436,7 @@ fn parse_cfg_attr_internal<'a>( } fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) { - let gate = find_gated_cfg(|sym| sym == name); + let gate = find_gated_cfg(name); if let (Some(feats), Some(gated_cfg)) = (features, gate) { gate_cfg(gated_cfg, span, sess, feats); } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 54a1babbaae72..b2a2d3dbd60dd 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -741,9 +741,7 @@ fn print_crate_info( .iter() .filter_map(|&(name, value)| { // On stable, exclude unstable flags. - if !sess.is_nightly_build() - && find_gated_cfg(|cfg_sym| cfg_sym == name).is_some() - { + if !sess.is_nightly_build() && find_gated_cfg(name).is_some() { return None; } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 89d87937cea5d..7e491a7569d11 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -54,9 +54,9 @@ const GATED_CFGS: &[GatedCfg] = &[ (sym::target_object_format, sym::cfg_target_object_format, Features::cfg_target_object_format), ]; -/// Find a gated cfg determined by the `pred`icate which is given the cfg's name. -pub fn find_gated_cfg(pred: impl Fn(Symbol) -> bool) -> Option<&'static GatedCfg> { - GATED_CFGS.iter().find(|(cfg_sym, ..)| pred(*cfg_sym)) +/// Find a gated cfg matching `name`. +pub fn find_gated_cfg(name: Symbol) -> Option<&'static GatedCfg> { + GATED_CFGS.iter().find(|(cfg_sym, ..)| name == *cfg_sym) } #[derive(Clone, Debug, Copy)] From 892c6bb8e88536aafabe1d4734073b82c15da566 Mon Sep 17 00:00:00 2001 From: khyperia <953151+khyperia@users.noreply.github.com> Date: Mon, 31 Aug 2026 14:20:09 +0200 Subject: [PATCH 19/26] explicitly track inherent const generic args kind --- compiler/rustc_borrowck/src/type_check/mod.rs | 3 +- .../src/check/compare_impl_item.rs | 4 +- .../src/hir_ty_lowering/bounds.rs | 7 +- .../src/hir_ty_lowering/errors.rs | 1 + .../src/hir_ty_lowering/mod.rs | 39 ++-- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 48 +---- compiler/rustc_hir_typeck/src/lib.rs | 3 +- compiler/rustc_infer/src/infer/mod.rs | 3 +- .../src/infer/relate/generalize.rs | 3 +- compiler/rustc_middle/src/mir/consts.rs | 10 +- .../rustc_middle/src/mir/interpret/queries.rs | 5 +- compiler/rustc_middle/src/mir/pretty.rs | 3 +- compiler/rustc_middle/src/ty/context.rs | 177 ++++++++++++++---- .../src/ty/context/impl_interner.rs | 46 ++++- compiler/rustc_middle/src/ty/error.rs | 3 +- compiler/rustc_middle/src/ty/print/pretty.rs | 8 +- compiler/rustc_middle/src/ty/sty.rs | 16 -- compiler/rustc_middle/src/ty/util.rs | 3 +- .../src/builder/expr/as_constant.rs | 6 +- .../src/thir/pattern/const_to_pat.rs | 9 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 6 +- .../src/solve/eval_ctxt/mod.rs | 16 +- .../src/solve/normalizes_to.rs | 37 ++-- .../src/solve/project_goals/inherent.rs | 81 +++++--- .../src/solve/project_goals/mod.rs | 4 +- .../src/unstable/convert/stable/ty.rs | 3 +- .../cfi/typeid/itanium_cxx_abi/transform.rs | 1 + compiler/rustc_symbol_mangling/src/v0.rs | 3 +- .../src/error_reporting/infer/mod.rs | 3 +- .../src/traits/fulfill.rs | 3 +- .../src/traits/normalize.rs | 2 +- .../src/traits/project.rs | 35 ++-- .../src/traits/query/normalize.rs | 4 +- .../traits/query/type_op/ascribe_user_type.rs | 22 --- .../src/traits/select/mod.rs | 3 +- .../rustc_trait_selection/src/traits/wf.rs | 6 +- .../src/normalize_projection_ty.rs | 6 - compiler/rustc_ty_utils/src/consts.rs | 11 +- compiler/rustc_type_ir/src/const_kind.rs | 73 ++++++-- compiler/rustc_type_ir/src/interner.rs | 27 ++- compiler/rustc_type_ir/src/predicate.rs | 5 +- compiler/rustc_type_ir/src/relate.rs | 13 +- compiler/rustc_type_ir/src/term_kind.rs | 68 ++++--- compiler/rustc_type_ir/src/ty_kind.rs | 28 +-- src/librustdoc/clean/utils.rs | 3 +- .../gca/path-to-non-type-const.rs | 17 +- ...h-to-non-type-inherent-associated-const.rs | 31 --- ...-non-type-inherent-associated-const.stderr | 24 --- 48 files changed, 563 insertions(+), 369 deletions(-) delete mode 100644 tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.rs delete mode 100644 tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.stderr diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6f89a64f95360..d9534527dc48f 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1769,7 +1769,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { Const::Ty(_, ct) => match ct.kind() { ty::ConstKind::Alias(_, alias_const) => match alias_const.kind { ty::AliasConstKind::Projection { def_id } - | ty::AliasConstKind::Inherent { def_id } + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } | ty::AliasConstKind::Free { def_id } | ty::AliasConstKind::Anon { def_id } => Some(UnevaluatedConst { def: def_id, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 7ad57107eebbd..e5d26cf72f9a5 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2727,9 +2727,9 @@ fn param_env_with_gat_bounds<'tcx>( _ => clauses.push( ty::Binder::bind_with_vars( ty::ProjectionClause { - projection_term: ty::AliasTerm::new_from_def_id( + projection_term: ty::AliasTerm::new( tcx, - trait_ty.def_id, + ty::AliasTermKind::ProjectionTy { def_id: trait_ty.def_id }, rebased_args, ), term: normalize_impl_ty.into(), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index c12bafd9d5d57..9fde34f473205 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -477,7 +477,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); debug!(?alias_args); - ty::AliasTerm::new_from_def_id(tcx, assoc_item.def_id, alias_args) + ty::AliasTerm::new_from_def_id( + tcx, + assoc_item.def_id, + alias_args, + ty::AliasConstInherentArgsKind::WithSelf, + ) }) }; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index dc108c41cf787..8c22506a8b918 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -485,6 +485,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx, assoc_item.def_id, alias_args, + ty::AliasConstInherentArgsKind::WithSelf, ) }); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 16a622da61c2b..cfff8d1768f0e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1609,7 +1609,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); } - Ok(TypeRelativePath::AssocItem(ty::AliasTerm::new_from_def_id(tcx, item_def_id, args))) + Ok(TypeRelativePath::AssocItem(ty::AliasTerm::new_from_def_id( + tcx, + item_def_id, + args, + ty::AliasConstInherentArgsKind::WithSelf, + ))) } /// Resolve a [type-relative](hir::QPath::TypeRelative) (and type-level) path. @@ -1773,12 +1778,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let kind = match assoc_tag { ty::AssocTag::Type => ty::AliasTermKind::InherentTy { def_id: assoc_item }, - ty::AssocTag::Const => { - // FIXME(mgca): drop once `InherentConst` accepts IAC-shaped args (issue #156181) - // without this, `new_from_args` errors (#155341). - self.require_type_const_attribute(assoc_item, span)?; - ty::AliasTermKind::InherentConst { def_id: assoc_item } - } + ty::AssocTag::Const => ty::AliasTermKind::InherentConstSelf { def_id: assoc_item }, ty::AssocTag::Fn => unreachable!(), }; @@ -1948,7 +1948,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.require_type_const_attribute(item_def_id, span)?; let alias_const = ty::AliasConst::new( tcx, - ty::AliasConstKind::new_from_def_id(tcx, item_def_id), + ty::AliasConstKind::new_from_def_id( + tcx, + item_def_id, + ty::AliasConstInherentArgsKind::WithSelf, + ), item_args, ); Ok(Const::new_alias(tcx, ty::IsRigid::No, alias_const)) @@ -2903,7 +2907,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::Const::new_alias( tcx, ty::IsRigid::No, - ty::AliasConst::new(tcx, ty::AliasConstKind::new_from_def_id(tcx, did), args), + ty::AliasConst::new( + tcx, + ty::AliasConstKind::new_from_def_id( + tcx, + did, + ty::AliasConstInherentArgsKind::WithSelf, + ), + args, + ), ) } Res::Def(kind @ DefKind::Ctor(ctor_of, CtorKind::Const), did) => { @@ -3141,14 +3153,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx(); - // FIXME(gca): Intentionally disallowing paths to inherent associated non-type constants - // until a refactoring for how generic args for IACs are represented has been landed. - let is_inherent_assoc_const = tcx.def_kind(def_id) - == DefKind::AssocConst { is_type_const: false } - && tcx.def_kind(tcx.parent(def_id)) == DefKind::Impl { of_trait: false }; - if tcx.is_type_const(def_id) - || tcx.features().generic_const_args() && !is_inherent_assoc_const - { + if tcx.is_type_const(def_id) || tcx.features().generic_const_args() { Ok(()) } else { let mut err = self.dcx().struct_span_err( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 651b4ca33be99..b59dc21981ce6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -48,38 +48,6 @@ use crate::method::{self, MethodCallee}; use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - /// Transform generic args for inherent associated type constants (IACs). - /// - /// IACs have a different generic parameter structure than regular associated constants: - /// - Regular assoc const: parent (impl) generic params + own generic params - /// - IAC (type_const): Self type + own generic params - pub(crate) fn transform_args_for_inherent_type_const( - &self, - def_id: DefId, - args: GenericArgsRef<'tcx>, - ) -> GenericArgsRef<'tcx> { - let tcx = self.tcx; - if !tcx.is_type_const(def_id) { - return args; - } - let Some(assoc_item) = tcx.opt_associated_item(def_id) else { - return args; - }; - if !matches!(assoc_item.container, ty::AssocContainer::InherentImpl) { - return args; - } - - let impl_def_id = assoc_item.container_id(tcx); - let generics = tcx.generics_of(def_id); - let impl_args = &args[..generics.parent_count]; - let self_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args).skip_norm_wip(); - // Build new args: [Self, own_args...] - let own_args = &args[generics.parent_count..]; - tcx.mk_args_from_iter( - std::iter::once(ty::GenericArg::from(self_ty)).chain(own_args.iter().copied()), - ) - } - /// Produces warning on the given node, if the current point in the /// function is unreachable, and there hasn't been another warning. pub(crate) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) { @@ -1399,7 +1367,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - let args_raw = implicit_args.unwrap_or_else(|| { + let args_for_user_type = implicit_args.unwrap_or_else(|| { lower_generic_args( self, def_id, @@ -1417,17 +1385,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }); - let args_for_user_type = if let Res::Def(DefKind::AssocConst { .. }, def_id) = res { - self.transform_args_for_inherent_type_const(def_id, args_raw) - } else { - args_raw - }; - // First, store the "user args" for later. self.write_user_type_annotation_from_args(hir_id, def_id, args_for_user_type, user_self_ty); // Normalize only after registering type annotations. - let args = self.normalize(span, Unnormalized::new_wip(args_raw)); + let args = self.normalize(span, Unnormalized::new_wip(args_for_user_type)); self.add_required_obligations_for_hir(span, def_id, args, hir_id); @@ -1465,12 +1427,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_instantiated); - let args = if let Res::Def(DefKind::AssocConst { .. }, def_id) = res { - self.transform_args_for_inherent_type_const(def_id, args) - } else { - args - }; - self.write_args(hir_id, args); (ty_instantiated, res) diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 57fd6a8658ae3..0f977710fbe09 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -392,7 +392,8 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti impl_def_id, impl_trait_ref.args, ); - tcx.check_args_compatible(trait_item_def_id, args) + let alias_kind = ty::AliasTermKind::ProjectionConst { def_id: trait_item_def_id }; + tcx.check_alias_term_args_compatible(alias_kind, args) .then(|| tcx.type_of(trait_item_def_id).instantiate(tcx, args).skip_norm_wip()) } else { Some(fcx.next_ty_var(span)) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index a49a4355b66b1..773cd9b75aaea 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -994,7 +994,8 @@ impl<'tcx> InferCtxt<'tcx> { | ty::AliasTermKind::OpaqueTy { .. } | ty::AliasTermKind::FreeTy { .. } => self.next_ty_var(span).into(), ty::AliasTermKind::FreeConst { .. } - | ty::AliasTermKind::InherentConst { .. } + | ty::AliasTermKind::InherentConstSelf { .. } + | ty::AliasTermKind::InherentConstImpl { .. } | ty::AliasTermKind::AnonConst { .. } | ty::AliasTermKind::ProjectionConst { .. } => self.next_const_var(span).into(), } diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index afdabb38c3b20..35d04597451c0 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -182,7 +182,8 @@ impl<'tcx> InferCtxt<'tcx> { | ty::AliasTermKind::OpaqueTy { .. } => { return Err(TypeError::CyclicTy(source_term.expect_type())); } - ty::AliasTermKind::InherentConst { .. } + ty::AliasTermKind::InherentConstSelf { .. } + | ty::AliasTermKind::InherentConstImpl { .. } | ty::AliasTermKind::FreeConst { .. } | ty::AliasTermKind::AnonConst { .. } => { return Err(TypeError::CyclicConst(source_term.expect_const())); diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 54e64b37245c3..3b85651ee5f76 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -474,7 +474,15 @@ impl<'tcx> UnevaluatedConst<'tcx> { #[inline] pub fn shrink(self, tcx: TyCtxt<'tcx>) -> ty::AliasConst<'tcx> { assert_eq!(self.promoted, None); - ty::AliasConst::new(tcx, ty::AliasConstKind::new_from_def_id(tcx, self.def), self.args) + ty::AliasConst::new( + tcx, + ty::AliasConstKind::new_from_def_id( + tcx, + self.def, + ty::AliasConstInherentArgsKind::Impl, + ), + self.args, + ) } } diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 9b98f4787371b..406a96ff7ca57 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -104,8 +104,11 @@ impl<'tcx> TyCtxt<'tcx> { } let def_id = match ct.kind { + ty::AliasConstKind::InherentSelf { .. } => { + bug!("got AliasConstKind::InherentSelf in const_eval_resolve_for_typeck") + } ty::AliasConstKind::Projection { def_id } - | ty::AliasConstKind::Inherent { def_id } + | ty::AliasConstKind::InherentImpl { def_id } | ty::AliasConstKind::Free { def_id } | ty::AliasConstKind::Anon { def_id } => def_id, }; diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 021c1c176d788..c8d0820a78903 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1494,7 +1494,8 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { ty::ConstKind::Alias(_, alias_const) => { let kind = match alias_const.kind { ty::AliasConstKind::Projection { def_id } - | ty::AliasConstKind::Inherent { def_id } + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } | ty::AliasConstKind::Free { def_id } | ty::AliasConstKind::Anon { def_id } => self.tcx.def_path_str(def_id), }; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7a3b4c7fbbeb8..924dc7552e59b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -13,7 +13,7 @@ use std::hash::{Hash, Hasher}; use std::marker::PointeeSized; use std::ops::Deref; use std::sync::{Arc, OnceLock}; -use std::{fmt, iter, mem}; +use std::{debug_assert_matches, fmt, iter, mem}; use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx}; use rustc_ast as ast; @@ -2117,27 +2117,44 @@ impl<'tcx> TyCtxt<'tcx> { if pred.kind() != binder { self.mk_predicate(binder) } else { pred } } + /// If you have a [`ty::Alias`], you should almost certainly be calling + /// [`Self::check_alias_term_args_compatible`] instead. This method assumes that inherent alias + /// consts always have `impl`-form args, and will return an invalid result if the `def_id` comes + /// from a [`ty::AliasConstKind::InherentSelf`] (see the doc on that for what "impl form args" + /// means). pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool { - self.check_args_compatible_inner(def_id, args, false) + let is_inherent_assoc_ty = matches!(self.def_kind(def_id), DefKind::AssocTy) + && matches!(self.def_kind(self.parent(def_id)), DefKind::Impl { of_trait: false }); + self.check_args_compatible_inner(def_id, args, is_inherent_assoc_ty) + } + + pub fn check_alias_term_args_compatible( + self, + kind: ty::AliasTermKind<'tcx>, + args: &'tcx [ty::GenericArg<'tcx>], + ) -> bool { + let (def_id, is_self_args) = match kind { + ty::AliasTermKind::ProjectionTy { def_id } + | ty::AliasTermKind::OpaqueTy { def_id } + | ty::AliasTermKind::FreeTy { def_id } + | ty::AliasTermKind::AnonConst { def_id } + | ty::AliasTermKind::ProjectionConst { def_id } + | ty::AliasTermKind::FreeConst { def_id } + | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false), + ty::AliasTermKind::InherentTy { def_id } + | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true), + }; + self.check_args_compatible_inner(def_id, args, is_self_args) } fn check_args_compatible_inner( self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>], - nested: bool, + is_self_args: bool, ) -> bool { let generics = self.generics_of(def_id); - - // IATs and IACs (inherent associated types/consts with `type const`) themselves have a - // weird arg setup (self + own args), but nested items *in* IATs (namely: opaques, i.e. - // ATPITs) do not. - let is_inherent_assoc_ty = matches!(self.def_kind(def_id), DefKind::AssocTy) - && matches!(self.def_kind(self.parent(def_id)), DefKind::Impl { of_trait: false }); - let is_inherent_assoc_type_const = - matches!(self.def_kind(def_id), DefKind::AssocConst { is_type_const: true }) - && matches!(self.def_kind(self.parent(def_id)), DefKind::Impl { of_trait: false }); - let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) { + let own_args = if is_self_args { if generics.own_params.len() + 1 != args.len() { return false; } @@ -2154,8 +2171,11 @@ impl<'tcx> TyCtxt<'tcx> { let (parent_args, own_args) = args.split_at(generics.parent_count); + // In the type system, IATs and IACs (inherent associated types/consts) themselves have a + // weird arg setup (self + own args), but nested items *in* IATs (namely: opaques, i.e. + // ATPITs) do not. So, set `is_self_args` to false for the parent generic check. if let Some(parent) = generics.parent - && !self.check_args_compatible_inner(parent, parent_args, true) + && !self.check_args_compatible_inner(parent, parent_args, false) { return false; } @@ -2177,39 +2197,116 @@ impl<'tcx> TyCtxt<'tcx> { /// With `cfg(debug_assertions)`, assert that args are compatible with their generics, /// and print out the args if not. + /// + /// If you have a [`ty::Alias`], you should use + /// [`Self::debug_assert_alias_term_args_compatible`] instead. See note on + /// [`Self::check_args_compatible`]. pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) { if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) { let is_inherent_assoc_ty = matches!(self.def_kind(def_id), DefKind::AssocTy) && matches!(self.def_kind(self.parent(def_id)), DefKind::Impl { of_trait: false }); - let is_inherent_assoc_type_const = - matches!(self.def_kind(def_id), DefKind::AssocConst { is_type_const: true }) - && matches!( - self.def_kind(self.parent(def_id)), - DefKind::Impl { of_trait: false } - ); - if is_inherent_assoc_ty || is_inherent_assoc_type_const { - bug!( - "args not compatible with generics for {}: args={:#?}, generics={:#?}", - self.def_path_str(def_id), - args, - // Make `[Self, GAT_ARGS...]` (this could be simplified) - self.mk_args_from_iter( - [self.types.self_param.into()].into_iter().chain( - self.generics_of(def_id) - .own_args(ty::GenericArgs::identity_for_item(self, def_id)) - .iter() - .copied() - ) - ) + self.emit_bug_args_compatible(def_id, args, is_inherent_assoc_ty); + } + } + + pub fn debug_assert_alias_term_args_compatible( + self, + kind: ty::AliasTermKind<'tcx>, + args: ty::GenericArgsRef<'tcx>, + ) { + if cfg!(debug_assertions) { + self.debug_assert_alias_term_kind_matches_def_kind(kind); + if !self.check_alias_term_args_compatible(kind, args) { + let (def_id, is_self_args) = match kind { + ty::AliasTermKind::ProjectionTy { def_id } + | ty::AliasTermKind::OpaqueTy { def_id } + | ty::AliasTermKind::FreeTy { def_id } + | ty::AliasTermKind::AnonConst { def_id } + | ty::AliasTermKind::ProjectionConst { def_id } + | ty::AliasTermKind::FreeConst { def_id } + | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false), + ty::AliasTermKind::InherentTy { def_id } + | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true), + }; + self.emit_bug_args_compatible(def_id, args, is_self_args); + } + } + } + + fn debug_assert_alias_term_kind_matches_def_kind(self, kind: ty::AliasTermKind<'tcx>) { + match kind { + ty::AliasTermKind::ProjectionTy { def_id } => { + debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy); + debug_assert_matches!( + self.def_kind(self.parent(def_id)), + DefKind::Trait | DefKind::Impl { of_trait: true } + ); + } + ty::AliasTermKind::InherentTy { def_id } => { + debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy); + debug_assert_matches!( + self.def_kind(self.parent(def_id)), + DefKind::Impl { of_trait: false } + ); + } + ty::AliasTermKind::OpaqueTy { def_id } => { + debug_assert_matches!(self.def_kind(def_id), DefKind::OpaqueTy); + } + ty::AliasTermKind::FreeTy { def_id } => { + debug_assert_matches!(self.def_kind(def_id), DefKind::TyAlias); + } + ty::AliasTermKind::AnonConst { def_id } => { + debug_assert_matches!(self.def_kind(def_id), DefKind::AnonConst); + } + ty::AliasTermKind::ProjectionConst { def_id } => { + debug_assert_matches!(self.def_kind(def_id), DefKind::AssocConst { .. }); + debug_assert_matches!( + self.def_kind(self.parent(def_id)), + DefKind::Trait | DefKind::Impl { of_trait: true } ); - } else { - bug!( - "args not compatible with generics for {}: args={:#?}, generics={:#?}", - self.def_path_str(def_id), - args, - ty::GenericArgs::identity_for_item(self, def_id) + } + ty::AliasTermKind::InherentConstSelf { def_id } + | ty::AliasTermKind::InherentConstImpl { def_id } => { + debug_assert_matches!(self.def_kind(def_id), DefKind::AssocConst { .. }); + debug_assert_matches!( + self.def_kind(self.parent(def_id)), + DefKind::Impl { of_trait: false } ); } + ty::AliasTermKind::FreeConst { def_id } => { + debug_assert_matches!(self.def_kind(def_id), DefKind::Const { .. }); + } + } + } + + fn emit_bug_args_compatible( + self, + def_id: DefId, + args: &'tcx [ty::GenericArg<'tcx>], + is_self_args: bool, + ) -> ! { + if is_self_args { + bug!( + "args not compatible with generics for {}: args={:#?}, generics={:#?}", + self.def_path_str(def_id), + args, + // Make `[Self, GAT_ARGS...]` (this could be simplified) + self.mk_args_from_iter( + [self.types.self_param.into()].into_iter().chain( + self.generics_of(def_id) + .own_args(ty::GenericArgs::identity_for_item(self, def_id)) + .iter() + .copied() + ) + ) + ); + } else { + bug!( + "args not compatible with generics for {}: args={:#?}, generics={:#?}", + self.def_path_str(def_id), + args, + ty::GenericArgs::identity_for_item(self, def_id) + ); } } diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 048e509ec88e0..576fdd8cb6053 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -204,11 +204,22 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.adt_def(adt_def_id) } - fn alias_const_kind_from_def_id(self, def_id: Self::DefId) -> ty::AliasConstKind<'tcx> { + fn alias_const_kind_from_def_id( + self, + def_id: Self::DefId, + inherent_args: ty::AliasConstInherentArgsKind, + ) -> ty::AliasConstKind<'tcx> { match self.def_kind(def_id) { DefKind::AssocConst { .. } => { if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id)) { - ty::AliasConstKind::Inherent { def_id } + match inherent_args { + ty::AliasConstInherentArgsKind::WithSelf => { + ty::AliasConstKind::InherentSelf { def_id } + } + ty::AliasConstInherentArgsKind::Impl => { + ty::AliasConstKind::InherentImpl { def_id } + } + } } else { ty::AliasConstKind::Projection { def_id } } @@ -221,7 +232,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } } - fn alias_term_kind_from_def_id(self, def_id: DefId) -> ty::AliasTermKind<'tcx> { + fn alias_term_kind_from_def_id( + self, + def_id: DefId, + inherent_args: ty::AliasConstInherentArgsKind, + ) -> ty::AliasTermKind<'tcx> { match self.def_kind(def_id) { DefKind::AssocTy => { if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id)) { @@ -232,7 +247,14 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } DefKind::AssocConst { .. } => { if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id)) { - ty::AliasTermKind::InherentConst { def_id } + match inherent_args { + ty::AliasConstInherentArgsKind::WithSelf => { + ty::AliasTermKind::InherentConstSelf { def_id } + } + ty::AliasConstInherentArgsKind::Impl => { + ty::AliasTermKind::InherentConstImpl { def_id } + } + } } else { ty::AliasTermKind::ProjectionConst { def_id } } @@ -271,14 +293,26 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.mk_args_from_iter(args) } - fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool { - self.check_args_compatible(def_id, args) + fn check_alias_term_args_compatible( + self, + kind: ty::AliasTermKind<'tcx>, + args: ty::GenericArgsRef<'tcx>, + ) -> bool { + self.check_alias_term_args_compatible(kind, args) } fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) { self.debug_assert_args_compatible(def_id, args); } + fn debug_assert_alias_term_args_compatible( + self, + kind: ty::AliasTermKind<'tcx>, + args: ty::GenericArgsRef<'tcx>, + ) { + self.debug_assert_alias_term_args_compatible(kind, args); + } + /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection` /// are compatible with the `DefId`. Since we're missing a `Self` type, stick on /// a dummy self type and forward to `debug_assert_args_compatible`. diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 33541dee52fe6..fb4e30b161d44 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -334,7 +334,8 @@ impl<'tcx> TyCtxt<'tcx> { | ty::AliasTermKind::AnonConst { def_id } | ty::AliasTermKind::ProjectionConst { def_id } | ty::AliasTermKind::FreeConst { def_id } - | ty::AliasTermKind::InherentConst { def_id } => self.def_path_str(def_id), + | ty::AliasTermKind::InherentConstSelf { def_id } + | ty::AliasTermKind::InherentConstImpl { def_id } => self.def_path_str(def_id), } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f055051580e81..f5960e65c4493 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1539,7 +1539,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::ConstKind::Alias(_, ty::AliasConst { kind, args, .. }) => { match kind { ty::AliasConstKind::Projection { def_id } - | ty::AliasConstKind::Inherent { def_id } + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } | ty::AliasConstKind::Free { def_id } => { self.pretty_print_value_path(def_id, args)?; } @@ -3172,7 +3173,7 @@ define_print! { ty::AliasTerm<'tcx> { match self.kind { - ty::AliasTermKind::InherentTy { .. } | ty::AliasTermKind::InherentConst { .. } => { + ty::AliasTermKind::InherentTy { .. } | ty::AliasTermKind::InherentConstSelf { .. } => { p.pretty_print_inherent_projection(*self)?; } ty::AliasTermKind::ProjectionTy { def_id } => { @@ -3188,7 +3189,8 @@ define_print! { | ty::AliasTermKind::FreeConst { def_id } | ty::AliasTermKind::OpaqueTy { def_id } | ty::AliasTermKind::AnonConst { def_id } - | ty::AliasTermKind::ProjectionConst { def_id } => { + | ty::AliasTermKind::ProjectionConst { def_id } + | ty::AliasTermKind::InherentConstImpl { def_id } => { p.print_def_path(def_id, self.args)?; } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index bef267b7eaf27..013064b5cec4b 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -478,22 +478,6 @@ impl<'tcx> Ty<'tcx> { is_rigid: ty::IsRigid, alias_ty: ty::AliasTy<'tcx>, ) -> Ty<'tcx> { - if cfg!(debug_assertions) { - match alias_ty.kind { - ty::AliasTyKind::Projection { def_id } => { - debug_assert_matches!(tcx.def_kind(def_id), DefKind::AssocTy) - } - ty::AliasTyKind::Inherent { def_id } => { - debug_assert_matches!(tcx.def_kind(def_id), DefKind::AssocTy) - } - ty::AliasTyKind::Opaque { def_id } => { - debug_assert_matches!(tcx.def_kind(def_id), DefKind::OpaqueTy) - } - ty::AliasTyKind::Free { def_id } => { - debug_assert_matches!(tcx.def_kind(def_id), DefKind::TyAlias) - } - } - } Ty::new(tcx, Alias(is_rigid, alias_ty)) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 09963dba563ec..622086b56c638 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -962,7 +962,8 @@ impl<'tcx> TyCtxt<'tcx> { } ty::AliasTermKind::OpaqueTy { def_id } => Some(self.variances_of(def_id)), ty::AliasTermKind::InherentTy { .. } - | ty::AliasTermKind::InherentConst { .. } + | ty::AliasTermKind::InherentConstSelf { .. } + | ty::AliasTermKind::InherentConstImpl { .. } | ty::AliasTermKind::FreeTy { .. } | ty::AliasTermKind::FreeConst { .. } | ty::AliasTermKind::AnonConst { .. } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index 6e09c365dbf7c..5996073241e2c 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -74,7 +74,11 @@ pub(crate) fn as_constant_inner<'tcx>( if tcx.is_type_const(def_id) { let uneval = ty::AliasConst::new( tcx, - ty::AliasConstKind::new_from_def_id(tcx, def_id), + ty::AliasConstKind::new_from_def_id( + tcx, + def_id, + ty::AliasConstInherentArgsKind::Impl, + ), args, ); let ct = ty::Const::new_alias(tcx, ty::IsRigid::No, uneval); diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 0230840ef2fb8..86387f5caf325 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -80,14 +80,16 @@ impl<'tcx> ConstToPat<'tcx> { fn mk_err(&self, mut err: Diag<'_>, ty: Ty<'tcx>) -> Box> { if let ty::ConstKind::Alias(_, alias_const) = self.c.kind() { if let ty::AliasConstKind::Projection { def_id } - | ty::AliasConstKind::Inherent { def_id } = alias_const.kind + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } = alias_const.kind && let Some(def_id) = def_id.as_local() { // Include the container item in the output. err.span_label(self.tcx.def_span(self.tcx.local_parent(def_id)), ""); } if let ty::AliasConstKind::Projection { def_id } - | ty::AliasConstKind::Inherent { def_id } + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } | ty::AliasConstKind::Free { def_id } = alias_const.kind { err.span_label(self.tcx.def_span(def_id), msg!("constant defined here")); @@ -166,7 +168,8 @@ impl<'tcx> ConstToPat<'tcx> { // on its use as well. if let ty::ConstKind::Alias(_, alias_const) = self.c.kind() && let ty::AliasConstKind::Projection { .. } - | ty::AliasConstKind::Inherent { .. } + | ty::AliasConstKind::InherentSelf { .. } + | ty::AliasConstKind::InherentImpl { .. } | ty::AliasConstKind::Free { .. } = alias_const.kind { err.downgrade_to_delayed_bug(); diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index b69519f3c714f..d64f98542b3a3 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -658,7 +658,11 @@ impl<'tcx, 'ptcx> PatCtxt<'tcx, 'ptcx> { ty::IsRigid::No, ty::AliasConst::new( self.tcx, - ty::AliasConstKind::new_from_def_id(self.tcx, def_id), + ty::AliasConstKind::new_from_def_id( + self.tcx, + def_id, + ty::AliasConstInherentArgsKind::Impl, + ), args, ), ); diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index a0abc918107df..034ad3463ba13 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -1074,7 +1074,8 @@ where | ty::AliasTermKind::OpaqueTy { .. } | ty::AliasTermKind::FreeTy { .. } => self.next_ty_infer().into(), ty::AliasTermKind::FreeConst { .. } - | ty::AliasTermKind::InherentConst { .. } + | ty::AliasTermKind::InherentConstSelf { .. } + | ty::AliasTermKind::InherentConstImpl { .. } | ty::AliasTermKind::AnonConst { .. } | ty::AliasTermKind::ProjectionConst { .. } => self.next_const_infer().into(), } @@ -1440,12 +1441,15 @@ where if self.resolve_vars_if_possible(alias_const).has_non_region_infer() { self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } else { + // Evaluation failed because the const was too generic or was an invalid type + // for const generics. The result of normalization is the alias itself, + // unchanged, but marked as rigid. + // // We do not instantiate to the `alias_const` passed in, but rather - // `goal.predicate.alias`. The `alias_const` passed in might correspond to the `impl` - // form of a constant (with generic arguments corresponding to the impl block), - // however, we want to structurally instantiate to the original, non-rebased, - // trait `Self` form of the constant (with generic arguments being the trait - // `Self` type). + // `projection_term`, which is the unprocessed, original alias contained within + // the goal. The `alias_const` passed in might be a Projection whose DefId is an + // impl of the trait, however, we want to structurally instantiate to the + // original DefId on the trait itself. self.eq( param_env, projection_term.to_term(self.cx(), ty::IsRigid::Yes), diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index f5b1df1be3eff..75f15623a9ba7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -417,7 +417,17 @@ where target_container_def_id, )?; - if !cx.check_args_compatible(target_item_def_id.into(), target_args) { + let target_item_def_id: I::DefId = target_item_def_id.into(); + + let target_item_kind = if goal.predicate.alias.kind.is_type() { + ty::AliasTermKind::ProjectionTy { def_id: target_item_def_id.try_into().unwrap() } + } else { + ty::AliasTermKind::ProjectionConst { + def_id: target_item_def_id.try_into().unwrap(), + } + }; + + if !cx.check_alias_term_args_compatible(target_item_kind, target_args) { return error_response( ecx, cx.delay_bug("associated item has mismatched arguments"), @@ -427,15 +437,14 @@ where // Finally we construct the actual value of the associated type. let term = match goal.predicate.alias.kind { ty::AliasTermKind::ProjectionTy { .. } => { - let t = cx.type_of(target_item_def_id.into()).instantiate(cx, target_args); + let t = cx.type_of(target_item_def_id).instantiate(cx, target_args); let t = ecx.normalize(GoalSource::Misc, goal.param_env, t)?; t.into() } ty::AliasTermKind::ProjectionConst { .. } - if cx.is_type_const(target_item_def_id.into()) => + if cx.is_type_const(target_item_def_id) => { - let c = - cx.const_of_item(target_item_def_id.into()).instantiate(cx, target_args); + let c = cx.const_of_item(target_item_def_id).instantiate(cx, target_args); let c = ecx.normalize(GoalSource::Misc, goal.param_env, c)?; c.into() } @@ -443,7 +452,7 @@ where let alias_const = ty::AliasConst::new( cx, ty::AliasConstKind::Projection { - def_id: target_item_def_id.into().try_into().unwrap(), + def_id: target_item_def_id.try_into().unwrap(), }, target_args, ); @@ -827,13 +836,7 @@ where CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionClause { - projection_term: ty::AliasTerm::new( - ecx.cx(), - cx.alias_term_kind_from_def_id( - goal.predicate.alias.expect_projection_def_id().into(), - ), - [self_ty], - ), + projection_term: ty::AliasTerm::new(ecx.cx(), goal.predicate.alias.kind, [self_ty]), term, } .upcast(cx), @@ -865,13 +868,7 @@ where CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionClause { - projection_term: ty::AliasTerm::new( - ecx.cx(), - cx.alias_term_kind_from_def_id( - goal.predicate.alias.expect_projection_def_id().into(), - ), - [self_ty], - ), + projection_term: ty::AliasTerm::new(ecx.cx(), goal.predicate.alias.kind, [self_ty]), term, } .upcast(cx), diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs index a7480cded0514..51c2475a33461 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs @@ -5,7 +5,7 @@ //! 2. equate the self type, and //! 3. instantiate and register where clauses. -use rustc_type_ir::solve::QueryResultOrRerunNonErased; +use rustc_type_ir::solve::{NoSolutionOrRerunNonErased, QueryResultOrRerunNonErased}; use rustc_type_ir::{self as ty, Interner, Unnormalized}; use crate::delegate::SolverDelegate; @@ -21,20 +21,9 @@ where goal: Goal>, ) -> QueryResultOrRerunNonErased { let cx = self.cx(); - let inherent = goal.predicate.projection_term; - let def_id = inherent.expect_inherent_def_id(); - let impl_def_id = cx.inherent_alias_term_parent(def_id); - let impl_args = self.fresh_args_for_item(impl_def_id.into()); - - // Equate impl header and add impl where clauses - self.eq( - goal.param_env, - inherent.self_ty(), - cx.type_of(impl_def_id.into()).instantiate(cx, impl_args).skip_norm_wip(), - )?; - - // Equate IAT with the RHS of the project goal - let inherent_args = inherent.rebase_inherent_args_onto_impl(impl_args, cx); + let def_id = goal.predicate.projection_term.expect_inherent_def_id(); + let (inherent_kind, inherent_args) = + self.convert_inherent_self_to_impl(goal.param_env, goal.predicate.projection_term)?; // Check both where clauses on the impl and IAT // @@ -53,25 +42,28 @@ where .map(|clause| goal.with(cx, clause)), )?; - let normalized: I::Term = match inherent.kind { + let normalized: I::Term = match inherent_kind { ty::AliasTermKind::InherentTy { def_id } => { let inherent = cx.type_of(def_id.into()).instantiate(cx, inherent_args); let inherent = self.normalize(GoalSource::Misc, goal.param_env, inherent)?; inherent.into() } - ty::AliasTermKind::InherentConst { def_id } if cx.is_type_const(def_id.into()) => { + ty::AliasTermKind::InherentConstImpl { def_id } if cx.is_type_const(def_id.into()) => { let inherent = cx.const_of_item(def_id.into()).instantiate(cx, inherent_args); let inherent = self.normalize(GoalSource::Misc, goal.param_env, inherent)?; inherent.into() } - ty::AliasTermKind::InherentConst { .. } => { - // FIXME(gca): This is dead code at the moment. It should eventually call - // self.evaluate_const like projected consts do in consider_impl_candidate in - // normalizes_to/mod.rs. However, how generic args are represented for IACs is up in - // the air right now. - // Will self.evaluate_const eventually take the inherent_args or the impl_args form - // of args? It might be either. - panic!("References to inherent associated consts should have been blocked"); + ty::AliasTermKind::InherentConstImpl { .. } => { + let term = ty::AliasTerm::new_from_args(cx, inherent_kind, inherent_args); + // NOTE: we intentionally pass in the `InherentConstImpl` form as the term to + // instantiate to upon too-generic CTFE failure, as we ought to consistently compare + // identities via `InherentConstImpl` rather than `InherentConstSelf`. + return self.evaluate_const_and_instantiate_projection_term( + goal.param_env, + term, + goal.predicate.term, + term.expect_ct(), + ); } kind => panic!("expected inherent alias, found {kind:?}"), }; @@ -84,4 +76,43 @@ where self.eq(goal.param_env, goal.predicate.term, normalized)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } + + fn convert_inherent_self_to_impl( + &mut self, + param_env: I::ParamEnv, + term: ty::AliasTerm, + ) -> Result<(ty::AliasTermKind, I::GenericArgs), NoSolutionOrRerunNonErased> { + match term.kind { + ty::AliasTermKind::InherentTy { .. } | ty::AliasTermKind::InherentConstSelf { .. } => { + let cx = self.cx(); + let def_id = term.expect_inherent_def_id(); + let impl_def_id = cx.inherent_alias_term_parent(def_id); + let impl_args = self.fresh_args_for_item(impl_def_id.into()); + + // Equate impl header and add impl where clauses + self.eq( + param_env, + term.self_ty(), + cx.type_of(impl_def_id.into()).instantiate(cx, impl_args).skip_norm_wip(), + )?; + + // Equate IAT with the RHS of the project goal + let inherent_args = term.rebase_inherent_args_onto_impl(impl_args, cx); + + let kind = match term.kind { + ty::AliasTermKind::InherentTy { def_id } => { + ty::AliasTermKind::InherentTy { def_id } + } + ty::AliasTermKind::InherentConstSelf { def_id } => { + ty::AliasTermKind::InherentConstImpl { def_id } + } + _ => unreachable!(), + }; + + Ok((kind, inherent_args)) + } + ty::AliasTermKind::InherentConstImpl { .. } => Ok((term.kind, term.args)), + kind => panic!("expected inherent alias, found {kind:?}"), + } + } } diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs index 6ec82aefb523f..db326e6d736a4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs @@ -27,7 +27,9 @@ where ty::AliasTermKind::ProjectionTy { .. } | ty::AliasTermKind::ProjectionConst { .. } => { self.normalize_associated_term(goal) } - ty::AliasTermKind::InherentTy { .. } | ty::AliasTermKind::InherentConst { .. } => { + ty::AliasTermKind::InherentTy { .. } + | ty::AliasTermKind::InherentConstSelf { .. } + | ty::AliasTermKind::InherentConstImpl { .. } => { self.normalize_inherent_associated_term(goal) } ty::AliasTermKind::OpaqueTy { .. } => self.normalize_opaque_type(goal), diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index e142cb26447a8..17ce015d4ce10 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -60,7 +60,8 @@ impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> { | ty::AliasTermKind::AnonConst { def_id } | ty::AliasTermKind::ProjectionConst { def_id } | ty::AliasTermKind::FreeConst { def_id } - | ty::AliasTermKind::InherentConst { def_id } => def_id, + | ty::AliasTermKind::InherentConstSelf { def_id } + | ty::AliasTermKind::InherentConstImpl { def_id } => def_id, }; crate::ty::AliasTerm { def_id: tables.alias_def(def_id), args: args.stable(tables, cx) } } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 8a44589f5052c..2019f7e15dc70 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -250,6 +250,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc tcx, assoc_item.def_id, super_trait_ref.args, + ty::AliasConstInherentArgsKind::WithSelf, ); let term = tcx.normalize_erasing_regions( ty::TypingEnv::fully_monomorphized(), diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index cf08d3e858ec5..5ed41ac456031 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -749,7 +749,8 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { // logic sometimes passing identity-substituted impl headers. ty::ConstKind::Alias(_, ty::AliasConst { kind, args, .. }) => match kind { ty::AliasConstKind::Projection { def_id } - | ty::AliasConstKind::Inherent { def_id } + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } | ty::AliasConstKind::Free { def_id } | ty::AliasConstKind::Anon { def_id } => { return self.print_def_path(def_id, args); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 1210a3ef57e32..34df03e2584e6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1613,7 +1613,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty::AliasTermKind::AnonConst { def_id } => def_id.into(), ty::AliasTermKind::ProjectionConst { def_id } => def_id.into(), ty::AliasTermKind::FreeConst { def_id } => def_id.into(), - ty::AliasTermKind::InherentConst { def_id } => def_id.into(), + ty::AliasTermKind::InherentConstSelf { def_id } => def_id.into(), + ty::AliasTermKind::InherentConstImpl { def_id } => def_id.into(), }; (false, Mismatch::Fixed(self.tcx.def_descr(def_id))) } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index bca336c2a0449..ddbb56affcff1 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -720,7 +720,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { && matches!( a.kind, ty::AliasConstKind::Projection { .. } - | ty::AliasConstKind::Inherent { .. } + | ty::AliasConstKind::InherentSelf { .. } + | ty::AliasConstKind::InherentImpl { .. } ) => { if let Ok(new_obligations) = infcx diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index f00b300c7e971..0d22ca4973511 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -491,7 +491,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx ty::AliasConstKind::Projection { .. } => { self.normalize_trait_projection(alias_const.into()).expect_const() } - ty::AliasConstKind::Inherent { .. } => { + ty::AliasConstKind::InherentSelf { .. } | ty::AliasConstKind::InherentImpl { .. } => { self.normalize_inherent_projection(alias_const.into()).expect_const() } ty::AliasConstKind::Free { .. } => { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index eaaf082b105c2..9d0daa3a8672b 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -470,18 +470,7 @@ fn normalize_to_error<'a, 'tcx>( depth: usize, ) -> NormalizedTerm<'tcx> { let trait_ref = ty::Binder::dummy(projection_term.trait_ref(selcx.tcx())); - let new_value = match projection_term.kind { - ty::AliasTermKind::ProjectionTy { .. } - | ty::AliasTermKind::InherentTy { .. } - | ty::AliasTermKind::OpaqueTy { .. } - | ty::AliasTermKind::FreeTy { .. } => selcx.infcx.next_ty_var(cause.span).into(), - ty::AliasTermKind::FreeConst { .. } - | ty::AliasTermKind::InherentConst { .. } - | ty::AliasTermKind::AnonConst { .. } - | ty::AliasTermKind::ProjectionConst { .. } => { - selcx.infcx.next_const_var(cause.span).into() - } - }; + let new_value = selcx.infcx.next_term_var_of_alias_kind(projection_term, cause.span); let mut obligations = PredicateObligations::new(); obligations.push(Obligation { cause, @@ -608,7 +597,13 @@ pub fn compute_inherent_assoc_term_args<'a, 'b, 'tcx>( ) -> ty::GenericArgsRef<'tcx> { let tcx = selcx.tcx(); - let alias_def_id = alias_term.expect_inherent_def_id(); + let alias_def_id = match alias_term.kind { + ty::AliasTermKind::InherentTy { def_id } => def_id, + ty::AliasTermKind::InherentConstSelf { def_id } => def_id, + ty::AliasTermKind::InherentConstImpl { .. } => return alias_term.args, + kind => panic!("expected inherent alias, found {kind:?}"), + }; + let impl_def_id = tcx.parent(alias_def_id); let impl_args = selcx.infcx.fresh_args_for_item(cause.span, impl_def_id); @@ -2101,13 +2096,13 @@ fn confirm_impl_candidate<'cx, 'tcx>( let args = obligation.predicate.args.rebase_onto(tcx, trait_def_id, args); let args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_term.defining_node); - let term = if obligation.predicate.kind.is_type() { - tcx.type_of(assoc_term.item.def_id).map_bound(|ty| ty.into()) + let term_kind = if obligation.predicate.kind.is_type() { + ty::AliasTermKind::ProjectionTy { def_id: assoc_term.item.def_id } } else { - tcx.const_of_item(assoc_term.item.def_id).map_bound(|ct| ct.into()) + ty::AliasTermKind::ProjectionConst { def_id: assoc_term.item.def_id } }; - let progress = if !tcx.check_args_compatible(assoc_term.item.def_id, args) { + let progress = if !tcx.check_alias_term_args_compatible(term_kind, args) { let msg = "impl item and trait item have different parameters"; let span = obligation.cause.span; let err = if obligation.predicate.kind.is_type() { @@ -2117,6 +2112,12 @@ fn confirm_impl_candidate<'cx, 'tcx>( }; Progress { term: ty::Unnormalized::dummy(err), obligations: nested } } else { + let term = if obligation.predicate.kind.is_type() { + tcx.type_of(assoc_term.item.def_id).map_bound(|ty| ty.into()) + } else { + tcx.const_of_item(assoc_term.item.def_id).map_bound(|ct| ct.into()) + }; + assoc_term_own_obligations(selcx, obligation, &mut nested); let instantiated_term = term.instantiate(tcx, args); let term_for_obligation = instantiated_term.skip_norm_wip(); diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 489e4f7a93d53..96e41f89be573 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -331,7 +331,9 @@ impl<'a, 'tcx> QueryNormalizer<'a, 'tcx> { ty::AliasTermKind::FreeTy { .. } | ty::AliasTermKind::FreeConst { .. } => { tcx.normalize_canonicalized_free_alias(c_term) } - ty::AliasTermKind::InherentTy { .. } | ty::AliasTermKind::InherentConst { .. } => { + ty::AliasTermKind::InherentTy { .. } + | ty::AliasTermKind::InherentConstSelf { .. } + | ty::AliasTermKind::InherentConstImpl { .. } => { tcx.normalize_canonicalized_inherent_projection(c_term) } kind @ (ty::AliasTermKind::OpaqueTy { .. } | ty::AliasTermKind::AnonConst { .. }) => { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs index e8814c56c5016..4dda9ca5646ea 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs @@ -1,4 +1,3 @@ -use rustc_hir::def::DefKind; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_infer::traits::Obligation; use rustc_middle::traits::query::NoSolution; @@ -99,27 +98,6 @@ fn relate_mir_and_user_args<'tcx>( let tcx = ocx.infcx.tcx; let cause = ObligationCause::dummy_with_span(span); - // For IACs, the user args are in the format [SelfTy, GAT_args...] but type_of expects [impl_args..., GAT_args...]. - // We need to infer the impl args by equating the impl's self type with the user-provided self type. - let is_inherent_assoc_const = matches!(tcx.def_kind(def_id), DefKind::AssocConst { .. }) - && tcx.def_kind(tcx.parent(def_id)) == DefKind::Impl { of_trait: false } - && tcx.is_type_const(def_id); - - let args = if is_inherent_assoc_const { - let impl_def_id = tcx.parent(def_id); - let impl_args = ocx.infcx.fresh_args_for_item(span, impl_def_id); - let impl_self_ty = - ocx.normalize(&cause, param_env, tcx.type_of(impl_def_id).instantiate(tcx, impl_args)); - let user_self_ty = - ocx.normalize(&cause, param_env, Unnormalized::new_wip(args[0].expect_ty())); - ocx.eq(&cause, param_env, impl_self_ty, user_self_ty)?; - - let gat_args = &args[1..]; - tcx.mk_args_from_iter(impl_args.iter().chain(gat_args.iter().copied())) - } else { - args - }; - let ty = tcx.type_of(def_id).instantiate(tcx, args); let ty = ocx.normalize(&cause, param_env, ty); debug!("relate_type_and_user_type: ty of def-id is {:?}", ty); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index f1eaa50797c49..a2785a7ca75dc 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -876,7 +876,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { && matches!( a.kind, ty::AliasConstKind::Projection { .. } - | ty::AliasConstKind::Inherent { .. } + | ty::AliasConstKind::InherentSelf { .. } + | ty::AliasConstKind::InherentImpl { .. } ) => { if let Ok(InferOk { obligations, value: () }) = self diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 5427d14c55af9..dc29b6311cc7e 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -1095,10 +1095,14 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { } match alias_const.kind { - ty::AliasConstKind::Inherent { .. } => { + ty::AliasConstKind::InherentSelf { .. } => { self.add_wf_preds_for_inherent_projection(alias_const.into()); return; // Subtree is handled by above function } + // please ping khyperia and/or BoxyUwU if this `bug!` fires + ty::AliasConstKind::InherentImpl { .. } => bug!( + "This ought to be unreachable, the entrypoints of WF should still have InherentSelf-form alias consts." + ), ty::AliasConstKind::Projection { def_id } | ty::AliasConstKind::Free { def_id } | ty::AliasConstKind::Anon { def_id } => { diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 3710d41dba0d9..f826b2641bb15 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -147,12 +147,6 @@ fn normalize_canonicalized_inherent_projection<'tcx>( 0, &mut obligations, ); - obligations.extend(const_arg_has_type_obligation( - tcx, - param_env, - normalized_term, - goal, - )); ocx.register_obligations(obligations); Ok(NormalizationResult { normalized_term }) diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index cd35423c5ef14..d48438819040a 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -70,8 +70,15 @@ fn recurse_build<'tcx>( } &ExprKind::ZstLiteral { user_ty: _ } => ty::Const::zero_sized(tcx, node.ty), &ExprKind::NamedConst { def_id, args, user_ty: _ } => { - let uneval = - ty::AliasConst::new(tcx, ty::AliasConstKind::new_from_def_id(tcx, def_id), args); + let uneval = ty::AliasConst::new( + tcx, + ty::AliasConstKind::new_from_def_id( + tcx, + def_id, + ty::AliasConstInherentArgsKind::Impl, + ), + args, + ); ty::Const::new_alias(tcx, ty::IsRigid::No, uneval) } ExprKind::ConstParam { param, .. } => ty::Const::new_param(tcx, *param), diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 29c65974d8b28..26a4edccd0134 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -73,13 +73,7 @@ impl AliasConst { #[inline] pub fn new(interner: I, kind: AliasConstKind, args: I::GenericArgs) -> AliasConst { if cfg!(debug_assertions) { - let def_id = match kind { - ty::AliasConstKind::Projection { def_id } => def_id.into(), - ty::AliasConstKind::Inherent { def_id } => def_id.into(), - ty::AliasConstKind::Free { def_id } => def_id.into(), - ty::AliasConstKind::Anon { def_id } => def_id.into(), - }; - interner.debug_assert_args_compatible(def_id, args); + interner.debug_assert_alias_term_args_compatible(kind.into(), args); } AliasConst { kind, args, _use_alias_new_instead: () } } @@ -87,7 +81,12 @@ impl AliasConst { pub fn type_of(self, interner: I) -> ty::Unnormalized { let def_id = match self.kind { ty::AliasConstKind::Projection { def_id } => def_id.into(), - ty::AliasConstKind::Inherent { def_id } => def_id.into(), + ty::AliasConstKind::InherentSelf { .. } => { + panic!( + "AliasConst::type_of got InherentSelf - args should always be InherentImpl at this point" + ) + } + ty::AliasConstKind::InherentImpl { def_id } => def_id.into(), ty::AliasConstKind::Free { def_id } => def_id.into(), ty::AliasConstKind::Anon { def_id } => def_id.into(), }; @@ -107,23 +106,65 @@ impl AliasConst { pub enum AliasConstKind { /// A projection `::AssocConst` Projection { def_id: I::TraitAssocConstId }, - /// An associated constant in an inherent `impl` - Inherent { def_id: I::InherentAssocConstId }, + /// An associated const in an inherent `impl`. + /// + /// The generic args are in "Self form", i.e. + /// there is a single `Self` type parameter, followed by any GAT args on the inherent const + /// itself. + /// + /// The "impl form" args can be obtained by generating fresh vars for each of the impl params, + /// instantiating the impl block's Self type with the fresh vars, equating the resulting type + /// with the `Self` generic argument, and using the result of what the fresh vars resolved to as + /// the "impl form" args. Doing so without considering the extra predicates generated by the + /// equate is a lossy operation, consider the following impl block: + /// + /// ```rust,ignore (illustrative) + /// impl Struct<'static, T> { + /// const ASSOC: () = (); + /// } + /// ``` + /// + /// If we have `Struct::<'a, u32>::Assoc`, the Self args form would be `[Struct<'a, u32>, + /// usize]`. The "impl form" args would be `[u32, usize]`, with an extra constraint generated + /// that `'a == 'static`. Disregarding this extra constraint would be wrong. + /// + /// Hence, when HIR lowering wants to construct an inherent alias, it must use the "Self form" + /// to let the trait solver do the equate and consider additional constraints. + /// + /// FIXME(inherent_associated_types): This ideally ought be a list of candidate DefIds that a + /// path could resolve to, then the trait solver does the above-written routine to figure out + /// which exact impl to use. `InherentSelf` could be conceptually be thought of as corresponding + /// to `Projection` where the def_id is a trait, and `InherentImpl` is `Projection` where the + /// def_id is an impl. + InherentSelf { def_id: I::InherentAssocConstId }, + /// An associated const in an inherent `impl`. See [`Self::InherentSelf`] for a description on + /// the difference between `InherentSelf` and `InherentImpl`. + InherentImpl { def_id: I::InherentAssocConstId }, /// A free constant, outside an impl block. Free { def_id: I::FreeConstAliasId }, /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`. Anon { def_id: I::AnonConstId }, } +pub enum AliasConstInherentArgsKind { + WithSelf, + Impl, +} + impl AliasConstKind { - pub fn new_from_def_id(interner: I, def_id: I::DefId) -> Self { - interner.alias_const_kind_from_def_id(def_id) + pub fn new_from_def_id( + interner: I, + def_id: I::DefId, + inherent_args: AliasConstInherentArgsKind, + ) -> Self { + interner.alias_const_kind_from_def_id(def_id, inherent_args) } pub fn is_type_const(self, interner: I) -> bool { match self { AliasConstKind::Projection { def_id } => interner.is_type_const(def_id.into()), - AliasConstKind::Inherent { def_id } => interner.is_type_const(def_id.into()), + AliasConstKind::InherentSelf { def_id } => interner.is_type_const(def_id.into()), + AliasConstKind::InherentImpl { def_id } => interner.is_type_const(def_id.into()), AliasConstKind::Free { def_id } => interner.is_type_const(def_id.into()), AliasConstKind::Anon { def_id } => interner.is_type_const(def_id.into()), } @@ -132,7 +173,8 @@ impl AliasConstKind { pub fn def_span(self, interner: I) -> I::Span { match self { AliasConstKind::Projection { def_id } => interner.def_span(def_id.into()), - AliasConstKind::Inherent { def_id } => interner.def_span(def_id.into()), + AliasConstKind::InherentSelf { def_id } => interner.def_span(def_id.into()), + AliasConstKind::InherentImpl { def_id } => interner.def_span(def_id.into()), AliasConstKind::Free { def_id } => interner.def_span(def_id.into()), AliasConstKind::Anon { def_id } => interner.def_span(def_id.into()), } @@ -141,7 +183,8 @@ impl AliasConstKind { pub fn opt_def_id(self) -> Option { match self { AliasConstKind::Projection { def_id } => Some(def_id.into()), - AliasConstKind::Inherent { def_id } => Some(def_id.into()), + AliasConstKind::InherentSelf { def_id } => Some(def_id.into()), + AliasConstKind::InherentImpl { def_id } => Some(def_id.into()), AliasConstKind::Free { def_id } => Some(def_id.into()), AliasConstKind::Anon { def_id } => Some(def_id.into()), } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index d230791304527..7060bae7d12ec 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -21,8 +21,8 @@ use crate::solve::{ }; use crate::visit::{Flags, TypeVisitable}; use crate::{ - self as ty, BoundRegion, BoundVar, CanonicalParamEnvCache, DebruijnIndex, Region, RegionKind, - TraitRef, search_graph, + self as ty, AliasTermKind, BoundRegion, BoundVar, CanonicalParamEnvCache, DebruijnIndex, + Region, RegionKind, TraitRef, search_graph, }; /// The central trait in the shared abstraction layer, specifying all implementation-specific @@ -275,10 +275,18 @@ pub trait Interner: type AdtDef: AdtDef; fn adt_def(self, adt_def_id: Self::AdtId) -> Self::AdtDef; - fn alias_const_kind_from_def_id(self, def_id: Self::DefId) -> ty::AliasConstKind; + fn alias_const_kind_from_def_id( + self, + def_id: Self::DefId, + inherent_args: ty::AliasConstInherentArgsKind, + ) -> ty::AliasConstKind; // FIXME: remove in favor of explicit construction - fn alias_term_kind_from_def_id(self, def_id: Self::DefId) -> ty::AliasTermKind; + fn alias_term_kind_from_def_id( + self, + def_id: Self::DefId, + inherent_args: ty::AliasConstInherentArgsKind, + ) -> ty::AliasTermKind; fn trait_ref_and_own_args_for_alias( self, @@ -293,9 +301,18 @@ pub trait Interner: I: Iterator, T: CollectAndApply; - fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool; + fn check_alias_term_args_compatible( + self, + term_kind: AliasTermKind, + args: Self::GenericArgs, + ) -> bool; fn debug_assert_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs); + fn debug_assert_alias_term_args_compatible( + self, + term_kind: AliasTermKind, + args: Self::GenericArgs, + ); /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection` /// are compatible with the `DefId`. diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 7d281663d5033..7ad23d3e5432a 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -502,7 +502,10 @@ impl ExistentialProjection { ProjectionClause { projection_term: ty::AliasTerm::new( interner, - interner.alias_term_kind_from_def_id(self.def_id.into()), + interner.alias_term_kind_from_def_id( + self.def_id.into(), + ty::AliasConstInherentArgsKind::WithSelf, + ), [self_ty.into()].iter().chain(self.args.iter()), ), term: self.term, diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 98d251c6f1d64..f6491bac642e3 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -262,7 +262,8 @@ impl Relate for ty::AliasTerm { | ty::AliasTermKind::FreeConst { .. } | ty::AliasTermKind::FreeTy { .. } | ty::AliasTermKind::InherentTy { .. } - | ty::AliasTermKind::InherentConst { .. } + | ty::AliasTermKind::InherentConstSelf { .. } + | ty::AliasTermKind::InherentConstImpl { .. } | ty::AliasTermKind::AnonConst { .. } | ty::AliasTermKind::ProjectionConst { .. } => { relate_args_invariantly(relation, a.args, b.args)? @@ -281,8 +282,14 @@ impl Relate for ty::ExistentialProjection { ) -> RelateResult> { if a.def_id != b.def_id { Err(TypeError::ProjectionMismatched(ExpectedFound::new( - relation.cx().alias_term_kind_from_def_id(a.def_id.into()), - relation.cx().alias_term_kind_from_def_id(b.def_id.into()), + relation.cx().alias_term_kind_from_def_id( + a.def_id.into(), + ty::AliasConstInherentArgsKind::WithSelf, + ), + relation.cx().alias_term_kind_from_def_id( + b.def_id.into(), + ty::AliasConstInherentArgsKind::WithSelf, + ), ))) } else { let term = relation.relate_with_variance( diff --git a/compiler/rustc_type_ir/src/term_kind.rs b/compiler/rustc_type_ir/src/term_kind.rs index aed634d4f3a21..bb4ebf054d263 100644 --- a/compiler/rustc_type_ir/src/term_kind.rs +++ b/compiler/rustc_type_ir/src/term_kind.rs @@ -66,8 +66,12 @@ pub enum AliasTermKind { ProjectionConst { def_id: I::TraitAssocConstId }, /// A top level const item not part of a trait or impl. FreeConst { def_id: I::FreeConstAliasId }, - /// An associated const in an inherent `impl` - InherentConst { def_id: I::InherentAssocConstId }, + /// An associated const in an inherent `impl`. See [`ty::AliasConstKind::InherentSelf`] for a + /// description on the difference between `InherentConstSelf` and `InherentConstImpl`. + InherentConstSelf { def_id: I::InherentAssocConstId }, + /// An associated const in an inherent `impl`. See [`ty::AliasConstKind::InherentSelf`] for a + /// description on the difference between `InherentConstSelf` and `InherentConstImpl`. + InherentConstImpl { def_id: I::InherentAssocConstId }, } impl AliasTermKind { @@ -76,7 +80,9 @@ impl AliasTermKind { AliasTermKind::ProjectionTy { .. } => "associated type", AliasTermKind::ProjectionConst { .. } => "associated const", AliasTermKind::InherentTy { .. } => "inherent associated type", - AliasTermKind::InherentConst { .. } => "inherent associated const", + AliasTermKind::InherentConstSelf { .. } | AliasTermKind::InherentConstImpl { .. } => { + "inherent associated const" + } AliasTermKind::OpaqueTy { .. } => "opaque type", AliasTermKind::FreeTy { .. } => "type alias", AliasTermKind::FreeConst { .. } => "const alias", @@ -93,7 +99,8 @@ impl AliasTermKind { AliasTermKind::AnonConst { .. } | AliasTermKind::ProjectionConst { .. } - | AliasTermKind::InherentConst { .. } + | AliasTermKind::InherentConstSelf { .. } + | AliasTermKind::InherentConstImpl { .. } | AliasTermKind::FreeConst { .. } => false, } } @@ -106,7 +113,8 @@ impl AliasTermKind { | AliasTermKind::FreeTy { .. } | AliasTermKind::AnonConst { .. } | AliasTermKind::FreeConst { .. } - | AliasTermKind::InherentConst { .. } => false, + | AliasTermKind::InherentConstSelf { .. } + | AliasTermKind::InherentConstImpl { .. } => false, } } } @@ -126,7 +134,12 @@ impl From> for AliasTermKind { fn from(value: ty::AliasConstKind) -> Self { match value { ty::AliasConstKind::Projection { def_id } => AliasTermKind::ProjectionConst { def_id }, - ty::AliasConstKind::Inherent { def_id } => AliasTermKind::InherentConst { def_id }, + ty::AliasConstKind::InherentSelf { def_id } => { + AliasTermKind::InherentConstSelf { def_id } + } + ty::AliasConstKind::InherentImpl { def_id } => { + AliasTermKind::InherentConstImpl { def_id } + } ty::AliasConstKind::Free { def_id } => AliasTermKind::FreeConst { def_id }, ty::AliasConstKind::Anon { def_id } => AliasTermKind::AnonConst { def_id }, } @@ -140,17 +153,7 @@ impl AliasTerm { args: I::GenericArgs, ) -> AliasTerm { if cfg!(debug_assertions) { - let def_id = match kind { - AliasTermKind::ProjectionTy { def_id } => def_id.into(), - AliasTermKind::InherentTy { def_id } => def_id.into(), - AliasTermKind::OpaqueTy { def_id } => def_id.into(), - AliasTermKind::FreeTy { def_id } => def_id.into(), - AliasTermKind::AnonConst { def_id } => def_id.into(), - AliasTermKind::ProjectionConst { def_id } => def_id.into(), - AliasTermKind::FreeConst { def_id } => def_id.into(), - AliasTermKind::InherentConst { def_id } => def_id.into(), - }; - interner.debug_assert_args_compatible(def_id, args); + interner.debug_assert_alias_term_args_compatible(kind, args); } AliasTerm { kind, args, _use_alias_new_instead: () } } @@ -164,8 +167,13 @@ impl AliasTerm { Self::new_from_args(interner, kind, args) } - pub fn new_from_def_id(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm { - let kind = interner.alias_term_kind_from_def_id(def_id); + pub fn new_from_def_id( + interner: I, + def_id: I::DefId, + args: I::GenericArgs, + inherent_args: ty::AliasConstInherentArgsKind, + ) -> AliasTerm { + let kind = interner.alias_term_kind_from_def_id(def_id, inherent_args); Self::new_from_args(interner, kind, args) } @@ -175,7 +183,8 @@ impl AliasTerm { AliasTermKind::InherentTy { def_id } => ty::AliasTyKind::Inherent { def_id }, AliasTermKind::OpaqueTy { def_id } => ty::AliasTyKind::Opaque { def_id }, AliasTermKind::FreeTy { def_id } => ty::AliasTyKind::Free { def_id }, - kind @ (AliasTermKind::InherentConst { .. } + kind @ (AliasTermKind::InherentConstSelf { .. } + | AliasTermKind::InherentConstImpl { .. } | AliasTermKind::FreeConst { .. } | AliasTermKind::AnonConst { .. } | AliasTermKind::ProjectionConst { .. }) => { @@ -187,7 +196,12 @@ impl AliasTerm { pub fn expect_ct(self) -> ty::AliasConst { let kind = match self.kind { - AliasTermKind::InherentConst { def_id } => ty::AliasConstKind::Inherent { def_id }, + AliasTermKind::InherentConstSelf { def_id } => { + ty::AliasConstKind::InherentSelf { def_id } + } + AliasTermKind::InherentConstImpl { def_id } => { + ty::AliasConstKind::InherentImpl { def_id } + } AliasTermKind::FreeConst { def_id } => ty::AliasConstKind::Free { def_id }, AliasTermKind::AnonConst { def_id } => ty::AliasConstKind::Anon { def_id }, AliasTermKind::ProjectionConst { def_id } => ty::AliasConstKind::Projection { def_id }, @@ -212,8 +226,11 @@ impl AliasTerm { }; match self.kind { AliasTermKind::FreeConst { def_id } => alias_const(ty::AliasConstKind::Free { def_id }), - AliasTermKind::InherentConst { def_id } => { - alias_const(ty::AliasConstKind::Inherent { def_id }) + AliasTermKind::InherentConstSelf { def_id } => { + alias_const(ty::AliasConstKind::InherentSelf { def_id }) + } + AliasTermKind::InherentConstImpl { def_id } => { + alias_const(ty::AliasConstKind::InherentImpl { def_id }) } AliasTermKind::AnonConst { def_id } => alias_const(ty::AliasConstKind::Anon { def_id }), AliasTermKind::ProjectionConst { def_id } => { @@ -305,7 +322,8 @@ impl AliasTerm { pub fn expect_inherent_def_id(self) -> I::InherentAssocTermId { match self.kind { AliasTermKind::InherentTy { def_id } => def_id.into(), - AliasTermKind::InherentConst { def_id } => def_id.into(), + AliasTermKind::InherentConstSelf { def_id } => def_id.into(), + AliasTermKind::InherentConstImpl { def_id } => def_id.into(), kind => panic!("expected inherent alias, found {kind:?}"), } } @@ -327,7 +345,7 @@ impl AliasTerm { ) -> I::GenericArgs { debug_assert!(matches!( self.kind, - AliasTermKind::InherentTy { .. } | AliasTermKind::InherentConst { .. } + AliasTermKind::InherentTy { .. } | AliasTermKind::InherentConstSelf { .. } )); interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1))) } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 94e6be03c766f..3b84c8e9a1c35 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -483,13 +483,7 @@ impl fmt::Debug for TyKind { impl AliasTy { pub fn new_from_args(interner: I, kind: AliasTyKind, args: I::GenericArgs) -> AliasTy { if cfg!(debug_assertions) { - let def_id = match kind { - AliasTyKind::Projection { def_id } => def_id.into(), - AliasTyKind::Inherent { def_id } => def_id.into(), - AliasTyKind::Opaque { def_id } => def_id.into(), - AliasTyKind::Free { def_id } => def_id.into(), - }; - interner.debug_assert_args_compatible(def_id, args); + interner.debug_assert_alias_term_args_compatible(kind.into(), args); } AliasTy { kind, args, _use_alias_new_instead: () } } @@ -551,7 +545,10 @@ impl ProjectionAliasTy { kind: I::TraitAssocTyId, args: I::GenericArgs, ) -> Self { - interner.debug_assert_args_compatible(kind.into(), args); + interner.debug_assert_alias_term_args_compatible( + ty::AliasTermKind::ProjectionTy { def_id: kind }, + args, + ); Self { kind, args, _use_alias_new_instead: () } } @@ -622,7 +619,10 @@ impl InherentAliasTy { kind: I::InherentAssocTyId, args: I::GenericArgs, ) -> Self { - interner.debug_assert_args_compatible(kind.into(), args); + interner.debug_assert_alias_term_args_compatible( + ty::AliasTermKind::InherentTy { def_id: kind }, + args, + ); Self { kind, args, _use_alias_new_instead: () } } @@ -637,7 +637,10 @@ impl InherentAliasTy { impl OpaqueAliasTy { pub fn new_opaque_from_args(interner: I, kind: I::OpaqueTyId, args: I::GenericArgs) -> Self { - interner.debug_assert_args_compatible(kind.into(), args); + interner.debug_assert_alias_term_args_compatible( + ty::AliasTermKind::OpaqueTy { def_id: kind }, + args, + ); Self { kind, args, _use_alias_new_instead: () } } @@ -652,7 +655,10 @@ impl OpaqueAliasTy { impl FreeAliasTy { pub fn new_free_from_args(interner: I, kind: I::FreeTyAliasId, args: I::GenericArgs) -> Self { - interner.debug_assert_args_compatible(kind.into(), args); + interner.debug_assert_alias_term_args_compatible( + ty::AliasTermKind::FreeTy { def_id: kind }, + args, + ); Self { kind, args, _use_alias_new_instead: () } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index d13a3fdb864bf..012c4997db9c1 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -358,7 +358,8 @@ pub(crate) fn print_const(tcx: TyCtxt<'_>, n: ty::Const<'_>) -> String { ty::ConstKind::Alias(_, ty::AliasConst { kind, .. }) => { let def_id: DefId = match kind { ty::AliasConstKind::Projection { def_id } => def_id.into(), - ty::AliasConstKind::Inherent { def_id } => def_id.into(), + ty::AliasConstKind::InherentSelf { def_id } => def_id.into(), + ty::AliasConstKind::InherentImpl { def_id } => def_id.into(), ty::AliasConstKind::Free { def_id } => def_id.into(), ty::AliasConstKind::Anon { def_id } => def_id.into(), }; diff --git a/tests/ui/const-generics/gca/path-to-non-type-const.rs b/tests/ui/const-generics/gca/path-to-non-type-const.rs index 9deb517095cbd..53382fe4aa247 100644 --- a/tests/ui/const-generics/gca/path-to-non-type-const.rs +++ b/tests/ui/const-generics/gca/path-to-non-type-const.rs @@ -1,7 +1,12 @@ //@ check-pass //@ compile-flags: -Znext-solver -#![feature(min_generic_const_args, macroless_generic_const_args, generic_const_args)] +#![feature( + min_generic_const_args, + macroless_generic_const_args, + generic_const_args, + inherent_associated_types +)] #![expect(incomplete_features)] trait Trait { @@ -21,6 +26,14 @@ impl Trait for GenericStructImpl { const PROJECTED: usize = A; } +impl StructImpl { + const INHERENT: usize = 1; +} + +impl GenericStructImpl { + const INHERENT: usize = A; +} + struct Struct; fn f() { @@ -31,4 +44,6 @@ fn main() { let _ = Struct::; let _ = Struct::<{ ::PROJECTED }>; let _ = Struct::<{ as Trait>::PROJECTED }>; + let _ = Struct::<{ StructImpl::INHERENT }>; + let _ = Struct::<{ GenericStructImpl::<2>::INHERENT }>; } diff --git a/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.rs b/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.rs deleted file mode 100644 index d15341836e493..0000000000000 --- a/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! This test should be part of path-to-non-type-const.rs, and should pass. However, we are holding -//! off on implementing paths to IACs until a refactoring of how IAC generics are represented. -//@ compile-flags: -Znext-solver - -#![feature( - inherent_associated_types, - min_generic_const_args, - generic_const_args, - macroless_generic_const_args -)] -#![expect(incomplete_features)] - -struct StructImpl; -struct GenericStructImpl; - -impl StructImpl { - const INHERENT: usize = 1; -} - -impl GenericStructImpl { - const INHERENT: usize = A; -} - -struct Struct; - -fn main() { - let _ = Struct::<{ StructImpl::INHERENT }>; - //~^ ERROR use of `const` in the type system not defined as `type const` - let _ = Struct::<{ GenericStructImpl::<2>::INHERENT }>; - //~^ ERROR use of `const` in the type system not defined as `type const` -} diff --git a/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.stderr b/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.stderr deleted file mode 100644 index af671fb614e31..0000000000000 --- a/tests/ui/const-generics/gca/path-to-non-type-inherent-associated-const.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error: use of `const` in the type system not defined as `type const` - --> $DIR/path-to-non-type-inherent-associated-const.rs:27:24 - | -LL | let _ = Struct::<{ StructImpl::INHERENT }>; - | ^^^^^^^^^^^^^^^^^^^^ - | -help: add `type` before `const` for `StructImpl::INHERENT` - | -LL | type const INHERENT: usize = 1; - | ++++ - -error: use of `const` in the type system not defined as `type const` - --> $DIR/path-to-non-type-inherent-associated-const.rs:29:24 - | -LL | let _ = Struct::<{ GenericStructImpl::<2>::INHERENT }>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add `type` before `const` for `GenericStructImpl::::INHERENT` - | -LL | type const INHERENT: usize = A; - | ++++ - -error: aborting due to 2 previous errors - From 614d9ea42ce84b46371e653f882496877ce277b4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 30 Aug 2026 16:24:44 +0200 Subject: [PATCH 20/26] Fix invalid `compile-args` ui tests argument --- .../lints/renamed-lint-still-applies.stderr | 12 ++++++------ tests/ui/lint/forbid-error-capped.rs | 1 - tests/ui/lint/forbid-error-capped.stderr | 4 ++-- tests/ui/mir/issue-71793-inline-args-storage.rs | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr b/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr index 88807dfb495d0..f4428ff6e5983 100644 --- a/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr +++ b/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr @@ -1,5 +1,5 @@ warning: lint `broken_intra_doc_links` has been renamed to `rustdoc::broken_intra_doc_links` - --> $DIR/renamed-lint-still-applies.rs:2:9 + --> $DIR/renamed-lint-still-applies.rs:3:9 | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::broken_intra_doc_links` @@ -7,33 +7,33 @@ LL | #![deny(broken_intra_doc_links)] = note: `#[warn(renamed_and_removed_lints)]` on by default warning: lint `rustdoc::non_autolinks` has been renamed to `rustdoc::bare_urls` - --> $DIR/renamed-lint-still-applies.rs:7:9 + --> $DIR/renamed-lint-still-applies.rs:8:9 | LL | #![deny(rustdoc::non_autolinks)] | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::bare_urls` error: unresolved link to `x` - --> $DIR/renamed-lint-still-applies.rs:4:6 + --> $DIR/renamed-lint-still-applies.rs:5:6 | LL | //! [x] | ^ no item named `x` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` note: the lint level is defined here - --> $DIR/renamed-lint-still-applies.rs:2:9 + --> $DIR/renamed-lint-still-applies.rs:3:9 | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ error: this URL is not a hyperlink - --> $DIR/renamed-lint-still-applies.rs:9:5 + --> $DIR/renamed-lint-still-applies.rs:10:5 | LL | //! http://example.com | ^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links note: the lint level is defined here - --> $DIR/renamed-lint-still-applies.rs:7:9 + --> $DIR/renamed-lint-still-applies.rs:8:9 | LL | #![deny(rustdoc::non_autolinks)] | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/forbid-error-capped.rs b/tests/ui/lint/forbid-error-capped.rs index e458ddf90746e..bfa72beac5828 100644 --- a/tests/ui/lint/forbid-error-capped.rs +++ b/tests/ui/lint/forbid-error-capped.rs @@ -1,5 +1,4 @@ //@ check-pass -// compile-args: --cap-lints=warn -Fwarnings // This checks that the forbid attribute checking is ignored when the forbidden // lint is capped. diff --git a/tests/ui/lint/forbid-error-capped.stderr b/tests/ui/lint/forbid-error-capped.stderr index 479e7b9412d57..3de8c2fe0ce61 100644 --- a/tests/ui/lint/forbid-error-capped.stderr +++ b/tests/ui/lint/forbid-error-capped.stderr @@ -1,5 +1,5 @@ warning: allow(unused) incompatible with previous forbid - --> $DIR/forbid-error-capped.rs:8:10 + --> $DIR/forbid-error-capped.rs:7:10 | LL | #![forbid(warnings)] | -------- `forbid` level set here @@ -14,7 +14,7 @@ warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: warning: allow(unused) incompatible with previous forbid - --> $DIR/forbid-error-capped.rs:8:10 + --> $DIR/forbid-error-capped.rs:7:10 | LL | #![forbid(warnings)] | -------- `forbid` level set here diff --git a/tests/ui/mir/issue-71793-inline-args-storage.rs b/tests/ui/mir/issue-71793-inline-args-storage.rs index 0ed4d4723731e..38ce28a035346 100644 --- a/tests/ui/mir/issue-71793-inline-args-storage.rs +++ b/tests/ui/mir/issue-71793-inline-args-storage.rs @@ -1,10 +1,10 @@ // Verifies that inliner emits StorageLive & StorageDead when introducing // temporaries for arguments, so that they don't become part of the coroutine. // Regression test for #71793. -// + //@ check-pass //@ edition:2018 -// compile-args: -Zmir-opt-level=3 +//@ compile-flags: -Zmir-opt-level=3 #![crate_type = "lib"] From af2d4bc7bd39e7b3d2abae51881625b74b9f4486 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 30 Aug 2026 10:52:01 -0400 Subject: [PATCH 21/26] Switch dist-aarch64-linux to EC2 and update dist-x86_64-linux For dist-aarch64-linux (full): * GHA 8c takes 2h25m ($2.03/build) * c8g.8xl takes 1h20m ($1.69/build) * c9g.8xl takes 1h ($1.38/build) * c9g.4xl takes 1h10m ($0.81/build) * m9g.2xl takes 1h30m ($0.59/build) - selected And adds a dist-aarch64-linux-quick: * c8g.8xl takes 50m ($1.059/build) * c9g.8xl takes 40m ($0.924/build) * c9g.4xl takes 47m ($0.543/build) - selected * m9g.2xl takes 64m ($0.417/build) For now I've chosen a balance between cost and speed (c9g.4xl). Once we decide where to enable this (e.g., in try builds by default) we can consider aligning with other tasks and saving $/build if we're not able to benefit from increased speed (e.g., because perf won't run until the try build as a whole finishes). For dist-x86_64-linux-full we have this breakdown: * c8a.8xl takes 1h34m ($2.64/build) - current * c8a.4xl takes 1h45m ($1.51/build) - selected * m8a.2xl takes 2h10m ($1.05/build) I'll re-benchmark dist-x86_64-linux-quick in a future PR, for now it will stay on c8a.8xl. This drops codebuild configuration (but not yet cleaning up various related pieces that are more tied into our CI) since it doesn't seem relevant anymore. --- rust-bors.toml | 35 +++++++------------- src/ci/github-actions/jobs.yml | 60 +++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/rust-bors.toml b/rust-bors.toml index 02effccdeeeb3..527d44126bf2d 100644 --- a/rust-bors.toml +++ b/rust-bors.toml @@ -87,31 +87,20 @@ images = { "arm64ami" = "latest-gha-runner-ami-arm64", } jit_runner = "organization" +# Prices per hour of on-demand compute in us-east-2 (as of Aug 2026) +# See build speed estimates in https://github.com/rust-lang/simpleinfra/issues/1132 allowed_instances = [ - # AMD Zen 5 (x86_64) instances, a subset of these is used in production. - # Prices per hour of on-demand compute in us-east-2 (as of Aug 2026) - # See rough assessment of build speed for dist-x86_64-quick in https://github.com/rust-lang/simpleinfra/issues/1132 - # m8a.2x 8 vCPU, 32 GB $0.48688/hr - # c8a.4x 16 vCPU, 32 GB $0.86216/hr - # c8a.8x 32 vCPU, 64 GB $1.72432/hr - # c8a.12x 48 vCPU, 96 GB $2.58648/hr - # CodeBuild 36 vCPU $4.78799/hr - "m8a.2xlarge", - "c8a.4xlarge", - "c8a.8xlarge", - "c8a.12xlarge", + # AMD Zen 5 (x86_64) + "m8a.2xlarge", # $0.48688/hr + "c8a.4xlarge", # $0.86216/hr + "c8a.8xlarge", # $1.72432/hr + "c8a.12xlarge", # $2.58648/hr - # Graviton 4 (aarch64) instances, currently just for experimentation - "m8g.2xlarge", - "c8g.4xlarge", - "c8g.8xlarge", - "c8g.12xlarge", - - # Graviton 5 (aarch64) instances, currently just for experimentation - "m9g.2xlarge", - "c9g.4xlarge", - "c9g.8xlarge", - "c9g.12xlarge", + # Graviton (aarch64) + "m9g.2xlarge", # $0.39136/hr + "c9g.4xlarge", # $0.69312/hr + "c9g.8xlarge", # $1.38624/hr + "c9g.12xlarge", # $2.07936/hr ] # Enable unrolling of rollup member PRs after rollup merge diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 387d0b77f1af5..688d75589dd9a 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -41,24 +41,24 @@ runners: os: ubuntu-24.04-arm <<: *base-job - - &job-aarch64-linux-8c - os: ubuntu-24.04-arm64-8core-32gb + - &job-linux-x86-8c-ec2 + os: ec2-x86_64ami-m8a.2xlarge-x64-linux-$github.run_id-$github.run_attempt <<: *base-job - # Codebuild runners are provisioned in - # https://github.com/rust-lang/simpleinfra/blob/b7ddd5e6bec8a93ec30510cdddec02c5666fefe9/terragrunt/accounts/ci-prod/ci-runners/terragrunt.hcl#L2 - - &job-linux-36c-codebuild - free_disk: true - codebuild: true - os: codebuild-ubuntu-22-36c-$github.run_id-$github.run_attempt + - &job-linux-x86-16c-ec2 + os: ec2-x86_64ami-c8a.4xlarge-x64-linux-$github.run_id-$github.run_attempt <<: *base-job - &job-linux-x86-32c-ec2 os: ec2-x86_64ami-c8a.8xlarge-x64-linux-$github.run_id-$github.run_attempt <<: *base-job - - &job-linux-x86-8c-ec2 - os: ec2-x86_64ami-m8a.2xlarge-x64-linux-$github.run_id-$github.run_attempt + - &job-linux-aarch64-8c-ec2 + os: ec2-arm64ami-m9g.2xlarge-aarch64-linux-$github.run_id-$github.run_attempt + <<: *base-job + + - &job-linux-aarch64-16c-ec2 + os: ec2-arm64ami-c9g.4xlarge-aarch64-linux-$github.run_id-$github.run_attempt <<: *base-job envs: @@ -96,6 +96,11 @@ jobs: IMAGE: dist-x86_64-linux CODEGEN_BACKENDS: llvm,cranelift DOCKER_SCRIPT: dist.sh + dist-aarch64-linux: &job-dist-aarch64-linux + name: dist-aarch64-linux + env: + IMAGE: dist-aarch64-linux + CODEGEN_BACKENDS: llvm,cranelift # Jobs that run on each push to a pull request (PR). @@ -167,6 +172,17 @@ pr: try: - <<: [*job-dist-x86_64-linux, *job-linux-x86-32c-ec2] name: dist-x86_64-linux-quick + env: + IMAGE: dist-x86_64-linux + CODEGEN_BACKENDS: llvm,cranelift + DOCKER_SCRIPT: dist.sh + DIST_TRY_BUILD: 1 + - <<: [*job-dist-aarch64-linux, *job-linux-aarch64-16c-ec2] + name: dist-aarch64-linux-quick + env: + IMAGE: dist-aarch64-linux + CODEGEN_BACKENDS: llvm,cranelift + DIST_TRY_BUILD: 1 # Jobs that only run when explicitly invoked in one of the following ways: # - comment `@bors try jobs=` @@ -178,19 +194,20 @@ optional: env: IMAGE: pr-check-1 <<: *job-linux-4c - - <<: [*job-dist-x86_64-linux, *job-linux-36c-codebuild] - name: dist-x86_64-linux-codebuild - - <<: [*job-dist-x86_64-linux, *job-linux-36c-codebuild] - name: dist-x86_64-linux-quick-codebuild + # Duplicate the try jobs here so that we can run them via jobs=... + - <<: [*job-dist-x86_64-linux, *job-linux-x86-32c-ec2] + name: dist-x86_64-linux-quick env: IMAGE: dist-x86_64-linux CODEGEN_BACKENDS: llvm,cranelift DOCKER_SCRIPT: dist.sh DIST_TRY_BUILD: 1 - # We repeat the try job here so that it can be explicitly executed using `@bors try jobs`, to test - # full x64 Linux dist try builds on EC2. - - <<: [*job-dist-x86_64-linux, *job-linux-x86-32c-ec2] - name: dist-x86_64-linux-quick + - <<: [*job-dist-aarch64-linux, *job-linux-aarch64-16c-ec2] + name: dist-aarch64-linux-quick + env: + IMAGE: dist-aarch64-linux + CODEGEN_BACKENDS: llvm,cranelift + DIST_TRY_BUILD: 1 # Main CI jobs that have to be green to merge a commit into the default branch. # @@ -218,10 +235,7 @@ auto: - name: armhf-gnu <<: *job-linux-4c - - name: dist-aarch64-linux - env: - CODEGEN_BACKENDS: llvm,cranelift - <<: *job-aarch64-linux-8c + - <<: [*job-dist-aarch64-linux, *job-linux-aarch64-16c-ec2] - name: dist-android <<: *job-linux-4c @@ -298,7 +312,7 @@ auto: - name: dist-x86_64-illumos <<: *job-linux-4c - - <<: [*job-dist-x86_64-linux, *job-linux-x86-32c-ec2] + - <<: [*job-dist-x86_64-linux, *job-linux-x86-16c-ec2] - name: dist-x86_64-linux-alt env: From 1483f9b6e80530193d7b3b94b154a33b446643cb Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Mon, 31 Aug 2026 16:03:50 +0200 Subject: [PATCH 22/26] remove `_{style}` recovery for diagnostic structs --- .../rustc_macros/src/diagnostics/utils.rs | 63 ++++--------------- compiler/rustc_macros/src/lib.rs | 10 +-- .../src/diagnostics/diagnostic-structs.md | 20 ++++-- .../subdiagnostic-derive-inline.rs | 6 +- .../subdiagnostic-derive-inline.stderr | 32 ++++++---- 5 files changed, 54 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 3cace48e3fb27..b030f0e07b2d6 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -13,7 +13,6 @@ use syn::spanned::Spanned; use syn::{Attribute, Field, LitStr, Meta, Path, Token, Type, TypeTuple, parenthesized}; use synstructure::{BindingInfo, VariantInfo}; -use super::error::invalid_attr; use crate::diagnostics::error::{ DiagnosticDeriveError, span_err, throw_invalid_attr, throw_span_err, }; @@ -542,16 +541,6 @@ impl SuggestionKind { } } } - - fn from_suffix(s: &str) -> Option { - match s { - "" => Some(SuggestionKind::Normal), - "_short" => Some(SuggestionKind::Short), - "_hidden" => Some(SuggestionKind::Hidden), - "_verbose" => Some(SuggestionKind::Verbose), - _ => None, - } - } } /// Types of subdiagnostics that can be created using attributes @@ -569,7 +558,7 @@ pub(super) enum SubdiagnosticKind { HelpOnce, /// `#[warning(...)]` Warn, - /// `#[suggestion{,_short,_hidden,_verbose}]` + /// `#[suggestion(..)]` Suggestion { suggestion_kind: SuggestionKind, applicability: SpannedOption, @@ -580,7 +569,7 @@ pub(super) enum SubdiagnosticKind { /// `let __formatted_code = /* whatever */;` code_init: TokenStream, }, - /// `#[multipart_suggestion{,_short,_hidden,_verbose}]` + /// `#[multipart_suggestion(..)]` MultipartSuggestion { suggestion_kind: SuggestionKind, applicability: SpannedOption, @@ -618,44 +607,18 @@ impl SubdiagnosticVariant { "help" => SubdiagnosticKind::Help, "help_once" => SubdiagnosticKind::HelpOnce, "warning" => SubdiagnosticKind::Warn, + "suggestion" => SubdiagnosticKind::Suggestion { + suggestion_kind: SuggestionKind::Normal, + applicability: None, + code_field: new_code_ident(), + code_init: TokenStream::new(), + }, + "multipart_suggestion" => SubdiagnosticKind::MultipartSuggestion { + suggestion_kind: SuggestionKind::Normal, + applicability: None, + }, _ => { - // Recover old `#[(multipart_)suggestion_*]` syntaxes - // FIXME(#100717): remove - if let Some(suggestion_kind) = - name.strip_prefix("suggestion").and_then(SuggestionKind::from_suffix) - { - if suggestion_kind != SuggestionKind::Normal { - invalid_attr(attr) - .help(format!( - r#"Use `#[suggestion(..., style = "{suggestion_kind}")]` instead"# - )) - .emit(); - } - - SubdiagnosticKind::Suggestion { - suggestion_kind: SuggestionKind::Normal, - applicability: None, - code_field: new_code_ident(), - code_init: TokenStream::new(), - } - } else if let Some(suggestion_kind) = - name.strip_prefix("multipart_suggestion").and_then(SuggestionKind::from_suffix) - { - if suggestion_kind != SuggestionKind::Normal { - invalid_attr(attr) - .help(format!( - r#"Use `#[multipart_suggestion(..., style = "{suggestion_kind}")]` instead"# - )) - .emit(); - } - - SubdiagnosticKind::MultipartSuggestion { - suggestion_kind: SuggestionKind::Normal, - applicability: None, - } - } else { - throw_invalid_attr!(attr); - } + throw_invalid_attr!(attr); } }; diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index ec7495f95ac3a..f632862dc4627 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -191,10 +191,7 @@ decl_derive!( primary_span, label, subdiagnostic, - suggestion, - suggestion_short, - suggestion_hidden, - suggestion_verbose)] => + suggestion)] => #[doc = "See "] diagnostics::diagnostic_derive ); @@ -209,12 +206,7 @@ decl_derive!( warning, subdiagnostic, suggestion, - suggestion_short, - suggestion_hidden, - suggestion_verbose, multipart_suggestion, - multipart_suggestion_short, - multipart_suggestion_hidden, // field attributes primary_span, suggestion_part, diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md index 6a450909eb8a4..d5a218dfa87c0 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md @@ -152,7 +152,7 @@ tcx.dcx().emit_err(FieldAlreadyDeclared { - _Applied to struct or struct fields of type `Span`, `Option<()>`, `bool`, or `()`._ - Adds a warning subdiagnostic. - Value is the warning's message. -- `#[suggestion{,_hidden,_short,_verbose}("message", code = "...", applicability = "...")]` +- `#[suggestion("message", code = "...", applicability = "...", style = "...")]` (_Optional_) - _Applied to `(Span, MachineApplicability)` or `Span` fields._ - Adds a suggestion subdiagnostic. @@ -165,6 +165,9 @@ tcx.dcx().emit_err(FieldAlreadyDeclared { - `applicability = "..."` (_Optional_) - String which must be one of `machine-applicable`, `maybe-incorrect`, `has-placeholders` or `unspecified`. + - `style = "..."` (_Optional_) + - Value is the style of the suggestion. + - String which must be one of `normal`, `short`, `hidden`, `verbose` or `tool-only`. - `#[subdiagnostic]` - _Applied to a type that implements `Subdiagnostic` (from `#[derive(Subdiagnostic)]`)._ - Adds the subdiagnostic represented by the subdiagnostic struct. @@ -209,7 +212,7 @@ Each `Subdiagnostic` should have one attribute applied to the struct or each var - `#[note(..)]` for defining a note - `#[help(..)]` for defining a help - `#[warning(..)]` for defining a warning -- `#[suggestion{,_hidden,_short,_verbose}(..)]` for defining a suggestion +- `#[suggestion(..)]` for defining a suggestion All of the above must provide a diagnostic message as the first positional argument. See [translation documentation](./translation.md) to learn more about how @@ -305,7 +308,7 @@ Additionally, subdiagnostics can access arguments from the main diagnostic with - Message (_Mandatory_) - The diagnostic message that will be shown to the user. - See [translation documentation](./translation.md). -- `#[suggestion{,_hidden,_short,_verbose}("message", code = "...", applicability = "...")]` +- `#[suggestion("message", code = "...", applicability = "...", style = "...")]` - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._ - _Mandatory_ @@ -324,13 +327,22 @@ Additionally, subdiagnostics can access arguments from the main diagnostic with - `maybe-incorrect` - `has-placeholders` - `unspecified` -- `#[multipart_suggestion{,_hidden,_short,_verbose}("message", applicability = "...")]` + - `style = "..."` (_Optional_) + - Value is the style of the suggestion. + - String which must be one of: + - `normal` (the default) + - `short` + - `hidden` + - `verbose` + - `tool-only` +- `#[multipart_suggestion("message", applicability = "...", style = "...")]` - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._ - _Mandatory_ - Defines the type to be representing a multipart suggestion. - Message (_Mandatory_): see `#[suggestion]` - `applicability = "..."` (_Optional_): see `#[suggestion]` + - `style = "..."` (_Optional_): see `#[suggestion]` - `#[primary_span]` (_Mandatory_ for labels and suggestions; _optional_ otherwise; not applicable to multipart suggestions) - _Applied to `Span` fields._ diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs index 1bec8ac03c981..1d60b3e0733ec 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs @@ -746,7 +746,8 @@ struct SuggestionStyleTwice { #[derive(Subdiagnostic)] #[suggestion_hidden("example message", code = "")] -//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute +//~^ ERROR cannot find attribute `suggestion_hidden` in this scope +//~| ERROR derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute struct SuggestionStyleOldSyntax { #[primary_span] sub: Span, @@ -754,7 +755,8 @@ struct SuggestionStyleOldSyntax { #[derive(Subdiagnostic)] #[suggestion_hidden("example message", code = "", style = "normal")] -//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute +//~^ ERROR cannot find attribute `suggestion_hidden` in this scope +//~| ERROR derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute struct SuggestionStyleOldAndNewSyntax { #[primary_span] sub: Span, diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr index cf3c9dd9ce10d..23999437d2876 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr @@ -439,19 +439,15 @@ error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute | LL | #[suggestion_hidden("example message", code = "")] | ^ - | - = help: Use `#[suggestion(..., style = "hidden")]` instead error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:756:1 + --> $DIR/subdiagnostic-derive-inline.rs:757:1 | LL | #[suggestion_hidden("example message", code = "", style = "normal")] | ^ - | - = help: Use `#[suggestion(..., style = "hidden")]` instead error: derive(Diagnostic): invalid suggestion style - --> $DIR/subdiagnostic-derive-inline.rs:764:52 + --> $DIR/subdiagnostic-derive-inline.rs:766:52 | LL | #[suggestion("example message", code = "", style = "foo")] | ^^^^^ @@ -459,25 +455,25 @@ LL | #[suggestion("example message", code = "", style = "foo")] = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` error: expected string literal - --> $DIR/subdiagnostic-derive-inline.rs:772:52 + --> $DIR/subdiagnostic-derive-inline.rs:774:52 | LL | #[suggestion("example message", code = "", style = 42)] | ^^ error: expected `=` - --> $DIR/subdiagnostic-derive-inline.rs:780:49 + --> $DIR/subdiagnostic-derive-inline.rs:782:49 | LL | #[suggestion("example message", code = "", style)] | ^ error: expected `=` - --> $DIR/subdiagnostic-derive-inline.rs:788:49 + --> $DIR/subdiagnostic-derive-inline.rs:790:49 | LL | #[suggestion("example message", code = "", style("foo"))] | ^ error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:799:5 + --> $DIR/subdiagnostic-derive-inline.rs:801:5 | LL | #[primary_span] | ^ @@ -486,7 +482,7 @@ LL | #[primary_span] = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive-inline.rs:796:1 + --> $DIR/subdiagnostic-derive-inline.rs:798:1 | LL | #[suggestion("example message", code = "")] | ^ @@ -545,5 +541,17 @@ error: cannot find attribute `bar` in this scope LL | #[bar("...")] | ^^^ -error: aborting due to 82 previous errors +error: cannot find attribute `suggestion_hidden` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:748:3 + | +LL | #[suggestion_hidden("example message", code = "")] + | ^^^^^^^^^^^^^^^^^ + +error: cannot find attribute `suggestion_hidden` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:757:3 + | +LL | #[suggestion_hidden("example message", code = "", style = "normal")] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 84 previous errors From e18a0126ea0117055c6ec55d16630f1d3228b018 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Mon, 31 Aug 2026 19:12:19 +0200 Subject: [PATCH 23/26] Move track_caller on closures gating to attribute parsing --- Cargo.lock | 1 + compiler/rustc_ast_lowering/Cargo.toml | 1 + compiler/rustc_ast_lowering/src/expr.rs | 42 ++++++------------- .../rustc_ast_lowering/src/expr/closure.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 2 +- .../src/attributes/codegen_attrs.rs | 9 ++++ .../rustc_codegen_ssa/src/codegen_attrs.rs | 15 +------ 7 files changed, 26 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7cb05bce70ec4..d83a93c31b276 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3634,6 +3634,7 @@ version = "0.0.0" dependencies = [ "rustc_abi", "rustc_ast", + "rustc_attr_ir", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index f7128e66193a8..9dc5f81581e87 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -10,6 +10,7 @@ doctest = false # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index db0dd2fcc6191..4d5b98fd1ac00 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -3,19 +3,19 @@ use std::ops::ControlFlow; use std::sync::Arc; use rustc_ast::node_id::NodeMap; +use rustc_ast::visit::{Visitor, walk_expr}; use rustc_ast::*; +use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::target::Target; use rustc_errors::msg; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_hir::HirId; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{HirId, Target, find_attr}; use rustc_middle::span_bug; use rustc_middle::ty::TyCtxt; use rustc_session::diagnostics::report_lit_error; use rustc_span::{ByteSymbol, DUMMY_SP, DesugaringKind, Ident, Span, Spanned, Symbol, respan, sym}; use thin_vec::{ThinVec, thin_vec}; -use visit::{Visitor, walk_expr}; - mod closure; use crate::diagnostics::{ @@ -882,35 +882,17 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Forwards a possible `#[track_caller]` annotation from `outer_hir_id` to /// `inner_hir_id` in case the `async_fn_track_caller` feature is enabled. - pub(super) fn maybe_forward_track_caller( - &mut self, - span: Span, - outer_hir_id: HirId, - inner_hir_id: HirId, - ) { + pub(super) fn maybe_forward_track_caller(&mut self, outer_hir_id: HirId, inner_hir_id: HirId) { if self.tcx.features().async_fn_track_caller() && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id) - && find_attr!(*attrs, TrackCaller(_)) + && let Some(t) = attrs.iter().find(|a| { + matches!( + a, + rustc_attr_ir::Attribute::Parsed(rustc_attr_ir::AttributeKind::TrackCaller(_)) + ) + }) { - let unstable_span = self.mark_span_with_reason( - DesugaringKind::Async, - span, - Some(Arc::clone(&self.allow_gen_future)), - ); - self.lower_attrs( - inner_hir_id, - &[Attribute { - kind: AttrKind::Normal(Box::new(NormalAttr::from_ident(Ident::new( - sym::track_caller, - span, - )))), - id: self.tcx.sess.psess.attr_id_generator.mk_attr_id(), - style: AttrStyle::Outer, - span: unstable_span, - }], - span, - Target::Fn, - ); + self.attrs.insert(inner_hir_id.local_id, std::slice::from_ref(t)); } } diff --git a/compiler/rustc_ast_lowering/src/expr/closure.rs b/compiler/rustc_ast_lowering/src/expr/closure.rs index 8c5c55e07fb04..2831fb4fa8352 100644 --- a/compiler/rustc_ast_lowering/src/expr/closure.rs +++ b/compiler/rustc_ast_lowering/src/expr/closure.rs @@ -343,7 +343,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }); - this.maybe_forward_track_caller(body.span, closure_hir_id, expr.hir_id); + this.maybe_forward_track_caller(closure_hir_id, expr.hir_id); (parameters, expr) }); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d5ef2f9e832dd..1ad96d1057042 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1462,7 +1462,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // FIXME(async_fn_track_caller): Can this be moved above? let hir_id = expr.hir_id; - this.maybe_forward_track_caller(body.span, fn_id, hir_id); + this.maybe_forward_track_caller(fn_id, hir_id); (parameters, expr) }) diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 8905cd704c6c4..bff7d7ad81cb9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -364,6 +364,15 @@ impl NoArgsAttributeParser for TrackCallerParser { }); } } + Target::Closure if !cx.features().closure_track_caller() => { + feature_err( + cx.sess(), + sym::closure_track_caller, + attr_span, + "`#[track_caller]` on closures is currently unstable", + ) + .emit(); + } _ => {} } } diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index aae300d2f9ed5..b753ff25b1b5b 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -15,8 +15,7 @@ use rustc_middle::middle::codegen_fn_attrs::{ use rustc_middle::mono::Visibility; use rustc_middle::query::Providers; use rustc_middle::ty::{self as ty, TyCtxt}; -use rustc_session::diagnostics::feature_err; -use rustc_span::{Span, sym}; +use rustc_span::Span; use rustc_target::spec::Os; use crate::diagnostics; @@ -155,18 +154,6 @@ fn process_builtin_attrs( // This error is already reported in `rustc_ast_passes/src/ast_validation.rs`. tcx.dcx().delayed_bug("`#[track_caller]` requires the Rust ABI"); } - if is_closure - && !tcx.features().closure_track_caller() - && !attr_span.allows_unstable(sym::closure_track_caller) - { - feature_err( - &tcx.sess, - sym::closure_track_caller, - *attr_span, - "`#[track_caller]` on closures is currently unstable", - ) - .emit(); - } codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER } AttributeKind::Used { used_by } => match used_by { From 9f89751ce757eb17da891b958924a43174d6bd32 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Fri, 28 Aug 2026 13:22:55 +0000 Subject: [PATCH 24/26] Move polonius loan liveness computation prior to RegionInferenceContext::new --- compiler/rustc_borrowck/src/nll.rs | 23 ++++++++++++------- compiler/rustc_borrowck/src/polonius/mod.rs | 16 +++++++------ .../rustc_borrowck/src/region_infer/mod.rs | 7 ------ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 672b58fcbfbea..f4a1edb0b675d 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -126,7 +126,7 @@ pub(crate) fn compute_regions<'tcx>( let polonius_output = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_output()) || infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled(); - let lowered_constraints = compute_sccs_applying_placeholder_outlives_constraints( + let mut lowered_constraints = compute_sccs_applying_placeholder_outlives_constraints( constraints, &universal_region_relations, infcx, @@ -144,6 +144,20 @@ pub(crate) fn compute_regions<'tcx>( &lowered_constraints, ); + // If requested for `-Zpolonius=next`, compute loan liveness information. + // This is done prior to `RegionInferenceContext::new`, because we may add + // additional liveness constraints. + if let Some(polonius_context) = polonius_context.as_mut() { + let _timer = infcx.tcx.prof.generic_activity("borrowck_polonius_loan_liveness"); + polonius_context.compute_loan_liveness( + &mut lowered_constraints.liveness_constraints, + lowered_constraints.outlives_constraints.outlives().iter().copied(), + &universal_region_relations.universal_regions, + body, + borrow_set, + ); + } + let mut regioncx = RegionInferenceContext::new( infcx, lowered_constraints, @@ -151,13 +165,6 @@ pub(crate) fn compute_regions<'tcx>( location_map, ); - // If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives constraints - // and use them to compute loan liveness. - if let Some(polonius_context) = polonius_context.as_mut() { - let _timer = infcx.tcx.prof.generic_activity("borrowck_polonius_loan_liveness"); - polonius_context.compute_loan_liveness(&mut regioncx, body, borrow_set) - } - // If requested: dump NLL facts, and run legacy polonius analysis. let polonius_output = polonius_facts.as_ref().and_then(|polonius_facts| { if infcx.tcx.sess.opts.unstable_opts.nll_facts { diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs index 45108bfcb79ba..1c9242a3127a9 100644 --- a/compiler/rustc_borrowck/src/polonius/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/mod.rs @@ -48,9 +48,11 @@ use rustc_mir_dataflow::points::PointIndex; pub(self) use self::constraints::*; pub(crate) use self::dump::dump_polonius_mir; +use crate::BorrowSet; +use crate::constraints::OutlivesConstraint; use crate::dataflow::BorrowIndex; use crate::region_infer::values::LivenessValues; -use crate::{BorrowSet, RegionInferenceContext}; +use crate::universal_regions::UniversalRegions; pub(crate) type LiveLoans = SparseBitMatrix; @@ -101,19 +103,19 @@ impl PoloniusContext { /// The constraint data will be used to compute errors and diagnostics. pub(crate) fn compute_loan_liveness<'tcx>( &mut self, - regioncx: &mut RegionInferenceContext<'tcx>, + liveness: &mut LivenessValues, + outlives_constraints: impl Iterator>, + universal_regions: &UniversalRegions<'tcx>, body: &Body<'tcx>, borrow_set: &BorrowSet<'tcx>, ) { - let liveness = regioncx.liveness_constraints(); - // We don't need to prepare the graph (index NLL constraints, etc.) if we have no loans to // trace throughout localized constraints. if borrow_set.len() > 0 { // From the outlives constraints, liveness, and variances, we can compute reachability // on the lazy localized constraint graph to trace the liveness of loans, for the next // step in the chain (the NLL loan scope and active loans computations). - let graph = LocalizedConstraintGraph::new(liveness, regioncx.outlives_constraints()); + let graph = LocalizedConstraintGraph::new(liveness, outlives_constraints); let mut live_loans = LiveLoans::new(borrow_set.len()); let mut visitor = LoanLivenessVisitor { liveness, live_loans: &mut live_loans }; @@ -121,11 +123,11 @@ impl PoloniusContext { body, liveness, &self.live_region_variances, - regioncx.universal_regions(), + universal_regions, borrow_set, &mut visitor, ); - regioncx.record_live_loans(live_loans); + liveness.record_live_loans(live_loans); // The graph can be traversed again during MIR dumping, so we store it here. self.graph = Some(graph); diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 19aa4081bfc88..d3fc7152acc44 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -30,7 +30,6 @@ use crate::constraints::{ConstraintSccIndex, OutlivesConstraint, OutlivesConstra use crate::dataflow::BorrowIndex; use crate::diagnostics::{RegionErrorKind, RegionErrors, UniverseInfo}; use crate::handle_placeholders::{LoweredConstraints, RegionTracker}; -use crate::polonius::LiveLoans; use crate::polonius::legacy::PoloniusOutput; use crate::region_infer::values::{LivenessValues, RegionElement, RegionValues}; use crate::type_check::Locations; @@ -1874,12 +1873,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self.liveness_constraints } - /// When using `-Zpolonius=next`, records the given live loans for the loan scopes and active - /// loans dataflow computations. - pub(crate) fn record_live_loans(&mut self, live_loans: LiveLoans) { - self.liveness_constraints.record_live_loans(live_loans); - } - /// Returns whether the `loan_idx` is live at the given `location`: whether its issuing /// region is contained within the type of a variable that is live at this point. /// Note: for now, the sets of live loans is only available when using `-Zpolonius=next`. From 6ad5c1731c751fb25781cc3f7e74730b019544e9 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Fri, 28 Aug 2026 13:35:17 +0000 Subject: [PATCH 25/26] Move record_live_region_variance to be a freestanding function --- .../src/polonius/liveness_constraints.rs | 32 +++++++++---------- compiler/rustc_borrowck/src/polonius/mod.rs | 5 +-- .../src/type_check/liveness/mod.rs | 9 ++++-- .../src/type_check/liveness/trace.rs | 5 +-- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs index b6f8b4a79f39b..4009a85180571 100644 --- a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs +++ b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs @@ -6,25 +6,23 @@ use rustc_middle::ty::relate::{ }; use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeVisitable}; -use super::{ConstraintDirection, PoloniusContext}; +use super::ConstraintDirection; use crate::universal_regions::UniversalRegions; -impl PoloniusContext { - /// Record the variance of each region contained within the given value. - pub(crate) fn record_live_region_variance<'tcx>( - &mut self, - tcx: TyCtxt<'tcx>, - universal_regions: &UniversalRegions<'tcx>, - value: impl TypeVisitable> + Relate>, - ) { - let mut extractor = VarianceExtractor { - tcx, - ambient_variance: ty::Variance::Covariant, - directions: &mut self.live_region_variances, - universal_regions, - }; - extractor.relate(value, value).expect("Can't have a type error relating to itself"); - } +/// Record the variance of each region contained within the given value. +pub(crate) fn record_live_region_variance<'tcx>( + tcx: TyCtxt<'tcx>, + live_region_variances: &mut BTreeMap, + universal_regions: &UniversalRegions<'tcx>, + value: impl TypeVisitable> + Relate>, +) { + let mut extractor = VarianceExtractor { + tcx, + ambient_variance: ty::Variance::Covariant, + directions: live_region_variances, + universal_regions, + }; + extractor.relate(value, value).expect("Can't have a type error relating to itself"); } /// Extracts variances for regions contained within types. Follows the same structure as diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs index 1c9242a3127a9..cbac05d2eff67 100644 --- a/compiler/rustc_borrowck/src/polonius/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/mod.rs @@ -48,6 +48,7 @@ use rustc_mir_dataflow::points::PointIndex; pub(self) use self::constraints::*; pub(crate) use self::dump::dump_polonius_mir; +pub(crate) use self::liveness_constraints::record_live_region_variance; use crate::BorrowSet; use crate::constraints::OutlivesConstraint; use crate::dataflow::BorrowIndex; @@ -67,7 +68,7 @@ pub(crate) struct PoloniusContext { /// The expected edge direction per live region: the kind of directed edge we'll create as /// liveness constraints depends on the variance of types with respect to each contained region. - live_region_variances: BTreeMap, + pub(crate) live_region_variances: BTreeMap, /// The regions that outlive free regions are used to distinguish relevant live locals from /// boring locals. A boring local is one whose type contains only such regions. Polonius @@ -79,7 +80,7 @@ pub(crate) struct PoloniusContext { /// The direction a constraint can flow into. Used to create liveness constraints according to /// variance. #[derive(Copy, Clone, PartialEq, Eq, Debug)] -enum ConstraintDirection { +pub(crate) enum ConstraintDirection { /// For covariant cases, we add a forward edge `O at P1 -> O at P2`. Forward, diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index fd8502773c51e..189a1634e56f8 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -11,7 +11,7 @@ use tracing::debug; use super::TypeChecker; use crate::constraints::OutlivesConstraintSet; -use crate::polonius::PoloniusContext; +use crate::polonius::{PoloniusContext, record_live_region_variance}; use crate::region_infer::values::LivenessValues; use crate::universal_regions::UniversalRegions; @@ -220,7 +220,12 @@ impl<'a, 'tcx> LiveVariablesVisitor<'a, 'tcx> { // When using `-Zpolonius=next`, we record the variance of each live region. if let Some(polonius_context) = self.polonius_context { - polonius_context.record_live_region_variance(self.tcx, self.universal_regions, value); + record_live_region_variance( + self.tcx, + &mut polonius_context.live_region_variances, + self.universal_regions, + value, + ); } } } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index fe20bb6c28c0c..33e2da693ed1e 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -19,7 +19,7 @@ use rustc_trait_selection::traits::query::dropck_outlives; use rustc_trait_selection::traits::query::type_op::{DropckOutlives, TypeOpOutput}; use tracing::debug; -use crate::polonius; +use crate::polonius::{self, record_live_region_variance}; use crate::region_infer::values; use crate::type_check::liveness::local_use_map::LocalUseMap; use crate::type_check::{NormalizeLocation, TypeChecker}; @@ -627,8 +627,9 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> { // When using `-Zpolonius=next`, we record the variance of each live region. if let Some(polonius_context) = typeck.polonius_context.as_mut() { - polonius_context.record_live_region_variance( + record_live_region_variance( typeck.infcx.tcx, + &mut polonius_context.live_region_variances, typeck.universal_regions, value, ); From b58ee5bb9a6171b5b4519a237f0bdcef2a5e7eb2 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Fri, 28 Aug 2026 14:50:00 +0000 Subject: [PATCH 26/26] Minor trace updates --- .../src/type_check/liveness/mod.rs | 2 +- .../src/type_check/liveness/trace.rs | 80 ++++++++----------- 2 files changed, 36 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index 189a1634e56f8..dfab2fd071773 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -67,7 +67,7 @@ pub(super) fn generate<'tcx>( let (relevant_live_locals, boring_locals) = compute_relevant_live_locals(typeck.tcx(), &free_regions, typeck.body); - trace::trace(typeck, location_map, move_data, relevant_live_locals, boring_locals); + trace::trace(typeck, location_map, move_data, &relevant_live_locals, &boring_locals); // Mark regions that should be live where they appear within rvalues or within a call: like // args, regions, and types. diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 33e2da693ed1e..89a8899a991c9 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -3,7 +3,7 @@ use rustc_index::bit_set::DenseBitSet; use rustc_index::interval::IntervalSet; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::traits::TraitErrors; -use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, HasLocalDecls, Local, Location}; +use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location}; use rustc_middle::traits::query::DropckOutlivesResult; use rustc_middle::ty::relate::Relate; use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt}; @@ -19,6 +19,7 @@ use rustc_trait_selection::traits::query::dropck_outlives; use rustc_trait_selection::traits::query::type_op::{DropckOutlives, TypeOpOutput}; use tracing::debug; +use crate::BorrowckInferCtxt; use crate::polonius::{self, record_live_region_variance}; use crate::region_infer::values; use crate::type_check::liveness::local_use_map::LocalUseMap; @@ -42,8 +43,8 @@ pub(super) fn trace<'tcx>( typeck: &mut TypeChecker<'_, 'tcx>, location_map: &DenseLocationMap, move_data: &MoveData<'tcx>, - relevant_live_locals: Vec, - boring_locals: Vec, + relevant_live_locals: &[Local], + boring_locals: &[Local], ) { let _timer = typeck.tcx().prof.generic_activity("borrowck_liveness_trace"); @@ -59,7 +60,7 @@ pub(super) fn trace<'tcx>( let mut results = LivenessResults::new(cx); - results.add_extra_drop_facts(&relevant_live_locals); + results.add_extra_drop_facts(relevant_live_locals); results.compute_for_all_locals(relevant_live_locals); @@ -131,8 +132,8 @@ impl<'a, 'typeck, 'tcx> LivenessResults<'a, 'typeck, 'tcx> { } } - fn compute_for_all_locals(&mut self, relevant_live_locals: Vec) { - for local in relevant_live_locals { + fn compute_for_all_locals(&mut self, relevant_live_locals: &[Local]) { + for &local in relevant_live_locals { self.reset_local_state(); self.add_defs_for(local); self.compute_use_live_points_for(local); @@ -161,20 +162,11 @@ impl<'a, 'typeck, 'tcx> LivenessResults<'a, 'typeck, 'tcx> { /// These are all the locals which do not potentially reference a region local /// to this body. Locals which only reference free regions are always drop-live /// and can therefore safely be dropped. - fn dropck_boring_locals(&mut self, boring_locals: Vec) { - for local in boring_locals { + fn dropck_boring_locals(&mut self, boring_locals: &[Local]) { + for &local in boring_locals { let local_ty = self.cx.body().local_decls[local].ty; let local_span = self.cx.body().local_decls[local].source_info.span; - let drop_data = self.cx.drop_data.entry(local_ty).or_insert_with({ - let typeck = &self.cx.typeck; - move || LivenessContext::compute_drop_data(typeck, local_ty, local_span) - }); - - drop_data.dropck_result.report_overflows( - self.cx.typeck.infcx.tcx, - self.cx.typeck.body.local_decls[local].source_info.span, - local_ty, - ); + dropck_local(&self.cx.typeck.infcx, &mut self.cx.drop_data, local_ty, local_span); } } @@ -567,11 +559,9 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> { values::pretty_print_points(self.location_map, live_at.iter()), ); - let local_span = self.body().local_decls()[dropped_local].source_info.span; - let drop_data = self.drop_data.entry(dropped_ty).or_insert_with({ - let typeck = &self.typeck; - move || Self::compute_drop_data(typeck, dropped_ty, local_span) - }); + let dropped_span = self.body().local_decls[dropped_local].source_info.span; + let drop_data = + dropck_local(&self.typeck.infcx, &mut self.drop_data, dropped_ty, dropped_span); if let Some(data) = &drop_data.region_constraint_data { for &drop_location in drop_locations { @@ -583,12 +573,6 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> { } } - drop_data.dropck_result.report_overflows( - self.typeck.infcx.tcx, - self.typeck.body.source_info(*drop_locations.first().unwrap()).span, - dropped_ty, - ); - // All things in the `outlives` array may be touched by // the destructor and must be live at this point. for &kind in &drop_data.dropck_result.kinds { @@ -635,17 +619,19 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> { ); } } +} - fn compute_drop_data( - typeck: &TypeChecker<'_, 'tcx>, - dropped_ty: Ty<'tcx>, - span: Span, - ) -> DropData<'tcx> { - debug!("compute_drop_data(dropped_ty={:?})", dropped_ty); - - let goal = DropckOutlives { dropped_ty }; - - match typeck.infcx.fully_perform(goal, DUMMY_SP) { +/// Computes the `DropData` for a given type, caching the result. +/// This also reports the overflow errors from the computation, if any. +fn dropck_local<'tcx, 'd>( + infcx: &BorrowckInferCtxt<'tcx>, + drop_data: &'d mut FxIndexMap, DropData<'tcx>>, + local_ty: Ty<'tcx>, + local_span: Span, +) -> &'d DropData<'tcx> { + let compute_drop_data = || { + let goal = DropckOutlives { dropped_ty: local_ty }; + match infcx.fully_perform(goal, DUMMY_SP) { Ok(TypeOpOutput { output, constraints, .. }) => { DropData { dropck_result: output, region_constraint_data: constraints } } @@ -657,12 +643,12 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> { // // Do this inside of a probe because we don't particularly care (or want) // any region side-effects of this operation in our infcx. - typeck.infcx.probe(|_| { - let ocx = ObligationCtxt::new_with_diagnostics(&typeck.infcx); + infcx.probe(|_| { + let ocx = ObligationCtxt::new_with_diagnostics(infcx); let errors = match dropck_outlives::compute_dropck_outlives_with_errors( &ocx, - typeck.infcx.param_env.and(goal), - span, + infcx.param_env.and(goal), + local_span, ) { Ok(_) => ocx.evaluate_obligations_error_on_ambiguity(), Err(e) => TraitErrors::HasErrors(e), @@ -671,11 +657,15 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> { // Could have no errors if a type lowering error, say, caused the query // to fail. if let TraitErrors::HasErrors(errors) = errors { - typeck.infcx.err_ctxt().report_fulfillment_errors(errors); + infcx.err_ctxt().report_fulfillment_errors(errors); } }); DropData { dropck_result: Default::default(), region_constraint_data: None } } } - } + }; + + let drop_data = drop_data.entry(local_ty).or_insert_with(compute_drop_data); + drop_data.dropck_result.report_overflows(infcx.tcx, local_span, local_ty); + drop_data }