From 925e7e6baf435e68b463f9e31911d28118de318e Mon Sep 17 00:00:00 2001 From: ismailarilik Date: Sat, 5 Oct 2024 07:34:14 +0300 Subject: Handle `clippy` cases of `rustc::potential_query_instability` lint --- compiler/rustc_data_structures/src/unhash.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'compiler/rustc_data_structures/src') diff --git a/compiler/rustc_data_structures/src/unhash.rs b/compiler/rustc_data_structures/src/unhash.rs index 48e21a9dab1..0617ef83aad 100644 --- a/compiler/rustc_data_structures/src/unhash.rs +++ b/compiler/rustc_data_structures/src/unhash.rs @@ -3,6 +3,7 @@ use std::hash::{BuildHasherDefault, Hasher}; pub type UnhashMap = HashMap>; pub type UnhashSet = HashSet>; +pub type UnindexMap = indexmap::IndexMap>; /// This no-op hasher expects only a single `write_u64` call. It's intended for /// map keys that already have hash-like quality, like `Fingerprint`. -- cgit 1.4.1-3-g733a5 From 1ac72b94bc5e8536e61232125b99dd052ac74b38 Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Sat, 12 Oct 2024 13:43:17 +0100 Subject: Add ExtractIf for ThinVec --- compiler/rustc_data_structures/src/lib.rs | 1 + compiler/rustc_data_structures/src/thinvec.rs | 92 +++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 compiler/rustc_data_structures/src/thinvec.rs (limited to 'compiler/rustc_data_structures/src') diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index f225684d99f..fba2707922b 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -76,6 +76,7 @@ pub mod svh; pub mod sync; pub mod tagged_ptr; pub mod temp_dir; +pub mod thinvec; pub mod transitive_relation; pub mod unhash; pub mod unord; diff --git a/compiler/rustc_data_structures/src/thinvec.rs b/compiler/rustc_data_structures/src/thinvec.rs new file mode 100644 index 00000000000..e60ac2cbc8b --- /dev/null +++ b/compiler/rustc_data_structures/src/thinvec.rs @@ -0,0 +1,92 @@ +//! This is a copy-paste of `Vec::extract_if` for `ThinVec`. +//! +//! FIXME: is merged, this can be removed. + +use std::{ptr, slice}; + +use thin_vec::ThinVec; + +/// An iterator for [`ThinVec`] which uses a closure to determine if an element should be removed. +#[must_use = "iterators are lazy and do nothing unless consumed"] +pub struct ExtractIf<'a, T, F> { + vec: &'a mut ThinVec, + /// The index of the item that will be inspected by the next call to `next`. + idx: usize, + /// The number of items that have been drained (removed) thus far. + del: usize, + /// The original length of `vec` prior to draining. + old_len: usize, + /// The filter test predicate. + pred: F, +} + +impl<'a, T, F> ExtractIf<'a, T, F> +where + F: FnMut(&mut T) -> bool, +{ + pub fn new(vec: &'a mut ThinVec, filter: F) -> Self { + let old_len = vec.len(); + + // Guard against us getting leaked (leak amplification) + unsafe { + vec.set_len(0); + } + + ExtractIf { vec, idx: 0, del: 0, old_len, pred: filter } + } +} + +impl Iterator for ExtractIf<'_, T, F> +where + F: FnMut(&mut T) -> bool, +{ + type Item = T; + fn next(&mut self) -> Option { + unsafe { + while self.idx < self.old_len { + let i = self.idx; + let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); + let drained = (self.pred)(&mut v[i]); + // Update the index *after* the predicate is called. If the index + // is updated prior and the predicate panics, the element at this + // index would be leaked. + self.idx += 1; + if drained { + self.del += 1; + return Some(ptr::read(&v[i])); + } else if self.del > 0 { + let del = self.del; + let src: *const T = &v[i]; + let dst: *mut T = &mut v[i - del]; + ptr::copy_nonoverlapping(src, dst, 1); + } + } + None + } + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.old_len - self.idx)) + } +} + +impl Drop for ExtractIf<'_, A, F> { + fn drop(&mut self) { + unsafe { + if self.idx < self.old_len && self.del > 0 { + // This is a pretty messed up state, and there isn't really an + // obviously right thing to do. We don't want to keep trying + // to execute `pred`, so we just backshift all the unprocessed + // elements and tell the vec that they still exist. The backshift + // is required to prevent a double-drop of the last successfully + // drained item prior to a panic in the predicate. + let ptr = self.vec.as_mut_ptr(); + let src = ptr.add(self.idx); + let dst = src.sub(self.del); + let tail_len = self.old_len - self.idx; + src.copy_to(dst, tail_len); + } + self.vec.set_len(self.old_len - self.del); + } + } +} -- cgit 1.4.1-3-g733a5 From 7ec06b0d1d08cbcc6ed2f7e6ae87fe18056f69ef Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Wed, 9 Oct 2024 01:02:55 +0100 Subject: Swap Vec to type alias --- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +- .../src/obligation_forest/mod.rs | 3 +- compiler/rustc_hir_analysis/src/autoderef.rs | 11 ++-- compiler/rustc_hir_typeck/src/autoderef.rs | 5 +- compiler/rustc_hir_typeck/src/closure.rs | 4 +- compiler/rustc_hir_typeck/src/coercion.rs | 33 +++++------ .../src/fn_ctxt/inspect_obligations.rs | 13 ++--- compiler/rustc_hir_typeck/src/method/mod.rs | 3 +- .../src/infer/canonical/query_response.rs | 7 ++- compiler/rustc_infer/src/infer/mod.rs | 10 ++-- compiler/rustc_infer/src/infer/opaque_types/mod.rs | 8 +-- compiler/rustc_infer/src/infer/projection.rs | 4 +- compiler/rustc_infer/src/infer/relate/lattice.rs | 8 +-- .../rustc_infer/src/infer/relate/type_relating.rs | 8 +-- compiler/rustc_infer/src/traits/engine.rs | 10 ++-- compiler/rustc_infer/src/traits/mod.rs | 2 + compiler/rustc_infer/src/traits/project.rs | 6 +- .../src/error_reporting/mod.rs | 7 +-- .../rustc_trait_selection/src/solve/fulfill.rs | 17 +++--- .../rustc_trait_selection/src/traits/coherence.rs | 9 +-- .../rustc_trait_selection/src/traits/engine.rs | 3 +- .../rustc_trait_selection/src/traits/fulfill.rs | 54 +++++++++++------- compiler/rustc_trait_selection/src/traits/mod.rs | 2 +- .../rustc_trait_selection/src/traits/normalize.rs | 14 ++--- .../src/traits/outlives_bounds.rs | 2 +- .../rustc_trait_selection/src/traits/project.rs | 63 +++++++++++---------- .../src/traits/query/normalize.rs | 14 +++-- .../src/traits/query/type_op/mod.rs | 6 +- .../src/traits/select/candidate_assembly.rs | 6 +- .../src/traits/select/confirmation.rs | 65 +++++++++++----------- .../rustc_trait_selection/src/traits/select/mod.rs | 20 +++---- compiler/rustc_trait_selection/src/traits/wf.rs | 39 +++++++------ .../rustc_traits/src/normalize_projection_ty.rs | 5 +- 33 files changed, 250 insertions(+), 215 deletions(-) (limited to 'compiler/rustc_data_structures/src') diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 82aeca66693..238d7d0749a 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -18,6 +18,7 @@ use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::{ BoundRegion, BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, }; +use rustc_infer::traits::PredicateObligations; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -40,7 +41,6 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; use rustc_span::{DUMMY_SP, Span}; use rustc_target::abi::{FIRST_VARIANT, FieldIdx}; -use rustc_trait_selection::traits::PredicateObligation; use rustc_trait_selection::traits::query::type_op::custom::{ CustomTypeOp, scrape_region_constraints, }; @@ -2940,7 +2940,7 @@ impl NormalizeLocation for Location { pub(super) struct InstantiateOpaqueType<'tcx> { pub base_universe: Option, pub region_constraints: Option>, - pub obligations: Vec>, + pub obligations: PredicateObligations<'tcx>, } impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> { diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index cfe7dd13e80..aca99b9fab1 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -402,9 +402,10 @@ impl ObligationForest { } /// Returns the set of obligations that are in a pending state. - pub fn map_pending_obligations(&self, f: F) -> Vec

+ pub fn map_pending_obligations(&self, f: F) -> R where F: Fn(&O) -> P, + R: FromIterator

