Auto merge of #131422 - GnomedDev:smallvec-predicate-obligations, r=compiler-errors

Use `ThinVec` for PredicateObligation storage

~~I noticed while profiling clippy on a project that a large amount of time is being spent allocating `Vec`s for `PredicateObligation`, and the `Vec`s are often quite small. This is an attempt to optimise this by using SmallVec to avoid heap allocations for these common small Vecs.~~

This PR turns all the `Vec<PredicateObligation>` into a single type alias while avoiding referring to `Vec` around it, then swaps the type over to `ThinVec<PredicateObligation>` and fixes the fallout. This also contains an implementation of `ThinVec::extract_if`, copied from `Vec::extract_if` and currently being upstreamed to https://github.com/Gankra/thin-vec/pull/66.

This leads to a small (0.2-0.7%) performance gain in the latest perf run.
This commit is contained in:
bors
2024-10-16 04:06:14 +00:00
43 changed files with 414 additions and 255 deletions

View File

@@ -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);
}
}
}

View File

@@ -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;
@@ -206,7 +207,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()
}

View File

@@ -6,13 +6,15 @@ 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;
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};
@@ -27,6 +29,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> = ThinVec<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 +165,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 +195,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 +212,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 +221,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 +326,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 +374,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 +403,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 +413,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 +430,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 +459,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 +470,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 +578,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 +732,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 +755,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 +819,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 +836,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))
}

View File

@@ -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

View File

@@ -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![] }

View File

@@ -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.

View File

@@ -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

View File

@@ -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>>,

View File

@@ -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();

View File

@@ -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();

View File

@@ -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

View File

@@ -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()

View File

@@ -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;