diff options
| author | GnomedDev <david2005thomas@gmail.com> | 2024-10-09 01:02:55 +0100 |
|---|---|---|
| committer | GnomedDev <david2005thomas@gmail.com> | 2024-10-12 15:17:08 +0100 |
| commit | 7ec06b0d1d08cbcc6ed2f7e6ae87fe18056f69ef (patch) | |
| tree | 84de21bf35650b6cadd11779c13bdee83e238afb /compiler/rustc_trait_selection/src/traits | |
| parent | 1ac72b94bc5e8536e61232125b99dd052ac74b38 (diff) | |
| download | rust-7ec06b0d1d08cbcc6ed2f7e6ae87fe18056f69ef.tar.gz rust-7ec06b0d1d08cbcc6ed2f7e6ae87fe18056f69ef.zip | |
Swap Vec<PredicateObligation> to type alias
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits')
13 files changed, 164 insertions, 133 deletions
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<Vec<PredicateObligation<'tcx>>> { +) -> Option<PredicateObligations<'tcx>> { 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<PredicateObligation<'tcx>> { + 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<PendingPredicateObligation<'tcx>>; + 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<PredicateObligation<'tcx>> { - 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<PredicateObligation<'tcx>>, + removed_predicates: PredicateObligations<'tcx>, } impl<'tcx> ObligationProcessor for DrainProcessor<'_, 'tcx> { @@ -190,7 +194,7 @@ where ) -> ProcessResult<PendingPredicateObligation<'tcx>, !> { 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<PredicateObligation<'tcx>> { + 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<PredicateObligation<'_>>) -> Vec<PendingPredicateObligation<'_>> { +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> { // `<lhs_ty as Add<rhs_ty>>::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<PredicateObligation<'tcx>>), + Cycle(PredicateObligations<'tcx>), Select(SelectionError<'tcx>), Project(MismatchedProjectionTypes<'tcx>), Subtype(ExpectedFound<Ty<'tcx>>, 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<T: TypeFoldable<TyCtxt<'tcx>>>(&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<TyCtxt<'tcx>>, { - 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<PredicateObligation<'tcx>>, + obligations: &mut PredicateObligations<'tcx>, ) -> T where T: TypeFoldable<TyCtxt<'tcx>>, { 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<PredicateObligation<'tcx>>, + obligations: &'a mut PredicateObligations<'tcx>, depth: usize, universes: Vec<Option<ty::UniverseIndex>>, } @@ -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<PredicateObligation<'tcx>>, + 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<Option<Vec<PredicateObligation<'tcx>>>, InProgress>, +/// Result<Option<PredicateObligations<'tcx>>, 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<PredicateObligation<'tcx>>), + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + obligations: &mut PredicateObligations<'tcx>, ) -> Result<Option<Term<'tcx>>, 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>) -> 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + 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<PredicateObligation<'tcx>>, + obligations: PredicateObligations<'tcx>, cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>, anon_depth: usize, universes: Vec<Option<ty::UniverseIndex>>, 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<TyCtxt<'tcx>> + 't ( Self::QueryResponse, Option<Canonical<'tcx, ParamEnvAnd<'tcx, Self>>>, - Vec<PredicateObligation<'tcx>>, + 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<PredicateObligation<'tcx>> { + ) -> 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<PredicateObligation<'tcx>> { + ) -> 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<PredicateObligation<'tcx>> { + ) -> 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<rustc_transmute::layout::rustc::Ref<'tcx>>, assume: Assume, - ) -> Vec<PredicateObligation<'tcx>> { + ) -> 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<Ty<'tcx>>>, - ) -> Vec<PredicateObligation<'tcx>> { + ) -> 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<PredicateObligation<'_>> = 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<PredicateObligation<'tcx>> { + ) -> 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`, // 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<DefId>, - ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + ) -> Result<PredicateObligations<'tcx>, 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<Ty<'tcx>>>, - ) -> Vec<PredicateObligation<'tcx>> { + ) -> 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<ty::PolyExistentialPredicate<'tcx>>, a_region: ty::Region<'tcx>, b_region: ty::Region<'tcx>, - ) -> SelectionResult<'tcx, Vec<PredicateObligation<'tcx>>> { + ) -> 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<Vec<PredicateObligation<'tcx>>, ()> { + ) -> Result<PredicateObligations<'tcx>, ()> { 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<Vec<PredicateObligation<'tcx>>, ()> { + ) -> Result<PredicateObligations<'tcx>, ()> { 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<PredicateObligation<'tcx>> { + ) -> 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<Vec<traits::PredicateObligation<'tcx>>> { +) -> Option<PredicateObligations<'tcx>> { // 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<Vec<traits::PredicateObligation<'tcx>>> { +) -> Option<PredicateObligations<'tcx>> { 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<traits::PredicateObligation<'tcx>> { +) -> 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<traits::PredicateObligation<'tcx>> { +) -> 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<traits::PredicateObligation<'tcx>>, + 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<traits::PredicateObligation<'tcx>> { + 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<traits::PredicateObligation<'tcx>> { + ) -> PredicateObligations<'tcx> { let predicates = self.tcx().predicates_of(def_id); let mut origins = vec![def_id; predicates.predicates.len()]; let mut head = predicates; |