, { self.nodes .iter() diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 8d11328743c..5a66c31a0cc 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -1,4 +1,5 @@ use rustc_infer::infer::InferCtxt; +use rustc_infer::traits::PredicateObligations; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Limit; use rustc_span::Span; @@ -23,7 +24,7 @@ struct AutoderefSnapshot<'tcx> { reached_recursion_limit: bool, steps: Vec<(Ty<'tcx>, AutoderefKind)>, cur_ty: Ty<'tcx>, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, } pub struct Autoderef<'a, 'tcx> { @@ -119,7 +120,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { state: AutoderefSnapshot { steps: vec![], cur_ty: infcx.resolve_vars_if_possible(base_ty), - obligations: vec![], + obligations: PredicateObligations::new(), at_start: true, reached_recursion_limit: false, }, @@ -165,7 +166,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { pub fn structurally_normalize( &self, ty: Ty<'tcx>, - ) -> Option<(Ty<'tcx>, Vec>)> { + ) -> Option<(Ty<'tcx>, PredicateObligations<'tcx>)> { let ocx = ObligationCtxt::new(self.infcx); let Ok(normalized_ty) = ocx.structurally_normalize( &traits::ObligationCause::misc(self.span, self.body_id), @@ -204,11 +205,11 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { self.state.steps.len() } - pub fn into_obligations(self) -> Vec> { + pub fn into_obligations(self) -> PredicateObligations<'tcx> { self.state.obligations } - pub fn current_obligations(&self) -> Vec> { + pub fn current_obligations(&self) -> PredicateObligations<'tcx> { self.state.obligations.clone() } diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs index d2d6da8f32b..e4ca1cee757 100644 --- a/compiler/rustc_hir_typeck/src/autoderef.rs +++ b/compiler/rustc_hir_typeck/src/autoderef.rs @@ -5,6 +5,7 @@ use std::iter; use itertools::Itertools; use rustc_hir_analysis::autoderef::{Autoderef, AutoderefKind}; use rustc_infer::infer::InferOk; +use rustc_infer::traits::PredicateObligations; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref}; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; @@ -36,10 +37,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> InferOk<'tcx, Vec>> { let steps = autoderef.steps(); if steps.is_empty() { - return InferOk { obligations: vec![], value: vec![] }; + return InferOk { obligations: PredicateObligations::new(), value: vec![] }; } - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); let targets = steps.iter().skip(1).map(|&(ty, _)| ty).chain(iter::once(autoderef.final_ty(false))); let steps: Vec<_> = steps diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index fcaa5751152..fd6ac7de14a 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -8,7 +8,7 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, InferResult}; -use rustc_infer::traits::ObligationCauseCode; +use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::span_bug; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; @@ -805,7 +805,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706 // [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796 self.commit_if_ok(|_| { - let mut all_obligations = vec![]; + let mut all_obligations = PredicateObligations::new(); let supplied_sig = self.instantiate_binder_with_fresh_vars( self.tcx.def_span(expr_def_id), BoundRegionConversionTime::FnCall, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index bd0b9870298..f81bc727aa1 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -46,6 +46,7 @@ use rustc_infer::infer::relate::RelateResult; use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; use rustc_infer::traits::{ IfExpressionCause, MatchExpressionArmCause, Obligation, PredicateObligation, + PredicateObligations, }; use rustc_middle::lint::in_external_macro; use rustc_middle::span_bug; @@ -120,7 +121,7 @@ fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec( adj: Vec>, target: Ty<'tcx>, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, ) -> CoerceResult<'tcx> { Ok(InferOk { value: (adj, target), obligations }) } @@ -184,7 +185,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Coercing from `!` to any type is allowed: if a.is_never() { if self.coerce_never { - return success(simple(Adjust::NeverToAny)(b), b, vec![]); + return success(simple(Adjust::NeverToAny)(b), b, PredicateObligations::new()); } else { // Otherwise the only coercion we can do is unification. return self.unify_and(a, b, identity); @@ -278,7 +279,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Two unresolved type variables: create a `Coerce` predicate. let target_ty = if self.use_lub { self.next_ty_var(self.cause.span) } else { b }; - let mut obligations = Vec::with_capacity(2); + let mut obligations = PredicateObligations::with_capacity(2); for &source_ty in &[a, b] { if source_ty != target_ty { obligations.push(Obligation::new( @@ -744,7 +745,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Check the obligations of the cast -- for example, when casting // `usize` to `dyn* Clone + 'static`: - let mut obligations: Vec<_> = predicates + let obligations = predicates .iter() .map(|predicate| { // For each existential predicate (e.g., `?Self: Clone`) instantiate @@ -764,21 +765,21 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { ty::OutlivesPredicate(a, b_region), ))), ), + // Enforce that the type is `usize`/pointer-sized. + Obligation::new( + self.tcx, + self.cause.clone(), + self.param_env, + ty::TraitRef::new( + self.tcx, + self.tcx + .require_lang_item(hir::LangItem::PointerLike, Some(self.cause.span)), + [a], + ), + ), ]) .collect(); - // Enforce that the type is `usize`/pointer-sized. - obligations.push(Obligation::new( - self.tcx, - self.cause.clone(), - self.param_env, - ty::TraitRef::new( - self.tcx, - self.tcx.require_lang_item(hir::LangItem::PointerLike, Some(self.cause.span)), - [a], - ), - )); - Ok(InferOk { value: ( vec![Adjustment { kind: Adjust::Pointer(PointerCoercion::DynStar), target: b }], diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 2aad9a043f9..693cb4465cc 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -1,6 +1,6 @@ //! A utility module to inspect currently ambiguous obligations in the current context. -use rustc_infer::traits::{self, ObligationCause}; +use rustc_infer::traits::{self, ObligationCause, PredicateObligations}; use rustc_middle::traits::solve::Goal; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_span::Span; @@ -15,10 +15,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Returns a list of all obligations whose self type has been unified /// with the unconstrained type `self_ty`. #[instrument(skip(self), level = "debug")] - pub(crate) fn obligations_for_self_ty( - &self, - self_ty: ty::TyVid, - ) -> Vec> { + pub(crate) fn obligations_for_self_ty(&self, self_ty: ty::TyVid) -> PredicateObligations<'tcx> { if self.next_trait_solver() { self.obligations_for_self_ty_next(self_ty) } else { @@ -75,10 +72,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn obligations_for_self_ty_next( &self, self_ty: ty::TyVid, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { let obligations = self.fulfillment_cx.borrow().pending_obligations(); debug!(?obligations); - let mut obligations_for_self_ty = vec![]; + let mut obligations_for_self_ty = PredicateObligations::new(); for obligation in obligations { let mut visitor = NestedObligationsForSelfTy { fcx: self, @@ -103,7 +100,7 @@ struct NestedObligationsForSelfTy<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, self_ty: ty::TyVid, root_cause: &'a ObligationCause<'tcx>, - obligations_for_self_ty: &'a mut Vec>, + obligations_for_self_ty: &'a mut PredicateObligations<'tcx>, } impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> { diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index cb8b1df2c6e..2de5947b16f 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -12,6 +12,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_infer::infer::{self, InferOk}; +use rustc_infer::traits::PredicateObligations; use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ @@ -412,7 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); // FIXME(effects): revisit when binops get `#[const_trait]` diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 7791bd73628..1d3d32ef749 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -28,7 +28,8 @@ use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult}; use crate::traits::query::NoSolution; use crate::traits::{ - Obligation, ObligationCause, PredicateObligation, ScrubbedTraitError, TraitEngine, + Obligation, ObligationCause, PredicateObligation, PredicateObligations, ScrubbedTraitError, + TraitEngine, }; impl<'tcx> InferCtxt<'tcx> { @@ -493,7 +494,7 @@ impl<'tcx> InferCtxt<'tcx> { ), }; - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); // Carry all newly resolved opaque types to the caller's scope for &(a, b) in &query_response.value.opaque_types { @@ -598,7 +599,7 @@ impl<'tcx> InferCtxt<'tcx> { variables1: &OriginalQueryValues<'tcx>, variables2: impl Fn(BoundVar) -> GenericArg<'tcx>, ) -> InferResult<'tcx, ()> { - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); for (index, value1) in variables1.var_values.iter().enumerate() { let value2 = variables2(BoundVar::new(index)); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bc813305ba4..7ef714475fc 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -50,7 +50,9 @@ use tracing::{debug, instrument}; use type_variable::TypeVariableOrigin; use crate::infer::region_constraints::UndoLog; -use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine}; +use crate::traits::{ + self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine, +}; pub mod at; pub mod canonical; @@ -68,7 +70,7 @@ pub(crate) mod snapshot; mod type_variable; /// `InferOk<'tcx, ()>` is used a lot. It may seem like a useless wrapper -/// around `Vec>`, but it has one important property: +/// around `PredicateObligations<'tcx>`, but it has one important property: /// because `InferOk` is marked with `#[must_use]`, if you have a method /// `InferCtxt::f` that returns `InferResult<'tcx, ()>` and you call it with /// `infcx.f()?;` you'll get a warning about the obligations being discarded @@ -78,7 +80,7 @@ mod type_variable; #[derive(Debug)] pub struct InferOk<'tcx, T> { pub value: T, - pub obligations: Vec>, + pub obligations: PredicateObligations<'tcx>, } pub type InferResult<'tcx, T> = Result, TypeError<'tcx>>; @@ -658,7 +660,7 @@ impl<'tcx, T> InferOk<'tcx, T> { } impl<'tcx> InferOk<'tcx, ()> { - pub fn into_obligations(self) -> Vec> { + pub fn into_obligations(self) -> PredicateObligations<'tcx> { self.obligations } } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 365ddaba138..853ae6d2641 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -16,7 +16,7 @@ use tracing::{debug, instrument}; use super::DefineOpaqueTypes; use crate::errors::OpaqueHiddenTypeDiag; use crate::infer::{InferCtxt, InferOk}; -use crate::traits::{self, Obligation}; +use crate::traits::{self, Obligation, PredicateObligations}; mod table; @@ -46,14 +46,14 @@ impl<'tcx> InferCtxt<'tcx> { ) -> InferOk<'tcx, T> { // We handle opaque types differently in the new solver. if self.next_trait_solver() { - return InferOk { value, obligations: vec![] }; + return InferOk { value, obligations: PredicateObligations::new() }; } if !value.has_opaque_types() { - return InferOk { value, obligations: vec![] }; + return InferOk { value, obligations: PredicateObligations::new() }; } - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); let value = value.fold_with(&mut BottomUpFolder { tcx: self.tcx, lt_op: |lt| lt, diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index b78f9d49268..1bee9632110 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -2,7 +2,7 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, Ty}; use super::InferCtxt; -use crate::traits::{Obligation, PredicateObligation}; +use crate::traits::{Obligation, PredicateObligations}; impl<'tcx> InferCtxt<'tcx> { /// Instead of normalizing an associated type projection, @@ -17,7 +17,7 @@ impl<'tcx> InferCtxt<'tcx> { projection_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, recursion_depth: usize, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> Ty<'tcx> { debug_assert!(!self.next_trait_solver()); let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id)); diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 7eb61abfbc1..4eb77a99be7 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -27,7 +27,7 @@ use tracing::{debug, instrument}; use super::StructurallyRelateAliases; use super::combine::PredicateEmittingRelation; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin, TypeTrace}; -use crate::traits::{Obligation, PredicateObligation}; +use crate::traits::{Obligation, PredicateObligations}; #[derive(Clone, Copy)] pub(crate) enum LatticeOpKind { @@ -52,7 +52,7 @@ pub(crate) struct LatticeOp<'infcx, 'tcx> { param_env: ty::ParamEnv<'tcx>, // Mutable fields kind: LatticeOpKind, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, } impl<'infcx, 'tcx> LatticeOp<'infcx, 'tcx> { @@ -62,10 +62,10 @@ impl<'infcx, 'tcx> LatticeOp<'infcx, 'tcx> { param_env: ty::ParamEnv<'tcx>, kind: LatticeOpKind, ) -> LatticeOp<'infcx, 'tcx> { - LatticeOp { infcx, trace, param_env, kind, obligations: vec![] } + LatticeOp { infcx, trace, param_env, kind, obligations: PredicateObligations::new() } } - pub(crate) fn into_obligations(self) -> Vec> { + pub(crate) fn into_obligations(self) -> PredicateObligations<'tcx> { self.obligations } } diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 35103c070c2..009271a8378 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -11,7 +11,7 @@ use tracing::{debug, instrument}; use crate::infer::BoundRegionConversionTime::HigherRankedType; use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases}; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin, TypeTrace}; -use crate::traits::{Obligation, PredicateObligation}; +use crate::traits::{Obligation, PredicateObligations}; /// Enforce that `a` is equal to or a subtype of `b`. pub(crate) struct TypeRelating<'infcx, 'tcx> { @@ -24,7 +24,7 @@ pub(crate) struct TypeRelating<'infcx, 'tcx> { // Mutable fields. ambient_variance: ty::Variance, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, /// The cache only tracks the `ambient_variance` as it's the /// only field which is mutable and which meaningfully changes /// the result when relating types. @@ -65,12 +65,12 @@ impl<'infcx, 'tcx> TypeRelating<'infcx, 'tcx> { param_env, define_opaque_types, ambient_variance, - obligations: vec![], + obligations: PredicateObligations::new(), cache: Default::default(), } } - pub(crate) fn into_obligations(self) -> Vec> { + pub(crate) fn into_obligations(self) -> PredicateObligations<'tcx> { self.obligations } } diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index a076cdad672..ba1516655b0 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, Ty, Upcast}; -use super::{ObligationCause, PredicateObligation}; +use super::{ObligationCause, PredicateObligation, PredicateObligations}; use crate::infer::InferCtxt; use crate::traits::Obligation; @@ -20,7 +20,7 @@ pub enum ScrubbedTraitError<'tcx> { /// An ambiguity. This goal may hold if further inference is done. Ambiguity, /// An old-solver-style cycle error, which will fatal. - Cycle(Vec>), + Cycle(PredicateObligations<'tcx>), } impl<'tcx> ScrubbedTraitError<'tcx> { @@ -62,7 +62,7 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx { fn register_predicate_obligations( &mut self, infcx: &InferCtxt<'tcx>, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, ) { for obligation in obligations { self.register_predicate_obligation(infcx, obligation); @@ -84,7 +84,7 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx { self.collect_remaining_errors(infcx) } - fn pending_obligations(&self) -> Vec>; + fn pending_obligations(&self) -> PredicateObligations<'tcx>; /// Among all pending obligations, collect those are stalled on a inference variable which has /// changed since the last call to `select_where_possible`. Those obligations are marked as @@ -92,7 +92,7 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx { fn drain_unstalled_obligations( &mut self, infcx: &InferCtxt<'tcx>, - ) -> Vec>; + ) -> PredicateObligations<'tcx>; } pub trait FromSolverError<'tcx, E>: Debug + 'tcx { diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 34b0fe3e967..2d02391c57a 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -84,6 +84,8 @@ pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>; pub type TraitObligation<'tcx> = Obligation<'tcx, ty::TraitPredicate<'tcx>>; pub type PolyTraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>; +pub type PredicateObligations<'tcx> = Vec>; + impl<'tcx> PredicateObligation<'tcx> { /// Flips the polarity of the inner predicate. /// diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index 64b72de3986..cab2ce9f5a0 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -6,7 +6,7 @@ use rustc_middle::traits::EvaluationResult; use rustc_middle::ty; use tracing::{debug, info}; -use super::PredicateObligation; +use super::PredicateObligations; use crate::infer::snapshot::undo_log::InferCtxtUndoLogs; pub(crate) type UndoLog<'tcx> = @@ -20,7 +20,7 @@ pub struct MismatchedProjectionTypes<'tcx> { #[derive(Clone)] pub struct Normalized<'tcx, T> { pub value: T, - pub obligations: Vec>, + pub obligations: PredicateObligations<'tcx>, } pub type NormalizedTerm<'tcx> = Normalized<'tcx, ty::Term<'tcx>>; @@ -191,7 +191,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { info!("ProjectionCacheEntry::complete({:?}) - completing {:?}", key, ty); let mut ty = ty.clone(); if result.must_apply_considering_regions() { - ty.obligations = vec![]; + ty.obligations = PredicateObligations::new(); } map.insert(key, ProjectionCacheEntry::NormalizedTerm { ty, diff --git a/compiler/rustc_trait_selection/src/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/mod.rs index cb7efeaae0b..82695688ae8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/mod.rs @@ -2,7 +2,7 @@ use std::ops::Deref; use rustc_errors::DiagCtxtHandle; use rustc_infer::infer::InferCtxt; -use rustc_infer::traits::PredicateObligation; +use rustc_infer::traits::PredicateObligations; use rustc_macros::extension; use rustc_middle::bug; use rustc_middle::ty::{self, Ty}; @@ -28,8 +28,7 @@ pub struct TypeErrCtxt<'a, 'tcx> { pub normalize_fn_sig: Box) -> ty::PolyFnSig<'tcx> + 'a>, - pub autoderef_steps: - Box) -> Vec<(Ty<'tcx>, Vec>)> + 'a>, + pub autoderef_steps: Box) -> Vec<(Ty<'tcx>, PredicateObligations<'tcx>)> + 'a>, } #[extension(pub trait InferCtxtErrorExt<'tcx>)] @@ -45,7 +44,7 @@ impl<'tcx> InferCtxt<'tcx> { normalize_fn_sig: Box::new(|fn_sig| fn_sig), autoderef_steps: Box::new(|ty| { debug_assert!(false, "shouldn't be using autoderef_steps outside of typeck"); - vec![(ty, vec![])] + vec![(ty, PredicateObligations::new())] }), } } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 081d7a6a769..8ec4427091d 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -7,7 +7,7 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause}; use rustc_infer::traits::{ self, FromSolverError, MismatchedProjectionTypes, Obligation, ObligationCause, - ObligationCauseCode, PredicateObligation, SelectionError, TraitEngine, + ObligationCauseCode, PredicateObligation, PredicateObligations, SelectionError, TraitEngine, }; use rustc_middle::bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -49,8 +49,8 @@ struct ObligationStorage<'tcx> { /// We cannot eagerly return these as error so we instead store them here /// to avoid recomputing them each time `select_where_possible` is called. /// This also allows us to return the correct `FulfillmentError` for them. - overflowed: Vec>, - pending: Vec>, + overflowed: PredicateObligations<'tcx>, + pending: PredicateObligations<'tcx>, } impl<'tcx> ObligationStorage<'tcx> { @@ -58,13 +58,13 @@ impl<'tcx> ObligationStorage<'tcx> { self.pending.push(obligation); } - fn clone_pending(&self) -> Vec> { + fn clone_pending(&self) -> PredicateObligations<'tcx> { let mut obligations = self.pending.clone(); obligations.extend(self.overflowed.iter().cloned()); obligations } - fn take_pending(&mut self) -> Vec> { + fn take_pending(&mut self) -> PredicateObligations<'tcx> { let mut obligations = mem::take(&mut self.pending); obligations.append(&mut self.overflowed); obligations @@ -197,14 +197,11 @@ where errors } - fn pending_obligations(&self) -> Vec> { + fn pending_obligations(&self) -> PredicateObligations<'tcx> { self.obligations.clone_pending() } - fn drain_unstalled_obligations( - &mut self, - _: &InferCtxt<'tcx>, - ) -> Vec> { + fn drain_unstalled_obligations(&mut self, _: &InferCtxt<'tcx>) -> PredicateObligations<'tcx> { self.obligations.take_pending() } } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index b29e41beab5..f4a2483cebf 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -11,6 +11,7 @@ use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; +use rustc_infer::traits::PredicateObligations; use rustc_middle::bug; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal}; @@ -279,7 +280,7 @@ fn equate_impl_headers<'tcx>( param_env: ty::ParamEnv<'tcx>, impl1: &ty::ImplHeader<'tcx>, impl2: &ty::ImplHeader<'tcx>, -) -> Option>> { +) -> Option> { let result = match (impl1.trait_ref, impl2.trait_ref) { (Some(impl1_ref), Some(impl2_ref)) => infcx @@ -491,7 +492,7 @@ fn plug_infer_with_placeholders<'tcx>( else { bug!("we always expect to be able to plug an infer var with placeholder") }; - assert_eq!(obligations, &[]); + assert_eq!(obligations.len(), 0); } else { ty.super_visit_with(self); } @@ -514,7 +515,7 @@ fn plug_infer_with_placeholders<'tcx>( else { bug!("we always expect to be able to plug an infer var with placeholder") }; - assert_eq!(obligations, &[]); + assert_eq!(obligations.len(), 0); } else { ct.super_visit_with(self); } @@ -545,7 +546,7 @@ fn plug_infer_with_placeholders<'tcx>( else { bug!("we always expect to be able to plug an infer var with placeholder") }; - assert_eq!(obligations, &[]); + assert_eq!(obligations.len(), 0); } } } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index d562692c1a8..eda3f6e8023 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -10,6 +10,7 @@ use rustc_infer::infer::canonical::{ }; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError, TypeTrace}; +use rustc_infer::traits::PredicateObligations; use rustc_macros::extension; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::traits::query::NoSolution; @@ -208,7 +209,7 @@ where /// getting ignored. You can make a new `ObligationCtxt` if this /// needs to be done in a loop, for example. #[must_use] - pub fn into_pending_obligations(self) -> Vec> { + pub fn into_pending_obligations(self) -> PredicateObligations<'tcx> { self.engine.borrow().pending_obligations() } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 33b8cf03701..3e3834a11c6 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -6,7 +6,8 @@ use rustc_data_structures::obligation_forest::{ }; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::{ - FromSolverError, PolyTraitObligation, ProjectionCacheKey, SelectionError, TraitEngine, + FromSolverError, PolyTraitObligation, PredicateObligations, ProjectionCacheKey, SelectionError, + TraitEngine, }; use rustc_middle::bug; use rustc_middle::mir::interpret::ErrorHandled; @@ -27,6 +28,8 @@ use crate::traits::normalize::normalize_with_depth_to; use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _}; use crate::traits::query::evaluate_obligation::InferCtxtExt; +pub(crate) type PendingPredicateObligations<'tcx> = Vec>; + impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { /// Note that we include both the `ParamEnv` and the `Predicate`, /// as the `ParamEnv` can influence whether fulfillment succeeds @@ -161,15 +164,16 @@ where fn drain_unstalled_obligations( &mut self, infcx: &InferCtxt<'tcx>, - ) -> Vec> { - let mut processor = DrainProcessor { removed_predicates: Vec::new(), infcx }; + ) -> PredicateObligations<'tcx> { + let mut processor = + DrainProcessor { removed_predicates: PredicateObligations::new(), infcx }; let outcome: Outcome<_, _> = self.predicates.process_obligations(&mut processor); assert!(outcome.errors.is_empty()); return processor.removed_predicates; struct DrainProcessor<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, - removed_predicates: Vec>, + removed_predicates: PredicateObligations<'tcx>, } impl<'tcx> ObligationProcessor for DrainProcessor<'_, 'tcx> { @@ -190,7 +194,7 @@ where ) -> ProcessResult, !> { assert!(self.needs_process_obligation(pending_obligation)); self.removed_predicates.push(pending_obligation.obligation.clone()); - ProcessResult::Changed(vec![]) + ProcessResult::Changed(Default::default()) } fn process_backedge<'c, I>( @@ -207,7 +211,7 @@ where } } - fn pending_obligations(&self) -> Vec> { + fn pending_obligations(&self) -> PredicateObligations<'tcx> { self.predicates.map_pending_obligations(|o| o.obligation.clone()) } } @@ -216,7 +220,7 @@ struct FulfillProcessor<'a, 'tcx> { selcx: SelectionContext<'a, 'tcx>, } -fn mk_pending(os: Vec>) -> Vec> { +fn mk_pending<'tcx>(os: PredicateObligations<'tcx>) -> PendingPredicateObligations<'tcx> { os.into_iter() .map(|o| PendingPredicateObligation { obligation: o, stalled_on: vec![] }) .collect() @@ -321,7 +325,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { let infcx = self.selcx.infcx; if obligation.predicate.has_aliases() { - let mut obligations = Vec::new(); + let mut obligations = PredicateObligations::new(); let predicate = normalize_with_depth_to( &mut self.selcx, obligation.param_env, @@ -369,7 +373,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) => { let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder)); - ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)])) + let mut obligations = PredicateObligations::with_capacity(1); + obligations.push(obligation.with(infcx.tcx, pred)); + + ProcessResult::Changed(mk_pending(obligations)) } ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, ty::PredicateKind::NormalizesTo(..) => { @@ -395,7 +402,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data)); } - ProcessResult::Changed(vec![]) + ProcessResult::Changed(Default::default()) } ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate( @@ -405,7 +412,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { if infcx.considering_regions { infcx.register_region_obligation_with_cause(t_a, r_b, &obligation.cause); } - ProcessResult::Changed(vec![]) + ProcessResult::Changed(Default::default()) } ty::PredicateKind::Clause(ty::ClauseKind::Projection(ref data)) => { @@ -422,7 +429,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { if !self.selcx.tcx().is_dyn_compatible(trait_def_id) { ProcessResult::Error(FulfillmentErrorCode::Select(Unimplemented)) } else { - ProcessResult::Changed(vec![]) + ProcessResult::Changed(Default::default()) } } @@ -451,7 +458,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { pending_obligation.stalled_on.extend([var]); return ProcessResult::Unchanged; } - ty::ConstKind::Error(_) => return ProcessResult::Changed(vec![]), + ty::ConstKind::Error(_) => { + return ProcessResult::Changed(PendingPredicateObligations::new()); + } ty::ConstKind::Value(ty, _) => ty, ty::ConstKind::Unevaluated(uv) => { infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) @@ -460,7 +469,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { // `>::Output` when this is an `Expr` representing // `lhs + rhs`. ty::ConstKind::Expr(_) => { - return ProcessResult::Changed(mk_pending(vec![])); + return ProcessResult::Changed(mk_pending(PredicateObligations::new())); } ty::ConstKind::Placeholder(_) => { bug!("placeholder const {:?} in old solver", ct) @@ -568,7 +577,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { obligation.param_env, obligation.cause.span, ) { - Ok(()) => ProcessResult::Changed(vec![]), + Ok(()) => ProcessResult::Changed(Default::default()), Err(NotConstEvaluatable::MentionsInfer) => { pending_obligation.stalled_on.clear(); pending_obligation.stalled_on.extend( @@ -722,7 +731,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { debug!("process_child_obligations: coinductive match"); Ok(()) } else { - let cycle: Vec<_> = cycle.map(|c| c.obligation.clone()).collect(); + let cycle = cycle.map(|c| c.obligation.clone()).collect(); Err(FulfillmentErrorCode::Cycle(cycle)) } } @@ -745,7 +754,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { "selecting trait at depth {} evaluated to holds", obligation.recursion_depth ); - return ProcessResult::Changed(vec![]); + return ProcessResult::Changed(Default::default()); } } @@ -809,7 +818,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { .projection_cache() .complete(key, EvaluationResult::EvaluatedToOk); } - return ProcessResult::Changed(vec![]); + return ProcessResult::Changed(Default::default()); } else { debug!("Does NOT hold: {:?}", obligation); } @@ -826,9 +835,12 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { ProcessResult::Unchanged } // Let the caller handle the recursion - ProjectAndUnifyResult::Recursive => ProcessResult::Changed(mk_pending(vec![ - project_obligation.with(tcx, project_obligation.predicate), - ])), + ProjectAndUnifyResult::Recursive => { + let mut obligations = PredicateObligations::with_capacity(1); + obligations.push(project_obligation.with(tcx, project_obligation.predicate)); + + ProcessResult::Changed(mk_pending(obligations)) + } ProjectAndUnifyResult::MismatchedProjectionTypes(e) => { ProcessResult::Error(FulfillmentErrorCode::Project(e)) } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 655bef0bab7..0fb795fc184 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -114,7 +114,7 @@ impl<'tcx> Debug for FulfillmentError<'tcx> { pub enum FulfillmentErrorCode<'tcx> { /// Inherently impossible to fulfill; this trait is implemented if and only /// if it is already implemented. - Cycle(Vec>), + Cycle(PredicateObligations<'tcx>), Select(SelectionError<'tcx>), Project(MismatchedProjectionTypes<'tcx>), Subtype(ExpectedFound>, TypeError<'tcx>), // always comes from a SubtypePredicate diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index a7130cbd28f..7eac3559348 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -4,7 +4,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::InferOk; use rustc_infer::infer::at::At; use rustc_infer::traits::{ - FromSolverError, Normalized, Obligation, PredicateObligation, TraitEngine, + FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine, }; use rustc_macros::extension; use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal}; @@ -29,7 +29,7 @@ impl<'tcx> At<'_, 'tcx> { /// projection may be fallible. fn normalize>>(&self, value: T) -> InferOk<'tcx, T> { if self.infcx.next_trait_solver() { - InferOk { value, obligations: Vec::new() } + InferOk { value, obligations: PredicateObligations::new() } } else { let mut selcx = SelectionContext::new(self.infcx); let Normalized { value, obligations } = @@ -83,7 +83,7 @@ pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>( where T: TypeFoldable>, { - let mut obligations = Vec::new(); + let mut obligations = PredicateObligations::new(); let value = normalize_with_depth_to(selcx, param_env, cause, depth, value, &mut obligations); Normalized { value, obligations } } @@ -95,14 +95,14 @@ pub(crate) fn normalize_with_depth_to<'a, 'b, 'tcx, T>( cause: ObligationCause<'tcx>, depth: usize, value: T, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> T where T: TypeFoldable>, { debug!(obligations.len = obligations.len()); let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth, obligations); - let result = ensure_sufficient_stack(|| normalizer.fold(value)); + let result = ensure_sufficient_stack(|| AssocTypeNormalizer::fold(&mut normalizer, value)); debug!(?result, obligations.len = normalizer.obligations.len()); debug!(?normalizer.obligations,); result @@ -128,7 +128,7 @@ struct AssocTypeNormalizer<'a, 'b, 'tcx> { selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, - obligations: &'a mut Vec>, + obligations: &'a mut PredicateObligations<'tcx>, depth: usize, universes: Vec>, } @@ -139,7 +139,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, depth: usize, - obligations: &'a mut Vec>, + obligations: &'a mut PredicateObligations<'tcx>, ) -> AssocTypeNormalizer<'a, 'b, 'tcx> { debug_assert!(!selcx.infcx.next_trait_solver()); AssocTypeNormalizer { selcx, param_env, cause, obligations, depth, universes: vec![] } diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index f1faff2c036..339e4bf1f22 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -77,7 +77,7 @@ fn implied_outlives_bounds<'a, 'tcx>( else { return vec![]; }; - assert_eq!(&obligations, &[]); + assert_eq!(obligations.len(), 0); // Because of #109628, we may have unexpected placeholders. Ignore them! // FIXME(#109628): panic in this case once the issue is fixed. diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 9cd99d99fc3..7f7c9bced18 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -9,7 +9,7 @@ use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::resolve::OpportunisticRegionResolver; -use rustc_infer::traits::ObligationCauseCode; +use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; pub use rustc_middle::traits::Reveal; use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; @@ -146,7 +146,7 @@ impl<'tcx> ProjectionCandidateSet<'tcx> { /// of the old return type, which was: /// ```ignore (not-rust) /// Result< -/// Result>>, InProgress>, +/// Result>, InProgress>, /// MismatchedProjectionTypes<'tcx>, /// > /// ``` @@ -155,7 +155,7 @@ pub(super) enum ProjectAndUnifyResult<'tcx> { /// projection cannot be normalized because the required trait bound does /// not hold, this is returned, with `obligations` being a predicate that /// cannot be proven. - Holds(Vec>), + Holds(PredicateObligations<'tcx>), /// The projection cannot be normalized due to ambiguity. Resolving some /// inference variables in the projection may fix this. FailedNormalization, @@ -231,7 +231,7 @@ fn project_and_unify_term<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionObligation<'tcx>, ) -> ProjectAndUnifyResult<'tcx> { - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); let infcx = selcx.infcx; let normalized = match opt_normalize_projection_term( @@ -289,7 +289,7 @@ pub fn normalize_projection_ty<'a, 'b, 'tcx>( projection_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> Term<'tcx> { opt_normalize_projection_term( selcx, @@ -330,7 +330,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( projection_term: ty::AliasTerm<'tcx>, cause: ObligationCause<'tcx>, depth: usize, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> Result>, InProgress> { let infcx = selcx.infcx; debug_assert!(!selcx.infcx.next_trait_solver()); @@ -452,7 +452,8 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( Ok(Some(result.value)) } Ok(Projected::NoProgress(projected_ty)) => { - let result = Normalized { value: projected_ty, obligations: vec![] }; + let result = + Normalized { value: projected_ty, obligations: PredicateObligations::new() }; if use_cache { infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone()); } @@ -519,13 +520,14 @@ fn normalize_to_error<'a, 'tcx>( selcx.infcx.next_const_var(cause.span).into() } }; - let trait_obligation = Obligation { + let mut obligations = PredicateObligations::new(); + obligations.push(Obligation { cause, recursion_depth: depth, param_env, predicate: trait_ref.upcast(selcx.tcx()), - }; - Normalized { value: new_value, obligations: vec![trait_obligation] } + }); + Normalized { value: new_value, obligations } } /// Confirm and normalize the given inherent projection. @@ -536,7 +538,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( alias_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> Ty<'tcx> { let tcx = selcx.tcx(); @@ -604,7 +606,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>( alias_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> ty::GenericArgsRef<'tcx> { let tcx = selcx.tcx(); @@ -657,15 +659,15 @@ enum Projected<'tcx> { struct Progress<'tcx> { term: ty::Term<'tcx>, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, } impl<'tcx> Progress<'tcx> { fn error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self { - Progress { term: Ty::new_error(tcx, guar).into(), obligations: vec![] } + Progress { term: Ty::new_error(tcx, guar).into(), obligations: PredicateObligations::new() } } - fn with_addl_obligations(mut self, mut obligations: Vec>) -> Self { + fn with_addl_obligations(mut self, mut obligations: PredicateObligations<'tcx>) -> Self { self.obligations.append(&mut obligations); self } @@ -1351,7 +1353,7 @@ fn confirm_select_candidate<'cx, 'tcx>( fn confirm_coroutine_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); let ty::Coroutine(_, args) = self_ty.kind() else { @@ -1410,7 +1412,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( fn confirm_future_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); let ty::Coroutine(_, args) = self_ty.kind() else { @@ -1458,7 +1460,7 @@ fn confirm_future_candidate<'cx, 'tcx>( fn confirm_iterator_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); let ty::Coroutine(_, args) = self_ty.kind() else { @@ -1504,7 +1506,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>( fn confirm_async_iterator_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let ty::Coroutine(_, args) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() else { @@ -1558,7 +1560,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>( fn confirm_builtin_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - data: Vec>, + data: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = obligation.predicate.self_ty(); @@ -1569,17 +1571,17 @@ fn confirm_builtin_candidate<'cx, 'tcx>( let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None); assert_eq!(discriminant_def_id, item_def_id); - (self_ty.discriminant_ty(tcx).into(), Vec::new()) + (self_ty.discriminant_ty(tcx).into(), PredicateObligations::new()) } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncDestruct) { let destructor_def_id = tcx.associated_item_def_ids(trait_def_id)[0]; assert_eq!(destructor_def_id, item_def_id); - (self_ty.async_destructor_ty(tcx).into(), Vec::new()) + (self_ty.async_destructor_ty(tcx).into(), PredicateObligations::new()) } else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) { let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); assert_eq!(metadata_def_id, item_def_id); - let mut obligations = Vec::new(); + let mut obligations = PredicateObligations::new(); let normalize = |ty| { normalize_with_depth_to( selcx, @@ -1627,7 +1629,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( fn confirm_fn_pointer_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); let fn_type = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1663,7 +1665,7 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>( fn confirm_closure_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1782,7 +1784,7 @@ fn confirm_callable_candidate<'cx, 'tcx>( fn confirm_async_closure_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1934,7 +1936,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let [ // We already checked that the goal_kind >= closure_kind @@ -1987,7 +1989,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>( ); let cache_projection = cache_entry.projection_term; - let mut nested_obligations = Vec::new(); + let mut nested_obligations = PredicateObligations::new(); let obligation_projection = obligation.predicate; let obligation_projection = ensure_sufficient_stack(|| { normalize_with_depth_to( @@ -2034,7 +2036,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>( ); debug!("confirm_param_env_candidate: {}", msg); let err = Ty::new_error_with_message(infcx.tcx, obligation.cause.span, msg); - Progress { term: err.into(), obligations: vec![] } + Progress { term: err.into(), obligations: PredicateObligations::new() } } } } @@ -2047,6 +2049,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( let tcx = selcx.tcx(); let ImplSourceUserDefinedData { impl_def_id, args, mut nested } = impl_impl_source; + let assoc_item_id = obligation.predicate.def_id; let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap(); @@ -2102,7 +2105,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( fn assoc_ty_own_obligations<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: &mut Vec>, + nested: &mut PredicateObligations<'tcx>, ) { let tcx = selcx.tcx(); let predicates = tcx diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 36b24eac5c4..18412b844ff 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -4,6 +4,7 @@ use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_infer::traits::PredicateObligations; use rustc_macros::extension; pub use rustc_middle::traits::query::NormalizationResult; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; @@ -20,8 +21,7 @@ use crate::infer::canonical::OriginalQueryValues; use crate::infer::{InferCtxt, InferOk}; use crate::traits::normalize::needs_normalization; use crate::traits::{ - BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, PredicateObligation, - Reveal, ScrubbedTraitError, + BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, Reveal, ScrubbedTraitError, }; #[extension(pub trait QueryNormalizeExt<'tcx>)] @@ -80,7 +80,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { match crate::solve::deeply_normalize_with_skipped_universes::<_, ScrubbedTraitError<'tcx>>( self, value, universes, ) { - Ok(value) => return Ok(Normalized { value, obligations: vec![] }), + Ok(value) => { + return Ok(Normalized { value, obligations: PredicateObligations::new() }); + } Err(_errors) => { return Err(NoSolution); } @@ -88,14 +90,14 @@ impl<'a, 'tcx> At<'a, 'tcx> { } if !needs_normalization(&value, self.param_env.reveal()) { - return Ok(Normalized { value, obligations: vec![] }); + return Ok(Normalized { value, obligations: PredicateObligations::new() }); } let mut normalizer = QueryNormalizer { infcx: self.infcx, cause: self.cause, param_env: self.param_env, - obligations: vec![], + obligations: PredicateObligations::new(), cache: SsoHashMap::new(), anon_depth: 0, universes, @@ -164,7 +166,7 @@ struct QueryNormalizer<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, cause: &'a ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, cache: SsoHashMap, Ty<'tcx>>, anon_depth: usize, universes: Vec>, diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index a765de92afd..5ae8c87ec02 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -2,7 +2,7 @@ use std::fmt; use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::canonical::Certainty; -use rustc_infer::traits::PredicateObligation; +use rustc_infer::traits::PredicateObligations; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; @@ -103,13 +103,13 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable> + 't ( Self::QueryResponse, Option>>, - Vec>, + PredicateObligations<'tcx>, Certainty, ), NoSolution, > { if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) { - return Ok((result, None, vec![], Certainty::Proven)); + return Ok((result, None, PredicateObligations::new(), Certainty::Proven)); } let mut canonical_var_values = OriginalQueryValues::default(); diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 20adda6f0de..52048ca79f9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -12,7 +12,9 @@ use hir::LangItem; use hir::def_id::DefId; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_hir as hir; -use rustc_infer::traits::{Obligation, ObligationCause, PolyTraitObligation, SelectionError}; +use rustc_infer::traits::{ + Obligation, ObligationCause, PolyTraitObligation, PredicateObligations, SelectionError, +}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; @@ -963,7 +965,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 0, // We're *intentionally* throwing these away, // since we don't actually use them. - &mut vec![], + &mut PredicateObligations::new(), ) .as_type() .unwrap(); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 5141e969608..cc5c7532b50 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -24,7 +24,7 @@ use rustc_span::def_id::DefId; use tracing::{debug, instrument}; use super::SelectionCandidate::{self, *}; -use super::{BuiltinImplConditions, SelectionContext}; +use super::{BuiltinImplConditions, PredicateObligations, SelectionContext}; use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; use crate::traits::util::{self, closure_trait_ref_and_return_type}; use crate::traits::{ @@ -85,7 +85,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // No nested obligations or confirmation process. The checks that we do in // candidate assembly are sufficient. - AsyncFnKindHelperCandidate => ImplSource::Builtin(BuiltinImplSource::Misc, vec![]), + AsyncFnKindHelperCandidate => { + ImplSource::Builtin(BuiltinImplSource::Misc, PredicateObligations::new()) + } CoroutineCandidate => { let vtable_coroutine = self.confirm_coroutine_candidate(obligation)?; @@ -121,7 +123,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // This indicates something like `Trait + Send: Send`. In this case, we know that // this holds because that's what the object type is telling us, and there's really // no additional obligations to prove and no types in particular to unify, etc. - ImplSource::Builtin(BuiltinImplSource::Misc, Vec::new()) + ImplSource::Builtin(BuiltinImplSource::Misc, PredicateObligations::new()) } BuiltinUnsizeCandidate => self.confirm_builtin_unsize_candidate(obligation)?, @@ -149,7 +151,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, idx: usize, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let tcx = self.tcx(); let placeholder_trait_predicate = @@ -179,7 +181,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { HigherRankedType, candidate, ); - let mut obligations = Vec::new(); + let mut obligations = PredicateObligations::new(); let candidate = normalize_with_depth_to( self, obligation.param_env, @@ -226,7 +228,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, param: ty::PolyTraitRef<'tcx>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { debug!(?obligation, ?param, "confirm_param_candidate"); // During evaluation, we already checked that this @@ -249,7 +251,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, has_nested: bool, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { debug!(?obligation, ?has_nested, "confirm_builtin_candidate"); let tcx = self.tcx(); @@ -279,7 +281,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { nested, ) } else { - vec![] + PredicateObligations::new() }; debug!(?obligations); @@ -291,7 +293,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_transmutability_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { use rustc_transmute::{Answer, Assume, Condition}; /// Generate sub-obligations for reference-to-reference transmutations. @@ -301,7 +303,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { (src_lifetime, src_ty, src_mut): (ty::Region<'tcx>, Ty<'tcx>, Mutability), (dst_lifetime, dst_ty, dst_mut): (ty::Region<'tcx>, Ty<'tcx>, Mutability), assume: Assume, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { let make_transmute_obl = |src, dst| { let transmute_trait = obligation.predicate.def_id(); let assume = obligation.predicate.skip_binder().trait_ref.args.const_at(2); @@ -347,7 +349,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Given a transmutation from `&'a (mut) Src` and `&'dst (mut) Dst`, // it is always the case that `Src` must be transmutable into `Dst`, // and that that `'src` must outlive `'dst`. - let mut obls = vec![make_transmute_obl(src_ty, dst_ty)]; + let mut obls = PredicateObligations::with_capacity(1); + obls.push(make_transmute_obl(src_ty, dst_ty)); if !assume.lifetimes { obls.push(make_outlives_obl(src_lifetime, dst_lifetime)); } @@ -382,7 +385,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, cond: Condition>, assume: Assume, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { match cond { // FIXME(bryangarza): Add separate `IfAny` case, instead of treating as `IfAll` // Not possible until the trait solver supports disjunctions of obligations @@ -424,7 +427,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let fully_flattened = match maybe_transmutable { Answer::No(_) => Err(Unimplemented)?, Answer::If(cond) => flatten_answer_tree(self.tcx(), obligation, cond, assume), - Answer::Yes => vec![], + Answer::Yes => PredicateObligations::new(), }; debug!(?fully_flattened); @@ -439,7 +442,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_auto_impl_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { debug!(?obligation, "confirm_auto_impl_candidate"); let self_ty = obligation.predicate.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty)); @@ -453,14 +456,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, trait_def_id: DefId, nested: ty::Binder<'tcx, Vec>>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { debug!(?nested, "vtable_auto_impl"); ensure_sufficient_stack(|| { let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived); let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); let trait_ref = self.infcx.enter_forall_and_leak_universe(poly_trait_ref); - let trait_obligations: Vec> = self.impl_or_trait_obligations( + let trait_obligations = self.impl_or_trait_obligations( &cause, obligation.recursion_depth + 1, obligation.param_env, @@ -566,7 +569,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); let object_trait_ref = object_trait_ref.with_self_ty(self.tcx(), self_ty); - let mut nested = vec![]; + let mut nested = PredicateObligations::new(); let mut supertraits = util::supertraits(tcx, ty::Binder::dummy(object_trait_ref)); let unnormalized_upcast_trait_ref = @@ -706,7 +709,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, fn_host_effect: ty::Const<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { debug!(?obligation, "confirm_fn_pointer_candidate"); let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); @@ -750,7 +753,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_trait_alias_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { debug!(?obligation, "confirm_trait_alias_candidate"); let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); @@ -775,7 +778,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_coroutine_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else { @@ -805,7 +808,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_future_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else { @@ -835,7 +838,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_iterator_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else { @@ -865,7 +868,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_async_iterator_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else { @@ -896,7 +899,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_closure_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty: Ty<'_> = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); @@ -926,13 +929,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_async_closure_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let tcx = self.tcx(); - let mut nested = vec![]; + let mut nested = PredicateObligations::new(); let (trait_ref, kind_ty) = match *self_ty.kind() { ty::CoroutineClosure(_, args) => { let args = args.as_coroutine_closure(); @@ -1055,7 +1058,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: TraitObligation<'tcx>, found_trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let found_trait_ref = self.infcx.instantiate_binder_with_fresh_vars( obligation.cause.span, HigherRankedType, @@ -1210,7 +1213,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // words, if the object type is `Foo + Send`, this would create an obligation for // the `Send` check.) // - Projection predicates - let mut nested: Vec<_> = data + let mut nested: PredicateObligations<'_> = data .iter() .map(|predicate| predicate_to_obligation(predicate.with_self_ty(tcx, source))) .collect(); @@ -1254,7 +1257,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tail_field = def.non_enum_variant().tail(); let tail_field_ty = tcx.type_of(tail_field.did); - let mut nested = vec![]; + let mut nested = PredicateObligations::new(); // Extract `TailField` and `TailField` from `Struct` and `Struct`, // normalizing in the process, since `type_of` returns something directly from @@ -1339,7 +1342,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, impl_def_id: Option, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let Some(host_effect_index) = self.tcx().generics_of(obligation.predicate.def_id()).host_effect_index else { @@ -1353,7 +1356,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tcx = self.tcx(); let self_ty = obligation.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty)); - let mut nested = vec![]; + let mut nested = PredicateObligations::new(); let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived); // If we have a custom `impl const Drop`, then diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fba1d1025ca..621babe9104 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -18,7 +18,7 @@ use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::relate::TypeRelation; -use rustc_infer::traits::TraitObligation; +use rustc_infer::traits::{PredicateObligations, TraitObligation}; use rustc_middle::bug; use rustc_middle::dep_graph::{DepNodeIndex, dep_kinds}; use rustc_middle::mir::interpret::ErrorHandled; @@ -1067,7 +1067,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { && fresh_trait_pred.has_aliases() && fresh_trait_pred.is_global() { - let mut nested_obligations = Vec::new(); + let mut nested_obligations = PredicateObligations::new(); let predicate = normalize_with_depth_to( this, param_env, @@ -1715,7 +1715,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> ProjectionMatchesProjection { debug_assert_eq!(obligation.predicate.def_id, env_predicate.projection_def_id()); - let mut nested_obligations = Vec::new(); + let mut nested_obligations = PredicateObligations::new(); let infer_predicate = self.infcx.instantiate_binder_with_fresh_vars( obligation.cause.span, BoundRegionConversionTime::HigherRankedType, @@ -2410,7 +2410,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { recursion_depth: usize, trait_def_id: DefId, types: ty::Binder<'tcx, Vec>>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { // Because the types were potentially derived from // higher-ranked obligations they may reference late-bound // regions. For example, `for<'a> Foo<&'a i32> : Copy` would @@ -2552,9 +2552,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { b_data: &'tcx ty::List>, a_region: ty::Region<'tcx>, b_region: ty::Region<'tcx>, - ) -> SelectionResult<'tcx, Vec>> { + ) -> SelectionResult<'tcx, PredicateObligations<'tcx>> { let tcx = self.tcx(); - let mut nested = vec![]; + let mut nested = PredicateObligations::new(); // We may upcast to auto traits that are either explicitly listed in // the object type's bounds, or implied by the principal trait ref's @@ -2705,7 +2705,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, where_clause_trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Result>, ()> { + ) -> Result, ()> { self.match_poly_trait_ref(obligation, where_clause_trait_ref) } @@ -2716,7 +2716,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Result>, ()> { + ) -> Result, ()> { let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let trait_ref = self.infcx.instantiate_binder_with_fresh_vars( obligation.cause.span, @@ -2797,7 +2797,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { def_id: DefId, // of impl or trait args: GenericArgsRef<'tcx>, // for impl or trait parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { let tcx = self.tcx(); // To allow for one-pass evaluation of the nested obligation, @@ -2817,7 +2817,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let predicates = tcx.predicates_of(def_id); assert_eq!(predicates.parent, None); let predicates = predicates.instantiate_own(tcx, args); - let mut obligations = Vec::with_capacity(predicates.len()); + let mut obligations = PredicateObligations::with_capacity(predicates.len()); for (index, (predicate, span)) in predicates.into_iter().enumerate() { let cause = if tcx.is_lang_item(parent_trait_pred.def_id(), LangItem::CoerceUnsized) { cause.clone() diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index a849cdfe125..07e68e5a3e8 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -2,7 +2,7 @@ use std::iter; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; -use rustc_infer::traits::ObligationCauseCode; +use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; use rustc_middle::bug; use rustc_middle::ty::{ self, GenericArg, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, @@ -27,7 +27,7 @@ pub fn obligations<'tcx>( recursion_depth: usize, arg: GenericArg<'tcx>, span: Span, -) -> Option>> { +) -> Option> { // Handle the "livelock" case (see comment above) by bailing out if necessary. let arg = match arg.unpack() { GenericArgKind::Type(ty) => { @@ -61,11 +61,18 @@ pub fn obligations<'tcx>( .into() } // There is nothing we have to do for lifetimes. - GenericArgKind::Lifetime(..) => return Some(Vec::new()), + GenericArgKind::Lifetime(..) => return Some(PredicateObligations::new()), }; - let mut wf = - WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth, item: None }; + let mut wf = WfPredicates { + infcx, + param_env, + body_id, + span, + out: PredicateObligations::new(), + recursion_depth, + item: None, + }; wf.compute(arg); debug!("wf::obligations({:?}, body_id={:?}) = {:?}", arg, body_id, wf.out); @@ -82,7 +89,7 @@ pub fn unnormalized_obligations<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, arg: GenericArg<'tcx>, -) -> Option>> { +) -> Option> { debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg)); // However, if `arg` IS an unresolved inference variable, returns `None`, @@ -93,7 +100,7 @@ pub fn unnormalized_obligations<'tcx>( } if let ty::GenericArgKind::Lifetime(..) = arg.unpack() { - return Some(vec![]); + return Some(PredicateObligations::new()); } let mut wf = WfPredicates { @@ -101,7 +108,7 @@ pub fn unnormalized_obligations<'tcx>( param_env, body_id: CRATE_DEF_ID, span: DUMMY_SP, - out: vec![], + out: PredicateObligations::new(), recursion_depth: 0, item: None, }; @@ -120,13 +127,13 @@ pub fn trait_obligations<'tcx>( trait_pred: ty::TraitPredicate<'tcx>, span: Span, item: &'tcx hir::Item<'tcx>, -) -> Vec> { +) -> PredicateObligations<'tcx> { let mut wf = WfPredicates { infcx, param_env, body_id, span, - out: vec![], + out: PredicateObligations::new(), recursion_depth: 0, item: Some(item), }; @@ -147,13 +154,13 @@ pub fn clause_obligations<'tcx>( body_id: LocalDefId, clause: ty::Clause<'tcx>, span: Span, -) -> Vec> { +) -> PredicateObligations<'tcx> { let mut wf = WfPredicates { infcx, param_env, body_id, span, - out: vec![], + out: PredicateObligations::new(), recursion_depth: 0, item: None, }; @@ -192,7 +199,7 @@ struct WfPredicates<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, body_id: LocalDefId, span: Span, - out: Vec>, + out: PredicateObligations<'tcx>, recursion_depth: usize, item: Option<&'tcx hir::Item<'tcx>>, } @@ -323,7 +330,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { traits::ObligationCause::new(self.span, self.body_id, code) } - fn normalize(self, infcx: &InferCtxt<'tcx>) -> Vec> { + fn normalize(self, infcx: &InferCtxt<'tcx>) -> PredicateObligations<'tcx> { // Do not normalize `wf` obligations with the new solver. // // The current deep normalization routine with the new solver does not @@ -336,7 +343,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let cause = self.cause(ObligationCauseCode::WellFormed(None)); let param_env = self.param_env; - let mut obligations = Vec::with_capacity(self.out.len()); + let mut obligations = PredicateObligations::with_capacity(self.out.len()); for mut obligation in self.out { assert!(!obligation.has_escaping_bound_vars()); let mut selcx = traits::SelectionContext::new(infcx); @@ -553,7 +560,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { &mut self, def_id: DefId, args: GenericArgsRef<'tcx>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { let predicates = self.tcx().predicates_of(def_id); let mut origins = vec![def_id; predicates.predicates.len()]; let mut head = predicates; diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 3102da218db..4c2b7e4769a 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -1,5 +1,6 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; +use rustc_infer::traits::PredicateObligations; use rustc_middle::query::Providers; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; @@ -30,7 +31,7 @@ fn normalize_canonicalized_projection_ty<'tcx>( debug_assert!(!ocx.infcx.next_trait_solver()); let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); let answer = traits::normalize_projection_ty(selcx, param_env, goal, cause, 0, &mut obligations); ocx.register_obligations(obligations); @@ -99,7 +100,7 @@ fn normalize_canonicalized_inherent_projection_ty<'tcx>( |ocx, ParamEnvAnd { param_env, value: goal }| { let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); let answer = traits::normalize_inherent_projection( selcx, param_env, -- cgit 1.4.1-3-g733a5 From 8de8f46f789e5e61a0129fd9a7cf0c942a6301d8 Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Thu, 10 Oct 2024 19:56:21 +0100 Subject: Swap PredicateObligation to ThinVec --- Cargo.lock | 5 +- .../src/obligation_forest/mod.rs | 3 +- .../src/obligation_forest/tests.rs | 68 ++++++++++++---------- compiler/rustc_infer/Cargo.toml | 1 + compiler/rustc_infer/src/traits/mod.rs | 3 +- compiler/rustc_middle/src/traits/mod.rs | 9 +-- compiler/rustc_trait_selection/Cargo.toml | 1 + .../rustc_trait_selection/src/solve/fulfill.rs | 4 +- .../rustc_trait_selection/src/traits/fulfill.rs | 3 +- compiler/rustc_type_ir/Cargo.toml | 3 +- compiler/rustc_type_ir/src/fold.rs | 7 +++ compiler/rustc_type_ir/src/visit.rs | 8 +++ 12 files changed, 73 insertions(+), 42 deletions(-) (limited to 'compiler/rustc_data_structures/src') diff --git a/Cargo.lock b/Cargo.lock index c62c379f70d..501d143890b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -3857,6 +3857,7 @@ dependencies = [ "rustc_target", "rustc_type_ir", "smallvec", + "thin-vec", "tracing", ] @@ -4490,6 +4491,7 @@ dependencies = [ "rustc_transmute", "rustc_type_ir", "smallvec", + "thin-vec", "tracing", ] @@ -4561,6 +4563,7 @@ dependencies = [ "rustc_span", "rustc_type_ir_macros", "smallvec", + "thin-vec", "tracing", ] diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index aca99b9fab1..34a2464972a 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -75,6 +75,7 @@ use std::fmt::Debug; use std::hash; use std::marker::PhantomData; +use thin_vec::ThinVec; use tracing::debug; use crate::fx::{FxHashMap, FxHashSet}; @@ -141,7 +142,7 @@ pub trait ObligationProcessor { #[derive(Debug)] pub enum ProcessResult { Unchanged, - Changed(Vec), + Changed(ThinVec), Error(E), } diff --git a/compiler/rustc_data_structures/src/obligation_forest/tests.rs b/compiler/rustc_data_structures/src/obligation_forest/tests.rs index 8391e98ba8b..739ef74e3f7 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/tests.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/tests.rs @@ -1,5 +1,7 @@ use std::fmt; +use thin_vec::thin_vec; + use super::*; impl<'a> super::ForestObligation for &'a str { @@ -101,9 +103,9 @@ fn push_pop() { // |-> A.3 let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]), + "A" => ProcessResult::Changed(thin_vec!["A.1", "A.2", "A.3"]), "B" => ProcessResult::Error("B is for broken"), - "C" => ProcessResult::Changed(vec![]), + "C" => ProcessResult::Changed(thin_vec![]), "A.1" | "A.2" | "A.3" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -123,8 +125,8 @@ fn push_pop() { |obligation| match *obligation { "A.1" => ProcessResult::Unchanged, "A.2" => ProcessResult::Unchanged, - "A.3" => ProcessResult::Changed(vec!["A.3.i"]), - "D" => ProcessResult::Changed(vec!["D.1", "D.2"]), + "A.3" => ProcessResult::Changed(thin_vec!["A.3.i"]), + "D" => ProcessResult::Changed(thin_vec!["D.1", "D.2"]), "A.3.i" | "D.1" | "D.2" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -139,11 +141,11 @@ fn push_pop() { // |-> D.2 |-> D.2.i let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A.1" => ProcessResult::Changed(vec![]), + "A.1" => ProcessResult::Changed(thin_vec![]), "A.2" => ProcessResult::Error("A is for apple"), - "A.3.i" => ProcessResult::Changed(vec![]), - "D.1" => ProcessResult::Changed(vec!["D.1.i"]), - "D.2" => ProcessResult::Changed(vec!["D.2.i"]), + "A.3.i" => ProcessResult::Changed(thin_vec![]), + "D.1" => ProcessResult::Changed(thin_vec!["D.1.i"]), + "D.2" => ProcessResult::Changed(thin_vec!["D.2.i"]), "D.1.i" | "D.2.i" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -158,7 +160,7 @@ fn push_pop() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { "D.1.i" => ProcessResult::Error("D is for dumb"), - "D.2.i" => ProcessResult::Changed(vec![]), + "D.2.i" => ProcessResult::Changed(thin_vec![]), _ => panic!("unexpected obligation {:?}", obligation), }, |_| {}, @@ -184,10 +186,10 @@ fn success_in_grandchildren() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]), - "A.1" => ProcessResult::Changed(vec![]), - "A.2" => ProcessResult::Changed(vec!["A.2.i", "A.2.ii"]), - "A.3" => ProcessResult::Changed(vec![]), + "A" => ProcessResult::Changed(thin_vec!["A.1", "A.2", "A.3"]), + "A.1" => ProcessResult::Changed(thin_vec![]), + "A.2" => ProcessResult::Changed(thin_vec!["A.2.i", "A.2.ii"]), + "A.3" => ProcessResult::Changed(thin_vec![]), "A.2.i" | "A.2.ii" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -201,7 +203,7 @@ fn success_in_grandchildren() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { "A.2.i" => ProcessResult::Unchanged, - "A.2.ii" => ProcessResult::Changed(vec![]), + "A.2.ii" => ProcessResult::Changed(thin_vec![]), _ => unreachable!(), }, |_| {}, @@ -211,7 +213,7 @@ fn success_in_grandchildren() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A.2.i" => ProcessResult::Changed(vec!["A.2.i.a"]), + "A.2.i" => ProcessResult::Changed(thin_vec!["A.2.i.a"]), "A.2.i.a" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -222,7 +224,7 @@ fn success_in_grandchildren() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A.2.i.a" => ProcessResult::Changed(vec![]), + "A.2.i.a" => ProcessResult::Changed(thin_vec![]), _ => unreachable!(), }, |_| {}, @@ -247,7 +249,7 @@ fn to_errors_no_throw() { forest.register_obligation("A"); let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]), + "A" => ProcessResult::Changed(thin_vec!["A.1", "A.2", "A.3"]), "A.1" | "A.2" | "A.3" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -269,7 +271,7 @@ fn diamond() { forest.register_obligation("A"); let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A" => ProcessResult::Changed(vec!["A.1", "A.2"]), + "A" => ProcessResult::Changed(thin_vec!["A.1", "A.2"]), "A.1" | "A.2" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -280,8 +282,8 @@ fn diamond() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A.1" => ProcessResult::Changed(vec!["D"]), - "A.2" => ProcessResult::Changed(vec!["D"]), + "A.1" => ProcessResult::Changed(thin_vec!["D"]), + "A.2" => ProcessResult::Changed(thin_vec!["D"]), "D" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -295,7 +297,7 @@ fn diamond() { |obligation| match *obligation { "D" => { d_count += 1; - ProcessResult::Changed(vec![]) + ProcessResult::Changed(thin_vec![]) } _ => unreachable!(), }, @@ -313,7 +315,7 @@ fn diamond() { forest.register_obligation("A'"); let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A'" => ProcessResult::Changed(vec!["A'.1", "A'.2"]), + "A'" => ProcessResult::Changed(thin_vec!["A'.1", "A'.2"]), "A'.1" | "A'.2" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -324,8 +326,8 @@ fn diamond() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A'.1" => ProcessResult::Changed(vec!["D'", "A'"]), - "A'.2" => ProcessResult::Changed(vec!["D'"]), + "A'.1" => ProcessResult::Changed(thin_vec!["D'", "A'"]), + "A'.2" => ProcessResult::Changed(thin_vec!["D'"]), "D'" | "A'" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -366,7 +368,7 @@ fn done_dependency() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A: Sized" | "B: Sized" | "C: Sized" => ProcessResult::Changed(vec![]), + "A: Sized" | "B: Sized" | "C: Sized" => ProcessResult::Changed(thin_vec![]), _ => unreachable!(), }, |_| {}, @@ -379,7 +381,9 @@ fn done_dependency() { forest.register_obligation("(A,B,C): Sized"); let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "(A,B,C): Sized" => ProcessResult::Changed(vec!["A: Sized", "B: Sized", "C: Sized"]), + "(A,B,C): Sized" => { + ProcessResult::Changed(thin_vec!["A: Sized", "B: Sized", "C: Sized"]) + } _ => unreachable!(), }, |_| {}, @@ -399,10 +403,10 @@ fn orphan() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A" => ProcessResult::Changed(vec!["D", "E"]), + "A" => ProcessResult::Changed(thin_vec!["D", "E"]), "B" => ProcessResult::Unchanged, - "C1" => ProcessResult::Changed(vec![]), - "C2" => ProcessResult::Changed(vec![]), + "C1" => ProcessResult::Changed(thin_vec![]), + "C2" => ProcessResult::Changed(thin_vec![]), "D" | "E" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -416,7 +420,7 @@ fn orphan() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { "D" | "E" => ProcessResult::Unchanged, - "B" => ProcessResult::Changed(vec!["D"]), + "B" => ProcessResult::Changed(thin_vec!["D"]), _ => unreachable!(), }, |_| {}, @@ -459,7 +463,7 @@ fn simultaneous_register_and_error() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { "A" => ProcessResult::Error("An error"), - "B" => ProcessResult::Changed(vec!["A"]), + "B" => ProcessResult::Changed(thin_vec!["A"]), _ => unreachable!(), }, |_| {}, @@ -474,7 +478,7 @@ fn simultaneous_register_and_error() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { "A" => ProcessResult::Error("An error"), - "B" => ProcessResult::Changed(vec!["A"]), + "B" => ProcessResult::Changed(thin_vec!["A"]), _ => unreachable!(), }, |_| {}, diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 1f616710200..ef5a1468c87 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -21,5 +21,6 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } +thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 2d02391c57a..ac641ef5652 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -17,6 +17,7 @@ use rustc_middle::traits::solve::Certainty; pub use rustc_middle::traits::*; use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; use rustc_span::Span; +use thin_vec::ThinVec; pub use self::ImplSource::*; pub use self::SelectionError::*; @@ -84,7 +85,7 @@ pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>; pub type TraitObligation<'tcx> = Obligation<'tcx, ty::TraitPredicate<'tcx>>; pub type PolyTraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>; -pub type PredicateObligations<'tcx> = Vec>; +pub type PredicateObligations<'tcx> = ThinVec>; impl<'tcx> PredicateObligation<'tcx> { /// Flips the polarity of the inner predicate. diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index caa86da8a85..8ee8b4c4823 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -25,6 +25,7 @@ use rustc_span::{DUMMY_SP, Span}; // FIXME: Remove this import and import via `solve::` pub use rustc_type_ir::solve::{BuiltinImplSource, Reveal}; use smallvec::{SmallVec, smallvec}; +use thin_vec::ThinVec; pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache}; use crate::mir::ConstraintCategory; @@ -625,14 +626,14 @@ pub enum ImplSource<'tcx, N> { /// for some type parameter. The `Vec` represents the /// obligations incurred from normalizing the where-clause (if /// any). - Param(Vec), + Param(ThinVec), /// Successful resolution for a builtin impl. - Builtin(BuiltinImplSource, Vec), + Builtin(BuiltinImplSource, ThinVec), } impl<'tcx, N> ImplSource<'tcx, N> { - pub fn nested_obligations(self) -> Vec { + pub fn nested_obligations(self) -> ThinVec { match self { ImplSource::UserDefined(i) => i.nested, ImplSource::Param(n) | ImplSource::Builtin(_, n) => n, @@ -686,7 +687,7 @@ impl<'tcx, N> ImplSource<'tcx, N> { pub struct ImplSourceUserDefinedData<'tcx, N> { pub impl_def_id: DefId, pub args: GenericArgsRef<'tcx>, - pub nested: Vec, + pub nested: ThinVec, } #[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)] diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index f023a0eb53a..d4bb84838cc 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -26,5 +26,6 @@ rustc_target = { path = "../rustc_target" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } +thin-vec = "0.2" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 8ec4427091d..d9dc772eca9 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -2,6 +2,7 @@ use std::marker::PhantomData; use std::mem; use std::ops::ControlFlow; +use rustc_data_structures::thinvec::ExtractIf; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause}; @@ -81,7 +82,8 @@ impl<'tcx> ObligationStorage<'tcx> { // we get all obligations involved in the overflow. We pretty much check: if // we were to do another step of `select_where_possible`, which goals would // change. - self.overflowed.extend(self.pending.extract_if(|o| { + // FIXME: is merged, this can be removed. + self.overflowed.extend(ExtractIf::new(&mut self.pending, |o| { let goal = o.clone().into(); let result = <&SolverDelegate<'tcx>>::from(infcx) .evaluate_root_goal(goal, GenerateProofTree::No) diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 3e3834a11c6..e56f1866970 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -14,6 +14,7 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, Binder, Const, GenericArgsRef, TypeVisitableExt}; +use thin_vec::ThinVec; use tracing::{debug, debug_span, instrument}; use super::project::{self, ProjectAndUnifyResult}; @@ -28,7 +29,7 @@ use crate::traits::normalize::normalize_with_depth_to; use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _}; use crate::traits::query::evaluate_obligation::InferCtxtExt; -pub(crate) type PendingPredicateObligations<'tcx> = Vec>; +pub(crate) type PendingPredicateObligations<'tcx> = ThinVec>; impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { /// Note that we include both the `ParamEnv` and the `Predicate`, diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 98cc116bd00..8d97ec72830 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -17,6 +17,7 @@ rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } smallvec = { version = "1.8.1", default-features = false } +thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end @@ -30,7 +31,7 @@ nightly = [ "smallvec/may_dangle", "smallvec/union", "rustc_index/nightly", - "rustc_ast_ir/nightly" + "rustc_ast_ir/nightly", ] [lints.rust] diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 64ce6fd69e6..8209d6f5fe3 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -48,6 +48,7 @@ use std::mem; use rustc_index::{Idx, IndexVec}; +use thin_vec::ThinVec; use tracing::instrument; use crate::data_structures::Lrc; @@ -322,6 +323,12 @@ impl> TypeFoldable for Vec { } } +impl> TypeFoldable for ThinVec { + fn try_fold_with>(self, folder: &mut F) -> Result { + self.into_iter().map(|t| t.try_fold_with(folder)).collect() + } +} + impl> TypeFoldable for Box<[T]> { fn try_fold_with>(self, folder: &mut F) -> Result { Vec::from(self).try_fold_with(folder).map(Vec::into_boxed_slice) diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 0ba7e2bd552..71c3646498b 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -47,6 +47,7 @@ use std::ops::ControlFlow; use rustc_ast_ir::visit::VisitorResult; use rustc_ast_ir::{try_visit, walk_visitable_list}; use rustc_index::{Idx, IndexVec}; +use thin_vec::ThinVec; use crate::data_structures::Lrc; use crate::inherent::*; @@ -184,6 +185,13 @@ impl> TypeVisitable for Vec { } } +impl> TypeVisitable for ThinVec { + fn visit_with>(&self, visitor: &mut V) -> V::Result { + walk_visitable_list!(visitor, self.iter()); + V::Result::output() + } +} + // `TypeFoldable` isn't impl'd for `&[T]`. It doesn't make sense in the general // case, because we can't return a new slice. But note that there are a couple // of trivial impls of `TypeFoldable` for specific slice types elsewhere. -- cgit 1.4.1-3-g733a5 From acb09bf741ba439356e824dd10a07054c6656fb6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 14 Oct 2024 14:46:44 -0700 Subject: update bootstrap configs --- compiler/rustc_const_eval/src/lib.rs | 4 +-- compiler/rustc_data_structures/src/steal.rs | 2 +- compiler/rustc_lint/src/if_let_rescope.rs | 2 +- compiler/rustc_lint_defs/src/builtin.rs | 1 - compiler/rustc_next_trait_solver/src/lib.rs | 2 +- compiler/rustc_type_ir/src/lib.rs | 2 +- library/alloc/src/lib.rs | 2 -- library/alloc/tests/lib.rs | 1 - library/alloc/tests/vec.rs | 2 +- library/core/src/arch.rs | 35 ---------------------- library/core/src/array/mod.rs | 1 - library/core/src/cell.rs | 1 - library/core/src/char/methods.rs | 4 --- library/core/src/intrinsics.rs | 4 --- library/core/src/lib.rs | 3 -- library/core/src/mem/maybe_uninit.rs | 3 -- library/core/src/mem/mod.rs | 1 - library/core/src/num/mod.rs | 2 -- library/core/src/option.rs | 4 --- library/core/src/ptr/mod.rs | 5 +--- library/core/src/ptr/mut_ptr.rs | 2 -- library/core/src/ptr/non_null.rs | 1 - library/core/src/result.rs | 2 -- library/core/src/slice/ascii.rs | 2 -- library/core/src/slice/mod.rs | 12 -------- library/core/src/slice/raw.rs | 2 -- library/core/src/str/converts.rs | 1 - library/core/src/str/mod.rs | 4 --- library/core/tests/atomic.rs | 2 +- library/core/tests/lib.rs | 1 - library/std/src/lib.rs | 1 - src/tools/miri/src/lib.rs | 4 +-- .../internal-lints/import-of-type-ir-inherent.rs | 3 -- .../import-of-type-ir-inherent.stderr | 8 ++--- .../internal-lints/query_completeness.rs | 2 -- .../internal-lints/query_completeness.stderr | 4 +-- 36 files changed, 17 insertions(+), 115 deletions(-) (limited to 'compiler/rustc_data_structures/src') diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index cbe8a043fba..39e2d3b4ebb 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,8 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] -#![cfg_attr(not(bootstrap), feature(unqualified_local_imports))] -#![cfg_attr(not(bootstrap), warn(unqualified_local_imports))] #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] @@ -15,7 +13,9 @@ #![feature(strict_provenance)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(unqualified_local_imports)] #![feature(yeet_expr)] +#![warn(unqualified_local_imports)] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/compiler/rustc_data_structures/src/steal.rs b/compiler/rustc_data_structures/src/steal.rs index aaa95f6b7f1..0d79d98b5d9 100644 --- a/compiler/rustc_data_structures/src/steal.rs +++ b/compiler/rustc_data_structures/src/steal.rs @@ -57,7 +57,7 @@ impl Steal { /// /// This should not be used within rustc as it leaks information not tracked /// by the query system, breaking incremental compilation. - #[cfg_attr(not(bootstrap), rustc_lint_untracked_query_information)] + #[rustc_lint_untracked_query_information] pub fn is_stolen(&self) -> bool { self.value.borrow().is_none() } diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index cdd0e80c458..58fd11fcc29 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -24,7 +24,7 @@ declare_lint! { /// ### Example /// /// ```rust,edition2021 - /// #![cfg_attr(not(bootstrap), feature(if_let_rescope))] // Simplify this in bootstrap bump. + /// #![feature(if_let_rescope)] /// #![warn(if_let_rescope)] /// #![allow(unused_variables)] /// diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index da603df9a9a..f532b9b153b 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1871,7 +1871,6 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail - /// # #[cfg_attr(bootstrap)] compile_error!(); // Remove this in bootstrap bump. /// #![deny(elided_named_lifetimes)] /// struct Foo; /// impl Foo { diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index de74ac32804..d67ae2550d9 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -5,7 +5,7 @@ //! So if you got to this crate from the old solver, it's totally normal. // tidy-alphabetical-start -#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))] +#![allow(rustc::usage_of_type_ir_inherent)] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 51c887fc4da..9e6d1f424ba 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -1,11 +1,11 @@ // tidy-alphabetical-start #![allow(rustc::usage_of_ty_tykind)] +#![allow(rustc::usage_of_type_ir_inherent)] #![cfg_attr( feature = "nightly", feature(associated_type_defaults, never_type, rustc_attrs, negative_impls) )] #![cfg_attr(feature = "nightly", allow(internal_features))] -#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 50bf385d671..12512f0dd8c 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -162,8 +162,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_mut_refs))] -#![cfg_attr(bootstrap, feature(const_refs_to_cell))] #![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(test, feature(panic_update_hook))] #![cfg_attr(test, feature(test))] diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 3ec4332c71b..301126b5d4d 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -5,7 +5,6 @@ #![feature(btree_extract_if)] #![feature(cow_is_borrowed)] #![feature(const_heap)] -#![cfg_attr(bootstrap, feature(const_mut_refs))] #![feature(const_try)] #![feature(core_intrinsics)] #![feature(extract_if)] diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index f508a3e4c22..0f27fdff3e1 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1288,7 +1288,7 @@ fn test_from_iter_specialization_panic_during_iteration_drops() { #[test] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint -#[cfg_attr(not(bootstrap), allow(static_mut_refs))] +#[allow(static_mut_refs)] fn test_from_iter_specialization_panic_during_drop_doesnt_leak() { static mut DROP_COUNTER_OLD: [usize; 5] = [0; 5]; static mut DROP_COUNTER_NEW: [usize; 2] = [0; 2]; diff --git a/library/core/src/arch.rs b/library/core/src/arch.rs index 4945c045bc6..57f456c98b3 100644 --- a/library/core/src/arch.rs +++ b/library/core/src/arch.rs @@ -3,9 +3,6 @@ #[allow(unused_imports)] #[stable(feature = "simd_arch", since = "1.27.0")] pub use crate::core_arch::arch::*; -#[unstable(feature = "naked_functions", issue = "90957")] -#[cfg(bootstrap)] -pub use crate::naked_asm; /// Inline assembly. /// @@ -20,37 +17,6 @@ pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ } -/// Inline assembly used in combination with `#[naked]` functions. -/// -/// Refer to [Rust By Example] for a usage guide and the [reference] for -/// detailed information about the syntax and available options. -/// -/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html -/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html -#[unstable(feature = "naked_functions", issue = "90957")] -#[macro_export] -#[cfg(bootstrap)] -macro_rules! naked_asm { - ([$last:expr], [$($pushed:expr),*]) => { - #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] - { - core::arch::asm!($($pushed),*, options(att_syntax, noreturn)) - } - #[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] - { - core::arch::asm!($($pushed),* , $last, options(noreturn)) - } - }; - - ([$first:expr $(, $rest:expr)*], [$($pushed:expr),*]) => { - naked_asm!([$($rest),*], [$($pushed,)* $first]); - }; - - ($($expr:expr),* $(,)?) => { - naked_asm!([$($expr),*], []); - }; -} - /// Inline assembly used in combination with `#[naked]` functions. /// /// Refer to [Rust By Example] for a usage guide and the [reference] for @@ -60,7 +26,6 @@ macro_rules! naked_asm { /// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html #[unstable(feature = "naked_functions", issue = "90957")] #[rustc_builtin_macro] -#[cfg(not(bootstrap))] pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ } diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 72f48878904..9b28b8b613e 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -147,7 +147,6 @@ pub const fn from_ref(s: &T) -> &[T; 1] { /// Converts a mutable reference to `T` into a mutable reference to an array of length 1 (without copying). #[stable(feature = "array_from_ref", since = "1.53.0")] #[rustc_const_stable(feature = "const_array_from_ref", since = "1.83.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn from_mut(s: &mut T) -> &mut [T; 1] { // SAFETY: Converting `&mut T` to `&mut [T; 1]` is sound. unsafe { &mut *(s as *mut T).cast::<[T; 1]>() } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 0945845021e..e1fa43296d0 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2181,7 +2181,6 @@ impl UnsafeCell { /// ``` #[inline(always)] #[stable(feature = "unsafe_cell_get_mut", since = "1.50.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_unsafecell_get_mut", since = "1.83.0")] pub const fn get_mut(&mut self) -> &mut T { &mut self.value diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 1abfaa46ec6..30c0fff3104 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -676,7 +676,6 @@ impl char { #[stable(feature = "unicode_encode_char", since = "1.15.0")] #[rustc_const_stable(feature = "const_char_encode_utf8", since = "1.83.0")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn encode_utf8(self, dst: &mut [u8]) -> &mut str { // SAFETY: `char` is not a surrogate, so this is valid UTF-8. unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) } @@ -1284,7 +1283,6 @@ impl char { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); } @@ -1311,7 +1309,6 @@ impl char { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } @@ -1777,7 +1774,6 @@ const fn len_utf16(code: u32) -> usize { #[doc(hidden)] #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] { const fn panic_at_const(_code: u32, _len: usize, _dst_len: usize) { // Note that we cannot format in constant expressions. diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index ca5b9fc98b9..69ad4f41519 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1807,7 +1807,6 @@ extern "rust-intrinsic" { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_nounwind] - #[cfg(not(bootstrap))] pub fn fmuladdf16(a: f16, b: f16, c: f16) -> f16; /// Returns `a * b + c` for `f32` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the @@ -1820,7 +1819,6 @@ extern "rust-intrinsic" { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_nounwind] - #[cfg(not(bootstrap))] pub fn fmuladdf32(a: f32, b: f32, c: f32) -> f32; /// Returns `a * b + c` for `f64` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the @@ -1833,7 +1831,6 @@ extern "rust-intrinsic" { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_nounwind] - #[cfg(not(bootstrap))] pub fn fmuladdf64(a: f64, b: f64, c: f64) -> f64; /// Returns `a * b + c` for `f128` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the @@ -1846,7 +1843,6 @@ extern "rust-intrinsic" { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_nounwind] - #[cfg(not(bootstrap))] pub fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; /// Returns the largest integer less than or equal to an `f16`. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index ccd6534de9b..7060da172f3 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -173,9 +173,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_mut_refs))] -#![cfg_attr(bootstrap, feature(const_refs_to_cell))] -#![cfg_attr(bootstrap, feature(const_refs_to_static))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index bb01d4e642c..ea73cfc3781 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -570,7 +570,6 @@ impl MaybeUninit { /// until they are, it is advisable to avoid them.) #[stable(feature = "maybe_uninit", since = "1.36.0")] #[rustc_const_stable(feature = "const_maybe_uninit_as_mut_ptr", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[inline(always)] pub const fn as_mut_ptr(&mut self) -> *mut T { // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer. @@ -910,7 +909,6 @@ impl MaybeUninit { /// }; /// ``` #[stable(feature = "maybe_uninit_ref", since = "1.55.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable( feature = "const_maybe_uninit_assume_init", since = "CURRENT_RUSTC_VERSION" @@ -1000,7 +998,6 @@ impl MaybeUninit { /// /// [`assume_init_mut`]: MaybeUninit::assume_init_mut #[unstable(feature = "maybe_uninit_slice", issue = "63569")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")] #[inline(always)] pub const unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] { diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index ada80463306..74b198c4fdd 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -857,7 +857,6 @@ pub fn take(dest: &mut T) -> T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you don't need the old value, you can just assign the new value directly"] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_replace", since = "1.83.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")] pub const fn replace(dest: &mut T, src: T) -> T { diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index f55d55171f2..5e2f45884dd 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -626,7 +626,6 @@ impl u8 { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); } @@ -653,7 +652,6 @@ impl u8 { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 661176ce9fc..0b996c40c04 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -723,7 +723,6 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn as_mut(&mut self) -> Option<&mut T> { match *self { @@ -1716,7 +1715,6 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn take(&mut self) -> Option { // FIXME(const-hack) replace `mem::replace` by `mem::take` when the latter is const ready @@ -1775,7 +1773,6 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_replace", since = "1.31.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn replace(&mut self, value: T) -> Option { mem::replace(self, Some(value)) @@ -1937,7 +1934,6 @@ impl Option<&mut T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "copied", since = "1.35.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn copied(self) -> Option where diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 61b48e312cf..09ff7f8cab1 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1265,7 +1265,6 @@ const unsafe fn swap_nonoverlapping_simple_untyped(x: *mut T, y: *mut T, coun /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_replace", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_replace"] pub const unsafe fn replace(dst: *mut T, src: T) -> T { @@ -1518,7 +1517,6 @@ pub const unsafe fn read(src: *const T) -> T { #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_read_unaligned"] pub const unsafe fn read_unaligned(src: *const T) -> T { @@ -1725,7 +1723,6 @@ pub const unsafe fn write(dst: *mut T, src: T) { /// ``` #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_refs_to_cell))] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_write_unaligned"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -1918,7 +1915,7 @@ pub unsafe fn write_volatile(dst: *mut T, src: T) { /// than trying to adapt this to accommodate that change. /// /// Any questions go to @nagisa. -#[cfg_attr(not(bootstrap), allow(ptr_to_integer_transmute_in_consts))] +#[allow(ptr_to_integer_transmute_in_consts)] #[lang = "align_offset"] pub(crate) const unsafe fn align_offset(p: *const T, a: usize) -> usize { // FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <= diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index d7ce197848b..613d2c91ac6 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1678,7 +1678,6 @@ impl *mut T { /// /// ``` /// #![feature(const_pointer_is_aligned)] - /// # #![cfg_attr(bootstrap, feature(const_mut_refs))] /// /// // On some platforms, the alignment of primitives is less than their size. /// #[repr(align(4))] @@ -1804,7 +1803,6 @@ impl *mut T { /// ``` /// #![feature(pointer_is_aligned_to)] /// #![feature(const_pointer_is_aligned)] - /// # #![cfg_attr(bootstrap, feature(const_mut_refs))] /// /// // On some platforms, the alignment of i32 is less than 4. /// #[repr(align(4))] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index c6839136348..dfd0bd8fd1e 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -394,7 +394,6 @@ impl NonNull { /// /// [the module documentation]: crate::ptr#safety #[stable(feature = "nonnull", since = "1.25.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_ptr_as_ref", since = "1.83.0")] #[must_use] #[inline(always)] diff --git a/library/core/src/result.rs b/library/core/src/result.rs index e84c4e3a239..330d1eb14ed 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -735,7 +735,6 @@ impl Result { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_result", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn as_mut(&mut self) -> Result<&mut T, &mut E> { match *self { Ok(ref mut x) => Ok(x), @@ -1589,7 +1588,6 @@ impl Result<&mut T, E> { #[inline] #[stable(feature = "result_copied", since = "1.59.0")] #[rustc_const_stable(feature = "const_result", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] pub const fn copied(self) -> Result where diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 8d8ac6a1d2a..a03e9fbae11 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -69,7 +69,6 @@ impl [u8] { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. let mut i = 0; @@ -92,7 +91,6 @@ impl [u8] { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. let mut i = 0; diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 9fdcea1f7b7..dbcfe946440 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -171,7 +171,6 @@ impl [T] { /// assert_eq!(None, y.first_mut()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] @@ -214,7 +213,6 @@ impl [T] { /// assert_eq!(x, &[3, 4, 5]); /// ``` #[stable(feature = "slice_splits", since = "1.5.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] @@ -257,7 +255,6 @@ impl [T] { /// assert_eq!(x, &[4, 5, 3]); /// ``` #[stable(feature = "slice_splits", since = "1.5.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] @@ -300,7 +297,6 @@ impl [T] { /// assert_eq!(None, y.last_mut()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] @@ -357,7 +353,6 @@ impl [T] { #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn first_chunk_mut(&mut self) -> Option<&mut [T; N]> { if self.len() < N { None @@ -423,7 +418,6 @@ impl [T] { #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn split_first_chunk_mut( &mut self, ) -> Option<(&mut [T; N], &mut [T])> { @@ -494,7 +488,6 @@ impl [T] { #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn split_last_chunk_mut( &mut self, ) -> Option<(&mut [T], &mut [T; N])> { @@ -564,7 +557,6 @@ impl [T] { #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn last_chunk_mut(&mut self) -> Option<&mut [T; N]> { if self.len() < N { None @@ -853,7 +845,6 @@ impl [T] { /// [`as_mut_ptr`]: slice::as_mut_ptr #[stable(feature = "slice_ptr_range", since = "1.48.0")] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs, const_refs_to_cell))] #[inline] #[must_use] pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> { @@ -1908,7 +1899,6 @@ impl [T] { #[track_caller] #[must_use] #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { match self.split_at_mut_checked(mid) { Some(pair) => pair, @@ -2011,7 +2001,6 @@ impl [T] { /// ``` #[stable(feature = "slice_split_at_unchecked", since = "1.79.0")] #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[inline] #[must_use] pub const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) { @@ -2112,7 +2101,6 @@ impl [T] { /// ``` #[stable(feature = "split_at_checked", since = "1.80.0")] #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[inline] #[must_use] pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut [T], &mut [T])> { diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 976749cc148..89840881c4d 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -172,7 +172,6 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "1.83.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[must_use] #[rustc_diagnostic_item = "slice_from_raw_parts_mut"] pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { @@ -205,7 +204,6 @@ pub const fn from_ref(s: &T) -> &[T] { /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] #[rustc_const_stable(feature = "const_slice_from_ref", since = "1.83.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[must_use] pub const fn from_mut(s: &mut T) -> &mut [T] { array::from_mut(s) diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs index b61ed454cd9..c997e5e443d 100644 --- a/library/core/src/str/converts.rs +++ b/library/core/src/str/converts.rs @@ -195,7 +195,6 @@ pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { #[inline] #[must_use] #[stable(feature = "str_mut_extras", since = "1.20.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_str_from_utf8_unchecked_mut", since = "1.83.0")] #[rustc_diagnostic_item = "str_from_utf8_unchecked_mut"] pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 09938dda262..89addc4cb74 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -339,7 +339,6 @@ impl str { /// assert_eq!("🍔∈🌏", s); /// ``` #[stable(feature = "str_mut_extras", since = "1.20.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_str_as_mut", since = "1.83.0")] #[must_use] #[inline(always)] @@ -386,7 +385,6 @@ impl str { /// It is your responsibility to make sure that the string slice only gets /// modified in a way that it remains valid UTF-8. #[stable(feature = "str_as_mut_ptr", since = "1.36.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_str_as_mut", since = "1.83.0")] #[rustc_never_returns_null_ptr] #[must_use] @@ -2477,7 +2475,6 @@ impl str { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. let me = unsafe { self.as_bytes_mut() }; @@ -2506,7 +2503,6 @@ impl str { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. let me = unsafe { self.as_bytes_mut() }; diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs index 2bdaeb3845a..0ffba538b20 100644 --- a/library/core/tests/atomic.rs +++ b/library/core/tests/atomic.rs @@ -229,7 +229,7 @@ fn static_init() { #[test] // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint -#[cfg_attr(not(bootstrap), allow(static_mut_refs))] +#[allow(static_mut_refs)] fn atomic_access_bool() { static mut ATOMIC: AtomicBool = AtomicBool::new(false); diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 37e7db1157c..bfc0b638b7e 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -1,5 +1,4 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_mut_refs))] #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_match))] #![feature(alloc_layout_extra)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index ed448e50e60..3ab65238368 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -279,7 +279,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_mut_refs))] #![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index f089d1e1bcc..9814858beaa 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -14,6 +14,7 @@ #![feature(strict_provenance)] #![feature(exposed_provenance)] #![feature(pointer_is_aligned_to)] +#![feature(unqualified_local_imports)] // Configure clippy and other lints #![allow( clippy::collapsible_else_if, @@ -42,13 +43,12 @@ )] #![warn( rust_2018_idioms, + unqualified_local_imports, clippy::cast_possible_wrap, // unsigned -> signed clippy::cast_sign_loss, // signed -> unsigned clippy::cast_lossless, clippy::cast_possible_truncation, )] -#![cfg_attr(not(bootstrap), feature(unqualified_local_imports))] -#![cfg_attr(not(bootstrap), warn(unqualified_local_imports))] // Needed for rustdoc from bootstrap (with `-Znormalize-docs`). #![recursion_limit = "256"] diff --git a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs index 08d86606a6b..a26d00b77ac 100644 --- a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs +++ b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs @@ -1,8 +1,5 @@ //@ compile-flags: -Z unstable-options -// #[cfg(bootstrap)]: We can stop ignoring next beta bump; afterward this ALWAYS should run. -//@ ignore-stage1 - #![feature(rustc_private)] #![deny(rustc::usage_of_type_ir_inherent)] diff --git a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr index cc6cb9170c0..3326b1047ac 100644 --- a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr +++ b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr @@ -1,18 +1,18 @@ error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver - --> $DIR/import-of-type-ir-inherent.rs:11:20 + --> $DIR/import-of-type-ir-inherent.rs:8:20 | LL | use rustc_type_ir::inherent::*; | ^^^^^^^^ | = note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler note: the lint level is defined here - --> $DIR/import-of-type-ir-inherent.rs:7:9 + --> $DIR/import-of-type-ir-inherent.rs:4:9 | LL | #![deny(rustc::usage_of_type_ir_inherent)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver - --> $DIR/import-of-type-ir-inherent.rs:13:20 + --> $DIR/import-of-type-ir-inherent.rs:10:20 | LL | use rustc_type_ir::inherent; | ^^^^^^^^ @@ -20,7 +20,7 @@ LL | use rustc_type_ir::inherent; = note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver - --> $DIR/import-of-type-ir-inherent.rs:15:20 + --> $DIR/import-of-type-ir-inherent.rs:12:20 | LL | use rustc_type_ir::inherent::Predicate; | ^^^^^^^^ diff --git a/tests/ui-fulldeps/internal-lints/query_completeness.rs b/tests/ui-fulldeps/internal-lints/query_completeness.rs index 50b0fb4c3fc..791f4599273 100644 --- a/tests/ui-fulldeps/internal-lints/query_completeness.rs +++ b/tests/ui-fulldeps/internal-lints/query_completeness.rs @@ -1,6 +1,4 @@ //@ compile-flags: -Z unstable-options -// #[cfg(bootstrap)]: We can stop ignoring next beta bump; afterward this ALWAYS should run. -//@ ignore-stage1 (requires matching sysroot built with in-tree compiler) #![feature(rustc_private)] #![deny(rustc::untracked_query_information)] diff --git a/tests/ui-fulldeps/internal-lints/query_completeness.stderr b/tests/ui-fulldeps/internal-lints/query_completeness.stderr index 35bb867f40e..e17c2a891cf 100644 --- a/tests/ui-fulldeps/internal-lints/query_completeness.stderr +++ b/tests/ui-fulldeps/internal-lints/query_completeness.stderr @@ -1,12 +1,12 @@ error: `is_stolen` accesses information that is not tracked by the query system - --> $DIR/query_completeness.rs:12:15 + --> $DIR/query_completeness.rs:10:15 | LL | let _ = x.is_stolen(); | ^^^^^^^^^ | = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale note: the lint level is defined here - --> $DIR/query_completeness.rs:5:9 + --> $DIR/query_completeness.rs:3:9 | LL | #![deny(rustc::untracked_query_information)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- cgit 1.4.1-3-g733a5