1 //! Candidate selection. See the [rustc dev guide] for more information on how this works.
3 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html#selection
5 // FIXME: The `map` field in ProvisionalEvaluationCache should be changed to
6 // a `FxIndexMap` to avoid query instability, but right now it causes a perf regression. This would be
7 // fixed or at least lightened by the addition of the `drain_filter` method to `FxIndexMap`
8 // Relevant: https://github.com/rust-lang/rust/pull/103723 and https://github.com/bluss/indexmap/issues/242
9 #![allow(rustc::potential_query_instability)]
11 use self::EvaluationResult::*;
12 use self::SelectionCandidate::*;
14 use super::coherence::{self, Conflict};
15 use super::const_evaluatable;
17 use super::project::normalize_with_depth_to;
18 use super::project::ProjectionTyObligation;
20 use super::util::{closure_trait_ref_and_return_type, predicate_for_trait_def};
23 ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, Normalized, Obligation,
24 ObligationCause, ObligationCauseCode, Overflow, PredicateObligation, Selection, SelectionError,
25 SelectionResult, TraitObligation, TraitQueryMode,
28 use crate::infer::{InferCtxt, InferOk, TypeFreshener};
29 use crate::traits::error_reporting::TypeErrCtxtExt;
30 use crate::traits::project::ProjectAndUnifyResult;
31 use crate::traits::project::ProjectionCacheKeyExt;
32 use crate::traits::ProjectionCacheKey;
33 use crate::traits::Unimplemented;
34 use rustc_data_structures::fx::FxHashMap;
35 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
36 use rustc_data_structures::stack::ensure_sufficient_stack;
37 use rustc_errors::Diagnostic;
39 use rustc_hir::def_id::DefId;
40 use rustc_infer::infer::LateBoundRegionConversionTime;
41 use rustc_infer::traits::TraitEngine;
42 use rustc_infer::traits::TraitEngineExt;
43 use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
44 use rustc_middle::mir::interpret::ErrorHandled;
45 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
46 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
47 use rustc_middle::ty::fold::BottomUpFolder;
48 use rustc_middle::ty::relate::TypeRelation;
49 use rustc_middle::ty::SubstsRef;
50 use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
51 use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitable};
52 use rustc_session::config::TraitSolver;
53 use rustc_span::symbol::sym;
55 use std::cell::{Cell, RefCell};
57 use std::fmt::{self, Display};
60 pub use rustc_middle::traits::select::*;
61 use rustc_middle::ty::print::with_no_trimmed_paths;
63 mod candidate_assembly;
66 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
67 pub enum IntercrateAmbiguityCause {
68 DownstreamCrate { trait_desc: String, self_desc: Option<String> },
69 UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> },
70 ReservationImpl { message: String },
73 impl IntercrateAmbiguityCause {
74 /// Emits notes when the overlap is caused by complex intercrate ambiguities.
75 /// See #23980 for details.
76 pub fn add_intercrate_ambiguity_hint(&self, err: &mut Diagnostic) {
77 err.note(&self.intercrate_ambiguity_hint());
80 pub fn intercrate_ambiguity_hint(&self) -> String {
82 IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } => {
83 let self_desc = if let Some(ty) = self_desc {
84 format!(" for type `{}`", ty)
88 format!("downstream crates may implement trait `{}`{}", trait_desc, self_desc)
90 IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc } => {
91 let self_desc = if let Some(ty) = self_desc {
92 format!(" for type `{}`", ty)
97 "upstream crates may add a new impl of trait `{}`{} \
102 IntercrateAmbiguityCause::ReservationImpl { message } => message.clone(),
107 pub struct SelectionContext<'cx, 'tcx> {
108 pub infcx: &'cx InferCtxt<'tcx>,
110 /// Freshener used specifically for entries on the obligation
111 /// stack. This ensures that all entries on the stack at one time
112 /// will have the same set of placeholder entries, which is
113 /// important for checking for trait bounds that recursively
114 /// require themselves.
115 freshener: TypeFreshener<'cx, 'tcx>,
117 /// If `intercrate` is set, we remember predicates which were
118 /// considered ambiguous because of impls potentially added in other crates.
119 /// This is used in coherence to give improved diagnostics.
120 /// We don't do his until we detect a coherence error because it can
121 /// lead to false overflow results (#47139) and because always
122 /// computing it may negatively impact performance.
123 intercrate_ambiguity_causes: Option<FxIndexSet<IntercrateAmbiguityCause>>,
125 /// The mode that trait queries run in, which informs our error handling
126 /// policy. In essence, canonicalized queries need their errors propagated
127 /// rather than immediately reported because we do not have accurate spans.
128 query_mode: TraitQueryMode,
131 // A stack that walks back up the stack frame.
132 struct TraitObligationStack<'prev, 'tcx> {
133 obligation: &'prev TraitObligation<'tcx>,
135 /// The trait predicate from `obligation` but "freshened" with the
136 /// selection-context's freshener. Used to check for recursion.
137 fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
139 /// Starts out equal to `depth` -- if, during evaluation, we
140 /// encounter a cycle, then we will set this flag to the minimum
141 /// depth of that cycle for all participants in the cycle. These
142 /// participants will then forego caching their results. This is
143 /// not the most efficient solution, but it addresses #60010. The
144 /// problem we are trying to prevent:
146 /// - If you have `A: AutoTrait` requires `B: AutoTrait` and `C: NonAutoTrait`
147 /// - `B: AutoTrait` requires `A: AutoTrait` (coinductive cycle, ok)
148 /// - `C: NonAutoTrait` requires `A: AutoTrait` (non-coinductive cycle, not ok)
150 /// you don't want to cache that `B: AutoTrait` or `A: AutoTrait`
151 /// is `EvaluatedToOk`; this is because they were only considered
152 /// ok on the premise that if `A: AutoTrait` held, but we indeed
153 /// encountered a problem (later on) with `A: AutoTrait. So we
154 /// currently set a flag on the stack node for `B: AutoTrait` (as
155 /// well as the second instance of `A: AutoTrait`) to suppress
158 /// This is a simple, targeted fix. A more-performant fix requires
159 /// deeper changes, but would permit more caching: we could
160 /// basically defer caching until we have fully evaluated the
161 /// tree, and then cache the entire tree at once. In any case, the
162 /// performance impact here shouldn't be so horrible: every time
163 /// this is hit, we do cache at least one trait, so we only
164 /// evaluate each member of a cycle up to N times, where N is the
165 /// length of the cycle. This means the performance impact is
166 /// bounded and we shouldn't have any terrible worst-cases.
167 reached_depth: Cell<usize>,
169 previous: TraitObligationStackList<'prev, 'tcx>,
171 /// The number of parent frames plus one (thus, the topmost frame has depth 1).
174 /// The depth-first number of this node in the search graph -- a
175 /// pre-order index. Basically, a freshly incremented counter.
179 struct SelectionCandidateSet<'tcx> {
180 // A list of candidates that definitely apply to the current
181 // obligation (meaning: types unify).
182 vec: Vec<SelectionCandidate<'tcx>>,
184 // If `true`, then there were candidates that might or might
185 // not have applied, but we couldn't tell. This occurs when some
186 // of the input types are type variables, in which case there are
187 // various "builtin" rules that might or might not trigger.
191 #[derive(PartialEq, Eq, Debug, Clone)]
192 struct EvaluatedCandidate<'tcx> {
193 candidate: SelectionCandidate<'tcx>,
194 evaluation: EvaluationResult,
197 /// When does the builtin impl for `T: Trait` apply?
199 enum BuiltinImplConditions<'tcx> {
200 /// The impl is conditional on `T1, T2, ...: Trait`.
201 Where(ty::Binder<'tcx, Vec<Ty<'tcx>>>),
202 /// There is no built-in impl. There may be some other
203 /// candidate (a where-clause or user-defined impl).
205 /// It is unknown whether there is an impl.
209 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
210 pub fn new(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> {
213 freshener: infcx.freshener_keep_static(),
214 intercrate_ambiguity_causes: None,
215 query_mode: TraitQueryMode::Standard,
219 pub fn with_query_mode(
220 infcx: &'cx InferCtxt<'tcx>,
221 query_mode: TraitQueryMode,
222 ) -> SelectionContext<'cx, 'tcx> {
223 debug!(?query_mode, "with_query_mode");
224 SelectionContext { query_mode, ..SelectionContext::new(infcx) }
227 /// Enables tracking of intercrate ambiguity causes. See
228 /// the documentation of [`Self::intercrate_ambiguity_causes`] for more.
229 pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
230 assert!(self.is_intercrate());
231 assert!(self.intercrate_ambiguity_causes.is_none());
232 self.intercrate_ambiguity_causes = Some(FxIndexSet::default());
233 debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
236 /// Gets the intercrate ambiguity causes collected since tracking
237 /// was enabled and disables tracking at the same time. If
238 /// tracking is not enabled, just returns an empty vector.
239 pub fn take_intercrate_ambiguity_causes(&mut self) -> FxIndexSet<IntercrateAmbiguityCause> {
240 assert!(self.is_intercrate());
241 self.intercrate_ambiguity_causes.take().unwrap_or_default()
244 pub fn tcx(&self) -> TyCtxt<'tcx> {
248 pub fn is_intercrate(&self) -> bool {
249 self.infcx.intercrate
252 ///////////////////////////////////////////////////////////////////////////
255 // The selection phase tries to identify *how* an obligation will
256 // be resolved. For example, it will identify which impl or
257 // parameter bound is to be used. The process can be inconclusive
258 // if the self type in the obligation is not fully inferred. Selection
259 // can result in an error in one of two ways:
261 // 1. If no applicable impl or parameter bound can be found.
262 // 2. If the output type parameters in the obligation do not match
263 // those specified by the impl/bound. For example, if the obligation
264 // is `Vec<Foo>: Iterable<Bar>`, but the impl specifies
265 // `impl<T> Iterable<T> for Vec<T>`, than an error would result.
267 /// Attempts to satisfy the obligation. If successful, this will affect the surrounding
268 /// type environment by performing unification.
269 #[instrument(level = "debug", skip(self), ret)]
272 obligation: &TraitObligation<'tcx>,
273 ) -> SelectionResult<'tcx, Selection<'tcx>> {
274 let candidate = match self.select_from_obligation(obligation) {
275 Err(SelectionError::Overflow(OverflowError::Canonical)) => {
276 // In standard mode, overflow must have been caught and reported
278 assert!(self.query_mode == TraitQueryMode::Canonical);
279 return Err(SelectionError::Overflow(OverflowError::Canonical));
287 Ok(Some(candidate)) => candidate,
290 match self.confirm_candidate(obligation, candidate) {
291 Err(SelectionError::Overflow(OverflowError::Canonical)) => {
292 assert!(self.query_mode == TraitQueryMode::Canonical);
293 Err(SelectionError::Overflow(OverflowError::Canonical))
296 Ok(candidate) => Ok(Some(candidate)),
300 pub(crate) fn select_from_obligation(
302 obligation: &TraitObligation<'tcx>,
303 ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
304 debug_assert!(!obligation.predicate.has_escaping_bound_vars());
306 let pec = &ProvisionalEvaluationCache::default();
307 let stack = self.push_stack(TraitObligationStackList::empty(pec), obligation);
309 self.candidate_from_obligation(&stack)
312 #[instrument(level = "debug", skip(self), ret)]
313 fn candidate_from_obligation<'o>(
315 stack: &TraitObligationStack<'o, 'tcx>,
316 ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
317 // Watch out for overflow. This intentionally bypasses (and does
318 // not update) the cache.
319 self.check_recursion_limit(&stack.obligation, &stack.obligation)?;
321 // Check the cache. Note that we freshen the trait-ref
322 // separately rather than using `stack.fresh_trait_ref` --
323 // this is because we want the unbound variables to be
324 // replaced with fresh types starting from index 0.
325 let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate);
326 debug!(?cache_fresh_trait_pred);
327 debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars());
330 self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred)
336 // If no match, compute result and insert into cache.
338 // FIXME(nikomatsakis) -- this cache is not taking into
339 // account cycles that may have occurred in forming the
340 // candidate. I don't know of any specific problems that
341 // result but it seems awfully suspicious.
342 let (candidate, dep_node) =
343 self.in_task(|this| this.candidate_from_obligation_no_cache(stack));
345 debug!("CACHE MISS");
346 self.insert_candidate_cache(
347 stack.obligation.param_env,
348 cache_fresh_trait_pred,
355 fn candidate_from_obligation_no_cache<'o>(
357 stack: &TraitObligationStack<'o, 'tcx>,
358 ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
359 if let Err(conflict) = self.is_knowable(stack) {
360 debug!("coherence stage: not knowable");
361 if self.intercrate_ambiguity_causes.is_some() {
362 debug!("evaluate_stack: intercrate_ambiguity_causes is some");
363 // Heuristics: show the diagnostics when there are no candidates in crate.
364 if let Ok(candidate_set) = self.assemble_candidates(stack) {
365 let mut no_candidates_apply = true;
367 for c in candidate_set.vec.iter() {
368 if self.evaluate_candidate(stack, &c)?.may_apply() {
369 no_candidates_apply = false;
374 if !candidate_set.ambiguous && no_candidates_apply {
375 let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
376 if !trait_ref.references_error() {
377 let self_ty = trait_ref.self_ty();
378 let (trait_desc, self_desc) = with_no_trimmed_paths!({
379 let trait_desc = trait_ref.print_only_trait_path().to_string();
380 let self_desc = if self_ty.has_concrete_skeleton() {
381 Some(self_ty.to_string())
385 (trait_desc, self_desc)
387 let cause = if let Conflict::Upstream = conflict {
388 IntercrateAmbiguityCause::UpstreamCrateUpdate {
393 IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
395 debug!(?cause, "evaluate_stack: pushing cause");
396 self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause);
404 let candidate_set = self.assemble_candidates(stack)?;
406 if candidate_set.ambiguous {
407 debug!("candidate set contains ambig");
411 let candidates = candidate_set.vec;
413 debug!(?stack, ?candidates, "assembled {} candidates", candidates.len());
415 // At this point, we know that each of the entries in the
416 // candidate set is *individually* applicable. Now we have to
417 // figure out if they contain mutual incompatibilities. This
418 // frequently arises if we have an unconstrained input type --
419 // for example, we are looking for `$0: Eq` where `$0` is some
420 // unconstrained type variable. In that case, we'll get a
421 // candidate which assumes $0 == int, one that assumes `$0 ==
422 // usize`, etc. This spells an ambiguity.
424 let mut candidates = self.filter_impls(candidates, stack.obligation);
426 // If there is more than one candidate, first winnow them down
427 // by considering extra conditions (nested obligations and so
428 // forth). We don't winnow if there is exactly one
429 // candidate. This is a relatively minor distinction but it
430 // can lead to better inference and error-reporting. An
431 // example would be if there was an impl:
433 // impl<T:Clone> Vec<T> { fn push_clone(...) { ... } }
435 // and we were to see some code `foo.push_clone()` where `boo`
436 // is a `Vec<Bar>` and `Bar` does not implement `Clone`. If
437 // we were to winnow, we'd wind up with zero candidates.
438 // Instead, we select the right impl now but report "`Bar` does
439 // not implement `Clone`".
440 if candidates.len() == 1 {
441 return self.filter_reservation_impls(candidates.pop().unwrap(), stack.obligation);
444 // Winnow, but record the exact outcome of evaluation, which
445 // is needed for specialization. Propagate overflow if it occurs.
446 let mut candidates = candidates
448 .map(|c| match self.evaluate_candidate(stack, &c) {
449 Ok(eval) if eval.may_apply() => {
450 Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
453 Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)),
454 Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
455 Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))),
457 .flat_map(Result::transpose)
458 .collect::<Result<Vec<_>, _>>()?;
460 debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len());
462 let needs_infer = stack.obligation.predicate.has_non_region_infer();
464 // If there are STILL multiple candidates, we can further
465 // reduce the list by dropping duplicates -- including
466 // resolving specializations.
467 if candidates.len() > 1 {
469 while i < candidates.len() {
470 let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| {
471 self.candidate_should_be_dropped_in_favor_of(
478 debug!(candidate = ?candidates[i], "Dropping candidate #{}/{}", i, candidates.len());
479 candidates.swap_remove(i);
481 debug!(candidate = ?candidates[i], "Retaining candidate #{}/{}", i, candidates.len());
484 // If there are *STILL* multiple candidates, give up
485 // and report ambiguity.
487 debug!("multiple matches, ambig");
494 // If there are *NO* candidates, then there are no impls --
495 // that we know of, anyway. Note that in the case where there
496 // are unbound type variables within the obligation, it might
497 // be the case that you could still satisfy the obligation
498 // from another crate by instantiating the type variables with
499 // a type from another crate that does have an impl. This case
500 // is checked for in `evaluate_stack` (and hence users
501 // who might care about this case, like coherence, should use
503 if candidates.is_empty() {
504 // If there's an error type, 'downgrade' our result from
505 // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid
506 // emitting additional spurious errors, since we're guaranteed
507 // to have emitted at least one.
508 if stack.obligation.predicate.references_error() {
509 debug!(?stack.obligation.predicate, "found error type in predicate, treating as ambiguous");
512 return Err(Unimplemented);
515 // Just one candidate left.
516 self.filter_reservation_impls(candidates.pop().unwrap().candidate, stack.obligation)
519 ///////////////////////////////////////////////////////////////////////////
522 // Tests whether an obligation can be selected or whether an impl
523 // can be applied to particular types. It skips the "confirmation"
524 // step and hence completely ignores output type parameters.
526 // The result is "true" if the obligation *may* hold and "false" if
527 // we can be sure it does not.
529 /// Evaluates whether the obligation `obligation` can be satisfied (by any means).
530 pub fn predicate_may_hold_fatal(&mut self, obligation: &PredicateObligation<'tcx>) -> bool {
531 debug!(?obligation, "predicate_may_hold_fatal");
533 // This fatal query is a stopgap that should only be used in standard mode,
534 // where we do not expect overflow to be propagated.
535 assert!(self.query_mode == TraitQueryMode::Standard);
537 self.evaluate_root_obligation(obligation)
538 .expect("Overflow should be caught earlier in standard query mode")
542 /// Evaluates whether the obligation `obligation` can be satisfied
543 /// and returns an `EvaluationResult`. This is meant for the
545 pub fn evaluate_root_obligation(
547 obligation: &PredicateObligation<'tcx>,
548 ) -> Result<EvaluationResult, OverflowError> {
549 self.evaluation_probe(|this| {
550 if this.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Next {
551 this.evaluate_predicate_recursively(
552 TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
556 this.evaluate_predicates_recursively_in_new_solver([obligation.clone()])
563 op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>,
564 ) -> Result<EvaluationResult, OverflowError> {
565 self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
566 let result = op(self)?;
568 match self.infcx.leak_check(true, snapshot) {
570 Err(_) => return Ok(EvaluatedToErr),
573 if self.infcx.opaque_types_added_in_snapshot(snapshot) {
574 return Ok(result.max(EvaluatedToOkModuloOpaqueTypes));
577 match self.infcx.region_constraints_added_in_snapshot(snapshot) {
579 Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)),
584 /// Evaluates the predicates in `predicates` recursively. Note that
585 /// this applies projections in the predicates, and therefore
586 /// is run within an inference probe.
587 #[instrument(skip(self, stack), level = "debug")]
588 fn evaluate_predicates_recursively<'o, I>(
590 stack: TraitObligationStackList<'o, 'tcx>,
592 ) -> Result<EvaluationResult, OverflowError>
594 I: IntoIterator<Item = PredicateObligation<'tcx>> + std::fmt::Debug,
596 if self.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Next {
597 let mut result = EvaluatedToOk;
598 for obligation in predicates {
599 let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?;
600 if let EvaluatedToErr = eval {
601 // fast-path - EvaluatedToErr is the top of the lattice,
602 // so we don't need to look on the other predicates.
603 return Ok(EvaluatedToErr);
605 result = cmp::max(result, eval);
610 self.evaluate_predicates_recursively_in_new_solver(predicates)
614 /// Evaluates the predicates using the new solver when `-Ztrait-solver=next` is enabled
615 fn evaluate_predicates_recursively_in_new_solver(
617 predicates: impl IntoIterator<Item = PredicateObligation<'tcx>>,
618 ) -> Result<EvaluationResult, OverflowError> {
619 let mut fulfill_cx = crate::solve::FulfillmentCtxt::new();
620 fulfill_cx.register_predicate_obligations(self.infcx, predicates);
622 if !fulfill_cx.select_where_possible(self.infcx).is_empty() {
623 return Ok(EvaluatedToErr);
625 if !fulfill_cx.select_all_or_error(self.infcx).is_empty() {
626 return Ok(EvaluatedToAmbig);
628 // Regions and opaques are handled in the `evaluation_probe` by looking at the snapshot
634 skip(self, previous_stack),
635 fields(previous_stack = ?previous_stack.head())
638 fn evaluate_predicate_recursively<'o>(
640 previous_stack: TraitObligationStackList<'o, 'tcx>,
641 obligation: PredicateObligation<'tcx>,
642 ) -> Result<EvaluationResult, OverflowError> {
643 // `previous_stack` stores a `TraitObligation`, while `obligation` is
644 // a `PredicateObligation`. These are distinct types, so we can't
645 // use any `Option` combinator method that would force them to be
647 match previous_stack.head() {
648 Some(h) => self.check_recursion_limit(&obligation, h.obligation)?,
649 None => self.check_recursion_limit(&obligation, &obligation)?,
652 ensure_sufficient_stack(|| {
653 let bound_predicate = obligation.predicate.kind();
654 match bound_predicate.skip_binder() {
655 ty::PredicateKind::Clause(ty::Clause::Trait(t)) => {
656 let t = bound_predicate.rebind(t);
657 debug_assert!(!t.has_escaping_bound_vars());
658 let obligation = obligation.with(self.tcx(), t);
659 self.evaluate_trait_predicate_recursively(previous_stack, obligation)
662 ty::PredicateKind::Subtype(p) => {
663 let p = bound_predicate.rebind(p);
664 // Does this code ever run?
665 match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
666 Ok(Ok(InferOk { mut obligations, .. })) => {
667 self.add_depth(obligations.iter_mut(), obligation.recursion_depth);
668 self.evaluate_predicates_recursively(
670 obligations.into_iter(),
673 Ok(Err(_)) => Ok(EvaluatedToErr),
674 Err(..) => Ok(EvaluatedToAmbig),
678 ty::PredicateKind::Coerce(p) => {
679 let p = bound_predicate.rebind(p);
680 // Does this code ever run?
681 match self.infcx.coerce_predicate(&obligation.cause, obligation.param_env, p) {
682 Ok(Ok(InferOk { mut obligations, .. })) => {
683 self.add_depth(obligations.iter_mut(), obligation.recursion_depth);
684 self.evaluate_predicates_recursively(
686 obligations.into_iter(),
689 Ok(Err(_)) => Ok(EvaluatedToErr),
690 Err(..) => Ok(EvaluatedToAmbig),
694 ty::PredicateKind::WellFormed(arg) => {
695 // So, there is a bit going on here. First, `WellFormed` predicates
696 // are coinductive, like trait predicates with auto traits.
697 // This means that we need to detect if we have recursively
698 // evaluated `WellFormed(X)`. Otherwise, we would run into
699 // a "natural" overflow error.
701 // Now, the next question is whether we need to do anything
702 // special with caching. Considering the following tree:
707 // In this case, the innermost `WF(Foo<T>)` should return
708 // `EvaluatedToOk`, since it's coinductive. Then if
709 // `Bar<T>: Send` is resolved to `EvaluatedToOk`, it can be
710 // inserted into a cache (because without thinking about `WF`
711 // goals, it isn't in a cycle). If `Foo<T>: Trait` later doesn't
712 // hold, then `Bar<T>: Send` shouldn't hold. Therefore, we
713 // *do* need to keep track of coinductive cycles.
715 let cache = previous_stack.cache;
716 let dfn = cache.next_dfn();
718 for stack_arg in previous_stack.cache.wf_args.borrow().iter().rev() {
719 if stack_arg.0 != arg {
722 debug!("WellFormed({:?}) on stack", arg);
723 if let Some(stack) = previous_stack.head {
724 // Okay, let's imagine we have two different stacks:
725 // `T: NonAutoTrait -> WF(T) -> T: NonAutoTrait`
726 // `WF(T) -> T: NonAutoTrait -> WF(T)`
727 // Because of this, we need to check that all
728 // predicates between the WF goals are coinductive.
729 // Otherwise, we can say that `T: NonAutoTrait` is
731 // Let's imagine we have a predicate stack like
732 // `Foo: Bar -> WF(T) -> T: NonAutoTrait -> T: Auto
734 // and the current predicate is `WF(T)`. `wf_args`
735 // would contain `(T, 1)`. We want to check all
736 // trait predicates greater than `1`. The previous
737 // stack would be `T: Auto`.
738 let cycle = stack.iter().take_while(|s| s.depth > stack_arg.1);
739 let tcx = self.tcx();
741 cycle.map(|stack| stack.obligation.predicate.to_predicate(tcx));
742 if self.coinductive_match(cycle) {
743 stack.update_reached_depth(stack_arg.1);
744 return Ok(EvaluatedToOk);
746 return Ok(EvaluatedToRecur);
749 return Ok(EvaluatedToOk);
752 match wf::obligations(
754 obligation.param_env,
755 obligation.cause.body_id,
756 obligation.recursion_depth + 1,
758 obligation.cause.span,
760 Some(mut obligations) => {
761 self.add_depth(obligations.iter_mut(), obligation.recursion_depth);
763 cache.wf_args.borrow_mut().push((arg, previous_stack.depth()));
765 self.evaluate_predicates_recursively(previous_stack, obligations);
766 cache.wf_args.borrow_mut().pop();
768 let result = result?;
770 if !result.must_apply_modulo_regions() {
771 cache.on_failure(dfn);
774 cache.on_completion(dfn);
778 None => Ok(EvaluatedToAmbig),
782 ty::PredicateKind::Clause(ty::Clause::TypeOutlives(pred)) => {
783 // A global type with no late-bound regions can only
784 // contain the "'static" lifetime (any other lifetime
785 // would either be late-bound or local), so it is guaranteed
786 // to outlive any other lifetime
787 if pred.0.is_global() && !pred.0.has_late_bound_vars() {
790 Ok(EvaluatedToOkModuloRegions)
794 ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) => {
795 // We do not consider region relationships when evaluating trait matches.
796 Ok(EvaluatedToOkModuloRegions)
799 ty::PredicateKind::ObjectSafe(trait_def_id) => {
800 if self.tcx().is_object_safe(trait_def_id) {
807 ty::PredicateKind::Clause(ty::Clause::Projection(data)) => {
808 let data = bound_predicate.rebind(data);
809 let project_obligation = obligation.with(self.tcx(), data);
810 match project::poly_project_and_unify_type(self, &project_obligation) {
811 ProjectAndUnifyResult::Holds(mut subobligations) => {
813 // If we've previously marked this projection as 'complete', then
814 // use the final cached result (either `EvaluatedToOk` or
815 // `EvaluatedToOkModuloRegions`), and skip re-evaluating the
818 ProjectionCacheKey::from_poly_projection_predicate(self, data)
820 if let Some(cached_res) = self
827 break 'compute_res Ok(cached_res);
832 subobligations.iter_mut(),
833 obligation.recursion_depth,
835 let res = self.evaluate_predicates_recursively(
839 if let Ok(eval_rslt) = res
840 && (eval_rslt == EvaluatedToOk || eval_rslt == EvaluatedToOkModuloRegions)
842 ProjectionCacheKey::from_poly_projection_predicate(
846 // If the result is something that we can cache, then mark this
847 // entry as 'complete'. This will allow us to skip evaluating the
848 // subobligations at all the next time we evaluate the projection
854 .complete(key, eval_rslt);
859 ProjectAndUnifyResult::FailedNormalization => Ok(EvaluatedToAmbig),
860 ProjectAndUnifyResult::Recursive => Ok(EvaluatedToRecur),
861 ProjectAndUnifyResult::MismatchedProjectionTypes(_) => Ok(EvaluatedToErr),
865 ty::PredicateKind::ClosureKind(_, closure_substs, kind) => {
866 match self.infcx.closure_kind(closure_substs) {
867 Some(closure_kind) => {
868 if closure_kind.extends(kind) {
874 None => Ok(EvaluatedToAmbig),
878 ty::PredicateKind::ConstEvaluatable(uv) => {
879 match const_evaluatable::is_const_evaluatable(
882 obligation.param_env,
883 obligation.cause.span,
885 Ok(()) => Ok(EvaluatedToOk),
886 Err(NotConstEvaluatable::MentionsInfer) => Ok(EvaluatedToAmbig),
887 Err(NotConstEvaluatable::MentionsParam) => Ok(EvaluatedToErr),
888 Err(_) => Ok(EvaluatedToErr),
892 ty::PredicateKind::ConstEquate(c1, c2) => {
893 let tcx = self.tcx();
895 tcx.features().generic_const_exprs,
896 "`ConstEquate` without a feature gate: {c1:?} {c2:?}",
900 let c1 = tcx.expand_abstract_consts(c1);
901 let c2 = tcx.expand_abstract_consts(c2);
903 "evalaute_predicate_recursively: equating consts:\nc1= {:?}\nc2= {:?}",
907 use rustc_hir::def::DefKind;
908 use ty::ConstKind::Unevaluated;
909 match (c1.kind(), c2.kind()) {
910 (Unevaluated(a), Unevaluated(b))
911 if a.def.did == b.def.did
912 && tcx.def_kind(a.def.did) == DefKind::AssocConst =>
914 if let Ok(new_obligations) = self
916 .at(&obligation.cause, obligation.param_env)
918 .eq(a.substs, b.substs)
920 let mut obligations = new_obligations.obligations;
922 obligations.iter_mut(),
923 obligation.recursion_depth,
925 return self.evaluate_predicates_recursively(
927 obligations.into_iter(),
931 (_, Unevaluated(_)) | (Unevaluated(_), _) => (),
933 if let Ok(new_obligations) = self
935 .at(&obligation.cause, obligation.param_env)
938 let mut obligations = new_obligations.obligations;
940 obligations.iter_mut(),
941 obligation.recursion_depth,
943 return self.evaluate_predicates_recursively(
945 obligations.into_iter(),
952 let evaluate = |c: ty::Const<'tcx>| {
953 if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
954 match self.infcx.try_const_eval_resolve(
955 obligation.param_env,
958 Some(obligation.cause.span),
968 match (evaluate(c1), evaluate(c2)) {
969 (Ok(c1), Ok(c2)) => {
970 match self.infcx.at(&obligation.cause, obligation.param_env).eq(c1, c2)
972 Ok(inf_ok) => self.evaluate_predicates_recursively(
974 inf_ok.into_obligations(),
976 Err(_) => Ok(EvaluatedToErr),
979 (Err(ErrorHandled::Reported(_)), _)
980 | (_, Err(ErrorHandled::Reported(_))) => Ok(EvaluatedToErr),
981 (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => {
982 if c1.has_non_region_infer() || c2.has_non_region_infer() {
985 // Two different constants using generic parameters ~> error.
991 ty::PredicateKind::TypeWellFormedFromEnv(..) => {
992 bug!("TypeWellFormedFromEnv is only used for chalk")
994 ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
999 #[instrument(skip(self, previous_stack), level = "debug", ret)]
1000 fn evaluate_trait_predicate_recursively<'o>(
1002 previous_stack: TraitObligationStackList<'o, 'tcx>,
1003 mut obligation: TraitObligation<'tcx>,
1004 ) -> Result<EvaluationResult, OverflowError> {
1005 if !self.is_intercrate()
1006 && obligation.is_global()
1007 && obligation.param_env.caller_bounds().iter().all(|bound| bound.needs_subst())
1009 // If a param env has no global bounds, global obligations do not
1010 // depend on its particular value in order to work, so we can clear
1011 // out the param env and get better caching.
1012 debug!("in global");
1013 obligation.param_env = obligation.param_env.without_caller_bounds();
1016 let stack = self.push_stack(previous_stack, &obligation);
1017 let mut fresh_trait_pred = stack.fresh_trait_pred;
1018 let mut param_env = obligation.param_env;
1020 fresh_trait_pred = fresh_trait_pred.map_bound(|mut pred| {
1021 pred.remap_constness(&mut param_env);
1025 debug!(?fresh_trait_pred);
1027 // If a trait predicate is in the (local or global) evaluation cache,
1028 // then we know it holds without cycles.
1029 if let Some(result) = self.check_evaluation_cache(param_env, fresh_trait_pred) {
1030 debug!("CACHE HIT");
1034 if let Some(result) = stack.cache().get_provisional(fresh_trait_pred) {
1035 debug!("PROVISIONAL CACHE HIT");
1036 stack.update_reached_depth(result.reached_depth);
1037 return Ok(result.result);
1040 // Check if this is a match for something already on the
1041 // stack. If so, we don't want to insert the result into the
1042 // main cache (it is cycle dependent) nor the provisional
1043 // cache (which is meant for things that have completed but
1044 // for a "backedge" -- this result *is* the backedge).
1045 if let Some(cycle_result) = self.check_evaluation_cycle(&stack) {
1046 return Ok(cycle_result);
1049 let (result, dep_node) = self.in_task(|this| this.evaluate_stack(&stack));
1050 let result = result?;
1052 if !result.must_apply_modulo_regions() {
1053 stack.cache().on_failure(stack.dfn);
1056 let reached_depth = stack.reached_depth.get();
1057 if reached_depth >= stack.depth {
1058 debug!("CACHE MISS");
1059 self.insert_evaluation_cache(param_env, fresh_trait_pred, dep_node, result);
1060 stack.cache().on_completion(stack.dfn);
1062 debug!("PROVISIONAL");
1064 "caching provisionally because {:?} \
1065 is a cycle participant (at depth {}, reached depth {})",
1066 fresh_trait_pred, stack.depth, reached_depth,
1069 stack.cache().insert_provisional(stack.dfn, reached_depth, fresh_trait_pred, result);
1075 /// If there is any previous entry on the stack that precisely
1076 /// matches this obligation, then we can assume that the
1077 /// obligation is satisfied for now (still all other conditions
1078 /// must be met of course). One obvious case this comes up is
1079 /// marker traits like `Send`. Think of a linked list:
1081 /// struct List<T> { data: T, next: Option<Box<List<T>>> }
1083 /// `Box<List<T>>` will be `Send` if `T` is `Send` and
1084 /// `Option<Box<List<T>>>` is `Send`, and in turn
1085 /// `Option<Box<List<T>>>` is `Send` if `Box<List<T>>` is
1088 /// Note that we do this comparison using the `fresh_trait_ref`
1089 /// fields. Because these have all been freshened using
1090 /// `self.freshener`, we can be sure that (a) this will not
1091 /// affect the inferencer state and (b) that if we see two
1092 /// fresh regions with the same index, they refer to the same
1093 /// unbound type variable.
1094 fn check_evaluation_cycle(
1096 stack: &TraitObligationStack<'_, 'tcx>,
1097 ) -> Option<EvaluationResult> {
1098 if let Some(cycle_depth) = stack
1100 .skip(1) // Skip top-most frame.
1102 stack.obligation.param_env == prev.obligation.param_env
1103 && stack.fresh_trait_pred == prev.fresh_trait_pred
1105 .map(|stack| stack.depth)
1107 debug!("evaluate_stack --> recursive at depth {}", cycle_depth);
1109 // If we have a stack like `A B C D E A`, where the top of
1110 // the stack is the final `A`, then this will iterate over
1111 // `A, E, D, C, B` -- i.e., all the participants apart
1112 // from the cycle head. We mark them as participating in a
1113 // cycle. This suppresses caching for those nodes. See
1114 // `in_cycle` field for more details.
1115 stack.update_reached_depth(cycle_depth);
1117 // Subtle: when checking for a coinductive cycle, we do
1118 // not compare using the "freshened trait refs" (which
1119 // have erased regions) but rather the fully explicit
1120 // trait refs. This is important because it's only a cycle
1121 // if the regions match exactly.
1122 let cycle = stack.iter().skip(1).take_while(|s| s.depth >= cycle_depth);
1123 let tcx = self.tcx();
1124 let cycle = cycle.map(|stack| stack.obligation.predicate.to_predicate(tcx));
1125 if self.coinductive_match(cycle) {
1126 debug!("evaluate_stack --> recursive, coinductive");
1129 debug!("evaluate_stack --> recursive, inductive");
1130 Some(EvaluatedToRecur)
1137 fn evaluate_stack<'o>(
1139 stack: &TraitObligationStack<'o, 'tcx>,
1140 ) -> Result<EvaluationResult, OverflowError> {
1141 // In intercrate mode, whenever any of the generics are unbound,
1142 // there can always be an impl. Even if there are no impls in
1143 // this crate, perhaps the type would be unified with
1144 // something from another crate that does provide an impl.
1146 // In intra mode, we must still be conservative. The reason is
1147 // that we want to avoid cycles. Imagine an impl like:
1149 // impl<T:Eq> Eq for Vec<T>
1151 // and a trait reference like `$0 : Eq` where `$0` is an
1152 // unbound variable. When we evaluate this trait-reference, we
1153 // will unify `$0` with `Vec<$1>` (for some fresh variable
1154 // `$1`), on the condition that `$1 : Eq`. We will then wind
1155 // up with many candidates (since that are other `Eq` impls
1156 // that apply) and try to winnow things down. This results in
1157 // a recursive evaluation that `$1 : Eq` -- as you can
1158 // imagine, this is just where we started. To avoid that, we
1159 // check for unbound variables and return an ambiguous (hence possible)
1160 // match if we've seen this trait before.
1162 // This suffices to allow chains like `FnMut` implemented in
1163 // terms of `Fn` etc, but we could probably make this more
1165 let unbound_input_types =
1166 stack.fresh_trait_pred.skip_binder().trait_ref.substs.types().any(|ty| ty.is_fresh());
1168 if unbound_input_types
1169 && stack.iter().skip(1).any(|prev| {
1170 stack.obligation.param_env == prev.obligation.param_env
1171 && self.match_fresh_trait_refs(
1172 stack.fresh_trait_pred,
1173 prev.fresh_trait_pred,
1174 prev.obligation.param_env,
1178 debug!("evaluate_stack --> unbound argument, recursive --> giving up",);
1179 return Ok(EvaluatedToUnknown);
1182 match self.candidate_from_obligation(stack) {
1183 Ok(Some(c)) => self.evaluate_candidate(stack, &c),
1184 Ok(None) => Ok(EvaluatedToAmbig),
1185 Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
1186 Err(ErrorReporting) => Err(OverflowError::ErrorReporting),
1187 Err(..) => Ok(EvaluatedToErr),
1191 /// For defaulted traits, we use a co-inductive strategy to solve, so
1192 /// that recursion is ok. This routine returns `true` if the top of the
1193 /// stack (`cycle[0]`):
1195 /// - is a defaulted trait,
1196 /// - it also appears in the backtrace at some position `X`,
1197 /// - all the predicates at positions `X..` between `X` and the top are
1198 /// also defaulted traits.
1199 pub(crate) fn coinductive_match<I>(&mut self, mut cycle: I) -> bool
1201 I: Iterator<Item = ty::Predicate<'tcx>>,
1203 cycle.all(|predicate| predicate.is_coinductive(self.tcx()))
1206 /// Further evaluates `candidate` to decide whether all type parameters match and whether nested
1207 /// obligations are met. Returns whether `candidate` remains viable after this further
1212 fields(depth = stack.obligation.recursion_depth),
1215 fn evaluate_candidate<'o>(
1217 stack: &TraitObligationStack<'o, 'tcx>,
1218 candidate: &SelectionCandidate<'tcx>,
1219 ) -> Result<EvaluationResult, OverflowError> {
1220 let mut result = self.evaluation_probe(|this| {
1221 let candidate = (*candidate).clone();
1222 match this.confirm_candidate(stack.obligation, candidate) {
1225 this.evaluate_predicates_recursively(
1227 selection.nested_obligations().into_iter(),
1230 Err(..) => Ok(EvaluatedToErr),
1234 // If we erased any lifetimes, then we want to use
1235 // `EvaluatedToOkModuloRegions` instead of `EvaluatedToOk`
1236 // as your final result. The result will be cached using
1237 // the freshened trait predicate as a key, so we need
1238 // our result to be correct by *any* choice of original lifetimes,
1239 // not just the lifetime choice for this particular (non-erased)
1242 if stack.fresh_trait_pred.has_erased_regions() {
1243 result = result.max(EvaluatedToOkModuloRegions);
1249 fn check_evaluation_cache(
1251 param_env: ty::ParamEnv<'tcx>,
1252 trait_pred: ty::PolyTraitPredicate<'tcx>,
1253 ) -> Option<EvaluationResult> {
1254 // Neither the global nor local cache is aware of intercrate
1255 // mode, so don't do any caching. In particular, we might
1256 // re-use the same `InferCtxt` with both an intercrate
1257 // and non-intercrate `SelectionContext`
1258 if self.is_intercrate() {
1262 let tcx = self.tcx();
1263 if self.can_use_global_caches(param_env) {
1264 if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) {
1268 self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx)
1271 fn insert_evaluation_cache(
1273 param_env: ty::ParamEnv<'tcx>,
1274 trait_pred: ty::PolyTraitPredicate<'tcx>,
1275 dep_node: DepNodeIndex,
1276 result: EvaluationResult,
1278 // Avoid caching results that depend on more than just the trait-ref
1279 // - the stack can create recursion.
1280 if result.is_stack_dependent() {
1284 // Neither the global nor local cache is aware of intercrate
1285 // mode, so don't do any caching. In particular, we might
1286 // re-use the same `InferCtxt` with both an intercrate
1287 // and non-intercrate `SelectionContext`
1288 if self.is_intercrate() {
1292 if self.can_use_global_caches(param_env) {
1293 if !trait_pred.needs_infer() {
1294 debug!(?trait_pred, ?result, "insert_evaluation_cache global");
1295 // This may overwrite the cache with the same value
1296 // FIXME: Due to #50507 this overwrites the different values
1297 // This should be changed to use HashMapExt::insert_same
1298 // when that is fixed
1299 self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result);
1304 debug!(?trait_pred, ?result, "insert_evaluation_cache");
1305 self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result);
1308 /// For various reasons, it's possible for a subobligation
1309 /// to have a *lower* recursion_depth than the obligation used to create it.
1310 /// Projection sub-obligations may be returned from the projection cache,
1311 /// which results in obligations with an 'old' `recursion_depth`.
1312 /// Additionally, methods like `InferCtxt.subtype_predicate` produce
1313 /// subobligations without taking in a 'parent' depth, causing the
1314 /// generated subobligations to have a `recursion_depth` of `0`.
1316 /// To ensure that obligation_depth never decreases, we force all subobligations
1317 /// to have at least the depth of the original obligation.
1318 fn add_depth<T: 'cx, I: Iterator<Item = &'cx mut Obligation<'tcx, T>>>(
1323 it.for_each(|o| o.recursion_depth = cmp::max(min_depth, o.recursion_depth) + 1);
1326 fn check_recursion_depth<T>(
1329 error_obligation: &Obligation<'tcx, T>,
1330 ) -> Result<(), OverflowError>
1332 T: ToPredicate<'tcx> + Clone,
1334 if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
1335 match self.query_mode {
1336 TraitQueryMode::Standard => {
1337 if let Some(e) = self.infcx.tainted_by_errors() {
1338 return Err(OverflowError::Error(e));
1340 self.infcx.err_ctxt().report_overflow_obligation(error_obligation, true);
1342 TraitQueryMode::Canonical => {
1343 return Err(OverflowError::Canonical);
1350 /// Checks that the recursion limit has not been exceeded.
1352 /// The weird return type of this function allows it to be used with the `try` (`?`)
1353 /// operator within certain functions.
1355 fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V>(
1357 obligation: &Obligation<'tcx, T>,
1358 error_obligation: &Obligation<'tcx, V>,
1359 ) -> Result<(), OverflowError>
1361 V: ToPredicate<'tcx> + Clone,
1363 self.check_recursion_depth(obligation.recursion_depth, error_obligation)
1366 fn in_task<OP, R>(&mut self, op: OP) -> (R, DepNodeIndex)
1368 OP: FnOnce(&mut Self) -> R,
1370 let (result, dep_node) =
1371 self.tcx().dep_graph.with_anon_task(self.tcx(), DepKind::TraitSelect, || op(self));
1372 self.tcx().dep_graph.read_index(dep_node);
1376 /// filter_impls filters constant trait obligations and candidates that have a positive impl
1377 /// for a negative goal and a negative impl for a positive goal
1378 #[instrument(level = "debug", skip(self, candidates))]
1381 candidates: Vec<SelectionCandidate<'tcx>>,
1382 obligation: &TraitObligation<'tcx>,
1383 ) -> Vec<SelectionCandidate<'tcx>> {
1384 trace!("{candidates:#?}");
1385 let tcx = self.tcx();
1386 let mut result = Vec::with_capacity(candidates.len());
1388 for candidate in candidates {
1389 // Respect const trait obligations
1390 if obligation.is_const() {
1393 ImplCandidate(def_id) if tcx.constness(def_id) == hir::Constness::Const => {}
1395 ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
1397 ProjectionCandidate(_, ty::BoundConstness::ConstIfConst)
1400 // generator / future, this will raise error in other places
1401 // or ignore error with const_async_blocks feature
1402 | GeneratorCandidate
1404 // FnDef where the function is const
1405 | FnPointerCandidate { is_const: true }
1406 | ConstDestructCandidate(_)
1407 | ClosureCandidate { is_const: true } => {}
1409 FnPointerCandidate { is_const: false } => {
1410 if let ty::FnDef(def_id, _) = obligation.self_ty().skip_binder().kind() && tcx.trait_of_item(*def_id).is_some() {
1411 // Trait methods are not seen as const unless the trait is implemented as const.
1412 // We do not filter that out in here, but nested obligations will be needed to confirm this.
1419 // reject all other types of candidates
1425 if let ImplCandidate(def_id) = candidate {
1426 if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id)
1427 || obligation.polarity() == tcx.impl_polarity(def_id)
1429 result.push(candidate);
1432 result.push(candidate);
1436 trace!("{result:#?}");
1440 /// filter_reservation_impls filter reservation impl for any goal as ambiguous
1441 #[instrument(level = "debug", skip(self))]
1442 fn filter_reservation_impls(
1444 candidate: SelectionCandidate<'tcx>,
1445 obligation: &TraitObligation<'tcx>,
1446 ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
1447 let tcx = self.tcx();
1448 // Treat reservation impls as ambiguity.
1449 if let ImplCandidate(def_id) = candidate {
1450 if let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) {
1451 if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
1453 .get_attr(def_id, sym::rustc_reservation_impl)
1454 .and_then(|a| a.value_str());
1455 if let Some(value) = value {
1457 "filter_reservation_impls: \
1458 reservation impl ambiguity on {:?}",
1461 intercrate_ambiguity_clauses.insert(
1462 IntercrateAmbiguityCause::ReservationImpl {
1463 message: value.to_string(),
1474 fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
1475 debug!("is_knowable(intercrate={:?})", self.is_intercrate());
1477 if !self.is_intercrate() || stack.obligation.polarity() == ty::ImplPolarity::Negative {
1481 let obligation = &stack.obligation;
1482 let predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
1484 // Okay to skip binder because of the nature of the
1485 // trait-ref-is-knowable check, which does not care about
1487 let trait_ref = predicate.skip_binder().trait_ref;
1489 coherence::trait_ref_is_knowable(self.tcx(), trait_ref)
1492 /// Returns `true` if the global caches can be used.
1493 fn can_use_global_caches(&self, param_env: ty::ParamEnv<'tcx>) -> bool {
1494 // If there are any inference variables in the `ParamEnv`, then we
1495 // always use a cache local to this particular scope. Otherwise, we
1496 // switch to a global cache.
1497 if param_env.needs_infer() {
1501 // Avoid using the master cache during coherence and just rely
1502 // on the local cache. This effectively disables caching
1503 // during coherence. It is really just a simplification to
1504 // avoid us having to fear that coherence results "pollute"
1505 // the master cache. Since coherence executes pretty quickly,
1506 // it's not worth going to more trouble to increase the
1507 // hit-rate, I don't think.
1508 if self.is_intercrate() {
1512 // Otherwise, we can use the global cache.
1516 fn check_candidate_cache(
1518 mut param_env: ty::ParamEnv<'tcx>,
1519 cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
1520 ) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> {
1521 // Neither the global nor local cache is aware of intercrate
1522 // mode, so don't do any caching. In particular, we might
1523 // re-use the same `InferCtxt` with both an intercrate
1524 // and non-intercrate `SelectionContext`
1525 if self.is_intercrate() {
1528 let tcx = self.tcx();
1529 let mut pred = cache_fresh_trait_pred.skip_binder();
1530 pred.remap_constness(&mut param_env);
1532 if self.can_use_global_caches(param_env) {
1533 if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
1537 self.infcx.selection_cache.get(&(param_env, pred), tcx)
1540 /// Determines whether can we safely cache the result
1541 /// of selecting an obligation. This is almost always `true`,
1542 /// except when dealing with certain `ParamCandidate`s.
1544 /// Ordinarily, a `ParamCandidate` will contain no inference variables,
1545 /// since it was usually produced directly from a `DefId`. However,
1546 /// certain cases (currently only librustdoc's blanket impl finder),
1547 /// a `ParamEnv` may be explicitly constructed with inference types.
1548 /// When this is the case, we do *not* want to cache the resulting selection
1549 /// candidate. This is due to the fact that it might not always be possible
1550 /// to equate the obligation's trait ref and the candidate's trait ref,
1551 /// if more constraints end up getting added to an inference variable.
1553 /// Because of this, we always want to re-run the full selection
1554 /// process for our obligation the next time we see it, since
1555 /// we might end up picking a different `SelectionCandidate` (or none at all).
1556 fn can_cache_candidate(
1558 result: &SelectionResult<'tcx, SelectionCandidate<'tcx>>,
1560 // Neither the global nor local cache is aware of intercrate
1561 // mode, so don't do any caching. In particular, we might
1562 // re-use the same `InferCtxt` with both an intercrate
1563 // and non-intercrate `SelectionContext`
1564 if self.is_intercrate() {
1568 Ok(Some(SelectionCandidate::ParamCandidate(trait_ref))) => !trait_ref.needs_infer(),
1573 #[instrument(skip(self, param_env, cache_fresh_trait_pred, dep_node), level = "debug")]
1574 fn insert_candidate_cache(
1576 mut param_env: ty::ParamEnv<'tcx>,
1577 cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
1578 dep_node: DepNodeIndex,
1579 candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>,
1581 let tcx = self.tcx();
1582 let mut pred = cache_fresh_trait_pred.skip_binder();
1584 pred.remap_constness(&mut param_env);
1586 if !self.can_cache_candidate(&candidate) {
1587 debug!(?pred, ?candidate, "insert_candidate_cache - candidate is not cacheable");
1591 if self.can_use_global_caches(param_env) {
1592 if let Err(Overflow(OverflowError::Canonical)) = candidate {
1593 // Don't cache overflow globally; we only produce this in certain modes.
1594 } else if !pred.needs_infer() {
1595 if !candidate.needs_infer() {
1596 debug!(?pred, ?candidate, "insert_candidate_cache global");
1597 // This may overwrite the cache with the same value.
1598 tcx.selection_cache.insert((param_env, pred), dep_node, candidate);
1604 debug!(?pred, ?candidate, "insert_candidate_cache local");
1605 self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate);
1608 /// Matches a predicate against the bounds of its self type.
1610 /// Given an obligation like `<T as Foo>::Bar: Baz` where the self type is
1611 /// a projection, look at the bounds of `T::Bar`, see if we can find a
1612 /// `Baz` bound. We return indexes into the list returned by
1613 /// `tcx.item_bounds` for any applicable bounds.
1614 #[instrument(level = "debug", skip(self), ret)]
1615 fn match_projection_obligation_against_definition_bounds(
1617 obligation: &TraitObligation<'tcx>,
1618 ) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]> {
1619 let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
1620 let placeholder_trait_predicate =
1621 self.infcx.replace_bound_vars_with_placeholders(poly_trait_predicate);
1622 debug!(?placeholder_trait_predicate);
1624 let tcx = self.infcx.tcx;
1625 let (def_id, substs) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() {
1626 ty::Alias(_, ty::AliasTy { def_id, substs, .. }) => (def_id, substs),
1629 obligation.cause.span,
1630 "match_projection_obligation_against_definition_bounds() called \
1631 but self-ty is not a projection: {:?}",
1632 placeholder_trait_predicate.trait_ref.self_ty()
1636 let bounds = tcx.item_bounds(def_id).subst(tcx, substs);
1638 // The bounds returned by `item_bounds` may contain duplicates after
1639 // normalization, so try to deduplicate when possible to avoid
1640 // unnecessary ambiguity.
1641 let mut distinct_normalized_bounds = FxHashSet::default();
1646 .filter_map(|(idx, bound)| {
1647 let bound_predicate = bound.kind();
1648 if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) =
1649 bound_predicate.skip_binder()
1651 let bound = bound_predicate.rebind(pred.trait_ref);
1652 if self.infcx.probe(|_| {
1653 match self.match_normalize_trait_ref(
1656 placeholder_trait_predicate.trait_ref,
1659 Ok(Some(normalized_trait))
1660 if distinct_normalized_bounds.insert(normalized_trait) =>
1667 return Some((idx, pred.constness));
1675 /// Equates the trait in `obligation` with trait bound. If the two traits
1676 /// can be equated and the normalized trait bound doesn't contain inference
1677 /// variables or placeholders, the normalized bound is returned.
1678 fn match_normalize_trait_ref(
1680 obligation: &TraitObligation<'tcx>,
1681 trait_bound: ty::PolyTraitRef<'tcx>,
1682 placeholder_trait_ref: ty::TraitRef<'tcx>,
1683 ) -> Result<Option<ty::PolyTraitRef<'tcx>>, ()> {
1684 debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars());
1685 if placeholder_trait_ref.def_id != trait_bound.def_id() {
1686 // Avoid unnecessary normalization
1690 let Normalized { value: trait_bound, obligations: _ } = ensure_sufficient_stack(|| {
1691 project::normalize_with_depth(
1693 obligation.param_env,
1694 obligation.cause.clone(),
1695 obligation.recursion_depth + 1,
1700 .at(&obligation.cause, obligation.param_env)
1701 .define_opaque_types(false)
1702 .sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound)
1703 .map(|InferOk { obligations: _, value: () }| {
1704 // This method is called within a probe, so we can't have
1705 // inference variables and placeholders escape.
1706 if !trait_bound.needs_infer() && !trait_bound.has_placeholders() {
1715 fn where_clause_may_apply<'o>(
1717 stack: &TraitObligationStack<'o, 'tcx>,
1718 where_clause_trait_ref: ty::PolyTraitRef<'tcx>,
1719 ) -> Result<EvaluationResult, OverflowError> {
1720 self.evaluation_probe(|this| {
1721 match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
1722 Ok(obligations) => this.evaluate_predicates_recursively(stack.list(), obligations),
1723 Err(()) => Ok(EvaluatedToErr),
1728 /// Return `Yes` if the obligation's predicate type applies to the env_predicate, and
1729 /// `No` if it does not. Return `Ambiguous` in the case that the projection type is a GAT,
1730 /// and applying this env_predicate constrains any of the obligation's GAT substitutions.
1732 /// This behavior is a somewhat of a hack to prevent over-constraining inference variables
1733 /// in cases like #91762.
1734 pub(super) fn match_projection_projections(
1736 obligation: &ProjectionTyObligation<'tcx>,
1737 env_predicate: PolyProjectionPredicate<'tcx>,
1738 potentially_unnormalized_candidates: bool,
1739 ) -> ProjectionMatchesProjection {
1740 let mut nested_obligations = Vec::new();
1741 let infer_predicate = self.infcx.replace_bound_vars_with_fresh_vars(
1742 obligation.cause.span,
1743 LateBoundRegionConversionTime::HigherRankedType,
1746 let infer_projection = if potentially_unnormalized_candidates {
1747 ensure_sufficient_stack(|| {
1748 project::normalize_with_depth_to(
1750 obligation.param_env,
1751 obligation.cause.clone(),
1752 obligation.recursion_depth + 1,
1753 infer_predicate.projection_ty,
1754 &mut nested_obligations,
1758 infer_predicate.projection_ty
1763 .at(&obligation.cause, obligation.param_env)
1764 .define_opaque_types(false)
1765 .sup(obligation.predicate, infer_projection)
1766 .map_or(false, |InferOk { obligations, value: () }| {
1767 self.evaluate_predicates_recursively(
1768 TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
1769 nested_obligations.into_iter().chain(obligations),
1771 .map_or(false, |res| res.may_apply())
1775 let generics = self.tcx().generics_of(obligation.predicate.def_id);
1776 // FIXME(generic-associated-types): Addresses aggressive inference in #92917.
1777 // If this type is a GAT, and of the GAT substs resolve to something new,
1778 // that means that we must have newly inferred something about the GAT.
1779 // We should give up in that case.
1780 if !generics.params.is_empty()
1781 && obligation.predicate.substs[generics.parent_count..]
1783 .any(|&p| p.has_non_region_infer() && self.infcx.shallow_resolve(p) != p)
1785 ProjectionMatchesProjection::Ambiguous
1787 ProjectionMatchesProjection::Yes
1790 ProjectionMatchesProjection::No
1794 ///////////////////////////////////////////////////////////////////////////
1797 // Winnowing is the process of attempting to resolve ambiguity by
1798 // probing further. During the winnowing process, we unify all
1799 // type variables and then we also attempt to evaluate recursive
1800 // bounds to see if they are satisfied.
1802 /// Returns `true` if `victim` should be dropped in favor of
1803 /// `other`. Generally speaking we will drop duplicate
1804 /// candidates and prefer where-clause candidates.
1806 /// See the comment for "SelectionCandidate" for more details.
1807 fn candidate_should_be_dropped_in_favor_of(
1809 victim: &EvaluatedCandidate<'tcx>,
1810 other: &EvaluatedCandidate<'tcx>,
1813 if victim.candidate == other.candidate {
1817 // Check if a bound would previously have been removed when normalizing
1818 // the param_env so that it can be given the lowest priority. See
1819 // #50825 for the motivation for this.
1821 |cand: &ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_late_bound_vars();
1823 // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
1824 // `DiscriminantKindCandidate`, `ConstDestructCandidate`
1825 // to anything else.
1827 // This is a fix for #53123 and prevents winnowing from accidentally extending the
1828 // lifetime of a variable.
1829 match (&other.candidate, &victim.candidate) {
1830 (_, AutoImplCandidate) | (AutoImplCandidate, _) => {
1832 "default implementations shouldn't be recorded \
1833 when there are other valid candidates"
1837 // FIXME(@jswrenn): this should probably be more sophisticated
1838 (TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => false,
1841 (BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_), _) => true,
1842 (_, BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_)) => false,
1844 (ParamCandidate(other), ParamCandidate(victim)) => {
1845 let same_except_bound_vars = other.skip_binder().trait_ref
1846 == victim.skip_binder().trait_ref
1847 && other.skip_binder().constness == victim.skip_binder().constness
1848 && other.skip_binder().polarity == victim.skip_binder().polarity
1849 && !other.skip_binder().trait_ref.has_escaping_bound_vars();
1850 if same_except_bound_vars {
1851 // See issue #84398. In short, we can generate multiple ParamCandidates which are
1852 // the same except for unused bound vars. Just pick the one with the fewest bound vars
1853 // or the current one if tied (they should both evaluate to the same answer). This is
1854 // probably best characterized as a "hack", since we might prefer to just do our
1855 // best to *not* create essentially duplicate candidates in the first place.
1856 other.bound_vars().len() <= victim.bound_vars().len()
1857 } else if other.skip_binder().trait_ref == victim.skip_binder().trait_ref
1858 && victim.skip_binder().constness == ty::BoundConstness::NotConst
1859 && other.skip_binder().polarity == victim.skip_binder().polarity
1861 // Drop otherwise equivalent non-const candidates in favor of const candidates.
1868 // Drop otherwise equivalent non-const fn pointer candidates
1869 (FnPointerCandidate { .. }, FnPointerCandidate { is_const: false }) => true,
1871 // Global bounds from the where clause should be ignored
1872 // here (see issue #50825). Otherwise, we have a where
1873 // clause so don't go around looking for impls.
1874 // Arbitrarily give param candidates priority
1875 // over projection and object candidates.
1877 ParamCandidate(ref cand),
1879 | ClosureCandidate { .. }
1880 | GeneratorCandidate
1882 | FnPointerCandidate { .. }
1883 | BuiltinObjectCandidate
1884 | BuiltinUnsizeCandidate
1885 | TraitUpcastingUnsizeCandidate(_)
1886 | BuiltinCandidate { .. }
1887 | TraitAliasCandidate
1888 | ObjectCandidate(_)
1889 | ProjectionCandidate(..),
1890 ) => !is_global(cand),
1891 (ObjectCandidate(_) | ProjectionCandidate(..), ParamCandidate(ref cand)) => {
1892 // Prefer these to a global where-clause bound
1893 // (see issue #50825).
1898 | ClosureCandidate { .. }
1899 | GeneratorCandidate
1901 | FnPointerCandidate { .. }
1902 | BuiltinObjectCandidate
1903 | BuiltinUnsizeCandidate
1904 | TraitUpcastingUnsizeCandidate(_)
1905 | BuiltinCandidate { has_nested: true }
1906 | TraitAliasCandidate,
1907 ParamCandidate(ref cand),
1909 // Prefer these to a global where-clause bound
1910 // (see issue #50825).
1911 is_global(cand) && other.evaluation.must_apply_modulo_regions()
1914 (ProjectionCandidate(i, _), ProjectionCandidate(j, _))
1915 | (ObjectCandidate(i), ObjectCandidate(j)) => {
1916 // Arbitrarily pick the lower numbered candidate for backwards
1917 // compatibility reasons. Don't let this affect inference.
1918 i < j && !needs_infer
1920 (ObjectCandidate(_), ProjectionCandidate(..))
1921 | (ProjectionCandidate(..), ObjectCandidate(_)) => {
1922 bug!("Have both object and projection candidate")
1925 // Arbitrarily give projection and object candidates priority.
1927 ObjectCandidate(_) | ProjectionCandidate(..),
1929 | ClosureCandidate { .. }
1930 | GeneratorCandidate
1932 | FnPointerCandidate { .. }
1933 | BuiltinObjectCandidate
1934 | BuiltinUnsizeCandidate
1935 | TraitUpcastingUnsizeCandidate(_)
1936 | BuiltinCandidate { .. }
1937 | TraitAliasCandidate,
1942 | ClosureCandidate { .. }
1943 | GeneratorCandidate
1945 | FnPointerCandidate { .. }
1946 | BuiltinObjectCandidate
1947 | BuiltinUnsizeCandidate
1948 | TraitUpcastingUnsizeCandidate(_)
1949 | BuiltinCandidate { .. }
1950 | TraitAliasCandidate,
1951 ObjectCandidate(_) | ProjectionCandidate(..),
1954 (&ImplCandidate(other_def), &ImplCandidate(victim_def)) => {
1955 // See if we can toss out `victim` based on specialization.
1956 // While this requires us to know *for sure* that the `other` impl applies
1957 // we still use modulo regions here.
1959 // This is fine as specialization currently assumes that specializing
1960 // impls have to be always applicable, meaning that the only allowed
1961 // region constraints may be constraints also present on the default impl.
1962 let tcx = self.tcx();
1963 if other.evaluation.must_apply_modulo_regions() {
1964 if tcx.specializes((other_def, victim_def)) {
1969 if other.evaluation.must_apply_considering_regions() {
1970 match tcx.impls_are_allowed_to_overlap(other_def, victim_def) {
1971 Some(ty::ImplOverlapKind::Permitted { marker: true }) => {
1972 // Subtle: If the predicate we are evaluating has inference
1973 // variables, do *not* allow discarding candidates due to
1974 // marker trait impls.
1976 // Without this restriction, we could end up accidentally
1977 // constraining inference variables based on an arbitrarily
1978 // chosen trait impl.
1980 // Imagine we have the following code:
1983 // #[marker] trait MyTrait {}
1984 // impl MyTrait for u8 {}
1985 // impl MyTrait for bool {}
1988 // And we are evaluating the predicate `<_#0t as MyTrait>`.
1990 // During selection, we will end up with one candidate for each
1991 // impl of `MyTrait`. If we were to discard one impl in favor
1992 // of the other, we would be left with one candidate, causing
1993 // us to "successfully" select the predicate, unifying
1994 // _#0t with (for example) `u8`.
1996 // However, we have no reason to believe that this unification
1997 // is correct - we've essentially just picked an arbitrary
1998 // *possibility* for _#0t, and required that this be the *only*
2001 // Eventually, we will either:
2002 // 1) Unify all inference variables in the predicate through
2003 // some other means (e.g. type-checking of a function). We will
2004 // then be in a position to drop marker trait candidates
2005 // without constraining inference variables (since there are
2006 // none left to constrain)
2007 // 2) Be left with some unconstrained inference variables. We
2008 // will then correctly report an inference error, since the
2009 // existence of multiple marker trait impls tells us nothing
2010 // about which one should actually apply.
2021 // Everything else is ambiguous
2024 | ClosureCandidate { .. }
2025 | GeneratorCandidate
2027 | FnPointerCandidate { .. }
2028 | BuiltinObjectCandidate
2029 | BuiltinUnsizeCandidate
2030 | TraitUpcastingUnsizeCandidate(_)
2031 | BuiltinCandidate { has_nested: true }
2032 | TraitAliasCandidate,
2034 | ClosureCandidate { .. }
2035 | GeneratorCandidate
2037 | FnPointerCandidate { .. }
2038 | BuiltinObjectCandidate
2039 | BuiltinUnsizeCandidate
2040 | TraitUpcastingUnsizeCandidate(_)
2041 | BuiltinCandidate { has_nested: true }
2042 | TraitAliasCandidate,
2047 fn sized_conditions(
2049 obligation: &TraitObligation<'tcx>,
2050 ) -> BuiltinImplConditions<'tcx> {
2051 use self::BuiltinImplConditions::{Ambiguous, None, Where};
2053 // NOTE: binder moved to (*)
2054 let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
2056 match self_ty.kind() {
2057 ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
2068 | ty::GeneratorWitness(..)
2072 | ty::Dynamic(_, _, ty::DynStar)
2074 // safe for everything
2075 Where(ty::Binder::dummy(Vec::new()))
2078 ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None,
2080 ty::Tuple(tys) => Where(
2081 obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])),
2084 ty::Adt(def, substs) => {
2085 let sized_crit = def.sized_constraint(self.tcx());
2086 // (*) binder moved here
2087 Where(obligation.predicate.rebind({
2091 .map(|ty| sized_crit.rebind(*ty).subst(self.tcx(), substs))
2096 ty::Alias(..) | ty::Param(_) => None,
2097 ty::Infer(ty::TyVar(_)) => Ambiguous,
2101 | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
2102 bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty);
2107 fn copy_clone_conditions(
2109 obligation: &TraitObligation<'tcx>,
2110 ) -> BuiltinImplConditions<'tcx> {
2111 // NOTE: binder moved to (*)
2112 let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
2114 use self::BuiltinImplConditions::{Ambiguous, None, Where};
2116 match *self_ty.kind() {
2117 ty::Infer(ty::IntVar(_))
2118 | ty::Infer(ty::FloatVar(_))
2121 | ty::Error(_) => Where(ty::Binder::dummy(Vec::new())),
2130 | ty::Ref(_, _, hir::Mutability::Not)
2131 | ty::Array(..) => {
2132 // Implementations provided in libcore
2139 | ty::Generator(_, _, hir::Movability::Static)
2141 | ty::Ref(_, _, hir::Mutability::Mut) => None,
2144 // (*) binder moved here
2145 Where(obligation.predicate.rebind(tys.iter().collect()))
2148 ty::Generator(_, substs, hir::Movability::Movable) => {
2149 if self.tcx().features().generator_clone {
2150 let resolved_upvars =
2151 self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
2152 let resolved_witness =
2153 self.infcx.shallow_resolve(substs.as_generator().witness());
2154 if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
2155 // Not yet resolved.
2161 .chain(iter::once(substs.as_generator().witness()))
2162 .collect::<Vec<_>>();
2163 Where(obligation.predicate.rebind(all))
2170 ty::GeneratorWitness(binder) => {
2171 let witness_tys = binder.skip_binder();
2172 for witness_ty in witness_tys.iter() {
2173 let resolved = self.infcx.shallow_resolve(witness_ty);
2174 if resolved.is_ty_var() {
2178 // (*) binder moved here
2179 let all_vars = self.tcx().mk_bound_variable_kinds(
2180 obligation.predicate.bound_vars().iter().chain(binder.bound_vars().iter()),
2182 Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars))
2185 ty::Closure(_, substs) => {
2186 // (*) binder moved here
2187 let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
2188 if let ty::Infer(ty::TyVar(_)) = ty.kind() {
2189 // Not yet resolved.
2192 Where(obligation.predicate.rebind(substs.as_closure().upvar_tys().collect()))
2196 ty::Adt(..) | ty::Alias(..) | ty::Param(..) => {
2197 // Fallback to whatever user-defined impls exist in this case.
2201 ty::Infer(ty::TyVar(_)) => {
2202 // Unbound type variable. Might or might not have
2203 // applicable impls and so forth, depending on what
2204 // those type variables wind up being bound to.
2210 | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
2211 bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty);
2216 /// For default impls, we need to break apart a type into its
2217 /// "constituent types" -- meaning, the types that it contains.
2219 /// Here are some (simple) examples:
2221 /// ```ignore (illustrative)
2222 /// (i32, u32) -> [i32, u32]
2223 /// Foo where struct Foo { x: i32, y: u32 } -> [i32, u32]
2224 /// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
2225 /// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
2227 #[instrument(level = "debug", skip(self), ret)]
2228 fn constituent_types_for_ty(
2230 t: ty::Binder<'tcx, Ty<'tcx>>,
2231 ) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
2232 match *t.skip_binder().kind() {
2241 | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
2243 | ty::Char => ty::Binder::dummy(Vec::new()),
2249 | ty::Alias(ty::Projection, ..)
2251 | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
2252 bug!("asked to assemble constituent types of unexpected type: {:?}", t);
2255 ty::RawPtr(ty::TypeAndMut { ty: element_ty, .. }) | ty::Ref(_, element_ty, _) => {
2256 t.rebind(vec![element_ty])
2259 ty::Array(element_ty, _) | ty::Slice(element_ty) => t.rebind(vec![element_ty]),
2261 ty::Tuple(ref tys) => {
2262 // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
2263 t.rebind(tys.iter().collect())
2266 ty::Closure(_, ref substs) => {
2267 let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
2271 ty::Generator(_, ref substs, _) => {
2272 let ty = self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
2273 let witness = substs.as_generator().witness();
2274 t.rebind([ty].into_iter().chain(iter::once(witness)).collect())
2277 ty::GeneratorWitness(types) => {
2278 debug_assert!(!types.has_escaping_bound_vars());
2279 types.map_bound(|types| types.to_vec())
2282 // For `PhantomData<T>`, we pass `T`.
2283 ty::Adt(def, substs) if def.is_phantom_data() => t.rebind(substs.types().collect()),
2285 ty::Adt(def, substs) => {
2286 t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect())
2289 ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
2290 // We can resolve the `impl Trait` to its concrete type,
2291 // which enforces a DAG between the functions requiring
2292 // the auto trait bounds in question.
2293 t.rebind(vec![self.tcx().bound_type_of(def_id).subst(self.tcx(), substs)])
2298 fn collect_predicates_for_types(
2300 param_env: ty::ParamEnv<'tcx>,
2301 cause: ObligationCause<'tcx>,
2302 recursion_depth: usize,
2303 trait_def_id: DefId,
2304 types: ty::Binder<'tcx, Vec<Ty<'tcx>>>,
2305 ) -> Vec<PredicateObligation<'tcx>> {
2306 // Because the types were potentially derived from
2307 // higher-ranked obligations they may reference late-bound
2308 // regions. For example, `for<'a> Foo<&'a i32> : Copy` would
2309 // yield a type like `for<'a> &'a i32`. In general, we
2310 // maintain the invariant that we never manipulate bound
2311 // regions, so we have to process these bound regions somehow.
2313 // The strategy is to:
2315 // 1. Instantiate those regions to placeholder regions (e.g.,
2316 // `for<'a> &'a i32` becomes `&0 i32`.
2317 // 2. Produce something like `&'0 i32 : Copy`
2318 // 3. Re-bind the regions back to `for<'a> &'a i32 : Copy`
2322 .skip_binder() // binder moved -\
2325 let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(*ty); // <----/
2327 let placeholder_ty = self.infcx.replace_bound_vars_with_placeholders(ty);
2328 let Normalized { value: normalized_ty, mut obligations } =
2329 ensure_sufficient_stack(|| {
2330 project::normalize_with_depth(
2338 let placeholder_obligation = predicate_for_trait_def(
2346 obligations.push(placeholder_obligation);
2352 ///////////////////////////////////////////////////////////////////////////
2355 // Matching is a common path used for both evaluation and
2356 // confirmation. It basically unifies types that appear in impls
2357 // and traits. This does affect the surrounding environment;
2358 // therefore, when used during evaluation, match routines must be
2359 // run inside of a `probe()` so that their side-effects are
2365 obligation: &TraitObligation<'tcx>,
2366 ) -> Normalized<'tcx, SubstsRef<'tcx>> {
2367 let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
2368 match self.match_impl(impl_def_id, impl_trait_ref, obligation) {
2369 Ok(substs) => substs,
2371 // FIXME: A rematch may fail when a candidate cache hit occurs
2372 // on thefreshened form of the trait predicate, but the match
2373 // fails for some reason that is not captured in the freshened
2374 // cache key. For example, equating an impl trait ref against
2375 // the placeholder trait ref may fail due the Generalizer relation
2376 // raising a CyclicalTy error due to a sub_root_var relation
2377 // for a variable being generalized...
2378 self.infcx.tcx.sess.delay_span_bug(
2379 obligation.cause.span,
2381 "Impl {:?} was matchable against {:?} but now is not",
2382 impl_def_id, obligation
2385 let value = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
2386 let err = self.tcx().ty_error();
2387 let value = value.fold_with(&mut BottomUpFolder {
2393 Normalized { value, obligations: vec![] }
2398 #[instrument(level = "debug", skip(self), ret)]
2402 impl_trait_ref: EarlyBinder<ty::TraitRef<'tcx>>,
2403 obligation: &TraitObligation<'tcx>,
2404 ) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> {
2405 let placeholder_obligation =
2406 self.infcx.replace_bound_vars_with_placeholders(obligation.predicate);
2407 let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref;
2409 let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
2411 let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs);
2412 if impl_trait_ref.references_error() {
2416 debug!(?impl_trait_ref);
2418 let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } =
2419 ensure_sufficient_stack(|| {
2420 project::normalize_with_depth(
2422 obligation.param_env,
2423 obligation.cause.clone(),
2424 obligation.recursion_depth + 1,
2429 debug!(?impl_trait_ref, ?placeholder_obligation_trait_ref);
2431 let cause = ObligationCause::new(
2432 obligation.cause.span,
2433 obligation.cause.body_id,
2434 ObligationCauseCode::MatchImpl(obligation.cause.clone(), impl_def_id),
2437 let InferOk { obligations, .. } = self
2439 .at(&cause, obligation.param_env)
2440 .define_opaque_types(false)
2441 .eq(placeholder_obligation_trait_ref, impl_trait_ref)
2442 .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{e}`"))?;
2443 nested_obligations.extend(obligations);
2445 if !self.is_intercrate()
2446 && self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation
2448 debug!("reservation impls only apply in intercrate mode");
2452 Ok(Normalized { value: impl_substs, obligations: nested_obligations })
2455 fn fast_reject_trait_refs(
2457 obligation: &TraitObligation<'tcx>,
2458 impl_trait_ref: &ty::TraitRef<'tcx>,
2460 // We can avoid creating type variables and doing the full
2461 // substitution if we find that any of the input types, when
2462 // simplified, do not match.
2463 let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::AsPlaceholder };
2464 iter::zip(obligation.predicate.skip_binder().trait_ref.substs, impl_trait_ref.substs)
2465 .any(|(obl, imp)| !drcx.generic_args_may_unify(obl, imp))
2468 /// Normalize `where_clause_trait_ref` and try to match it against
2469 /// `obligation`. If successful, return any predicates that
2470 /// result from the normalization.
2471 fn match_where_clause_trait_ref(
2473 obligation: &TraitObligation<'tcx>,
2474 where_clause_trait_ref: ty::PolyTraitRef<'tcx>,
2475 ) -> Result<Vec<PredicateObligation<'tcx>>, ()> {
2476 self.match_poly_trait_ref(obligation, where_clause_trait_ref)
2479 /// Returns `Ok` if `poly_trait_ref` being true implies that the
2480 /// obligation is satisfied.
2481 #[instrument(skip(self), level = "debug")]
2482 fn match_poly_trait_ref(
2484 obligation: &TraitObligation<'tcx>,
2485 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2486 ) -> Result<Vec<PredicateObligation<'tcx>>, ()> {
2488 .at(&obligation.cause, obligation.param_env)
2489 // We don't want predicates for opaque types to just match all other types,
2490 // if there is an obligation on the opaque type, then that obligation must be met
2491 // opaquely. Otherwise we'd match any obligation to the opaque type and then error
2493 .define_opaque_types(false)
2494 .sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
2495 .map(|InferOk { obligations, .. }| obligations)
2499 ///////////////////////////////////////////////////////////////////////////
2502 fn match_fresh_trait_refs(
2504 previous: ty::PolyTraitPredicate<'tcx>,
2505 current: ty::PolyTraitPredicate<'tcx>,
2506 param_env: ty::ParamEnv<'tcx>,
2508 let mut matcher = ty::_match::Match::new(self.tcx(), param_env);
2509 matcher.relate(previous, current).is_ok()
2514 previous_stack: TraitObligationStackList<'o, 'tcx>,
2515 obligation: &'o TraitObligation<'tcx>,
2516 ) -> TraitObligationStack<'o, 'tcx> {
2517 let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener);
2519 let dfn = previous_stack.cache.next_dfn();
2520 let depth = previous_stack.depth() + 1;
2521 TraitObligationStack {
2524 reached_depth: Cell::new(depth),
2525 previous: previous_stack,
2531 #[instrument(skip(self), level = "debug")]
2532 fn closure_trait_ref_unnormalized(
2534 obligation: &TraitObligation<'tcx>,
2535 substs: SubstsRef<'tcx>,
2536 ) -> ty::PolyTraitRef<'tcx> {
2537 let closure_sig = substs.as_closure().sig();
2539 debug!(?closure_sig);
2541 // NOTE: The self-type is an unboxed closure type and hence is
2542 // in fact unparameterized (or at least does not reference any
2543 // regions bound in the obligation).
2544 let self_ty = obligation
2548 .expect("unboxed closure type should not capture bound vars from the predicate");
2550 closure_trait_ref_and_return_type(
2552 obligation.predicate.def_id(),
2555 util::TupleArgumentsFlag::No,
2557 .map_bound(|(trait_ref, _)| trait_ref)
2560 /// Returns the obligations that are implied by instantiating an
2561 /// impl or trait. The obligations are substituted and fully
2562 /// normalized. This is used when confirming an impl or default
2564 #[instrument(level = "debug", skip(self, cause, param_env))]
2565 fn impl_or_trait_obligations(
2567 cause: &ObligationCause<'tcx>,
2568 recursion_depth: usize,
2569 param_env: ty::ParamEnv<'tcx>,
2570 def_id: DefId, // of impl or trait
2571 substs: SubstsRef<'tcx>, // for impl or trait
2572 parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
2573 ) -> Vec<PredicateObligation<'tcx>> {
2574 let tcx = self.tcx();
2576 // To allow for one-pass evaluation of the nested obligation,
2577 // each predicate must be preceded by the obligations required
2579 // for example, if we have:
2580 // impl<U: Iterator<Item: Copy>, V: Iterator<Item = U>> Foo for V
2581 // the impl will have the following predicates:
2582 // <V as Iterator>::Item = U,
2583 // U: Iterator, U: Sized,
2584 // V: Iterator, V: Sized,
2585 // <U as Iterator>::Item: Copy
2586 // When we substitute, say, `V => IntoIter<u32>, U => $0`, the last
2587 // obligation will normalize to `<$0 as Iterator>::Item = $1` and
2588 // `$1: Copy`, so we must ensure the obligations are emitted in
2590 let predicates = tcx.predicates_of(def_id);
2591 assert_eq!(predicates.parent, None);
2592 let predicates = predicates.instantiate_own(tcx, substs);
2593 let mut obligations = Vec::with_capacity(predicates.len());
2594 for (predicate, span) in predicates {
2595 let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
2596 ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
2598 impl_def_id: def_id,
2602 let predicate = normalize_with_depth_to(
2610 obligations.push(Obligation { cause, recursion_depth, param_env, predicate });
2617 impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {
2618 fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> {
2619 TraitObligationStackList::with(self)
2622 fn cache(&self) -> &'o ProvisionalEvaluationCache<'tcx> {
2626 fn iter(&'o self) -> TraitObligationStackList<'o, 'tcx> {
2630 /// Indicates that attempting to evaluate this stack entry
2631 /// required accessing something from the stack at depth `reached_depth`.
2632 fn update_reached_depth(&self, reached_depth: usize) {
2634 self.depth >= reached_depth,
2635 "invoked `update_reached_depth` with something under this stack: \
2636 self.depth={} reached_depth={}",
2640 debug!(reached_depth, "update_reached_depth");
2642 while reached_depth < p.depth {
2643 debug!(?p.fresh_trait_pred, "update_reached_depth: marking as cycle participant");
2644 p.reached_depth.set(p.reached_depth.get().min(reached_depth));
2645 p = p.previous.head.unwrap();
2650 /// The "provisional evaluation cache" is used to store intermediate cache results
2651 /// when solving auto traits. Auto traits are unusual in that they can support
2652 /// cycles. So, for example, a "proof tree" like this would be ok:
2654 /// - `Foo<T>: Send` :-
2655 /// - `Bar<T>: Send` :-
2656 /// - `Foo<T>: Send` -- cycle, but ok
2657 /// - `Baz<T>: Send`
2659 /// Here, to prove `Foo<T>: Send`, we have to prove `Bar<T>: Send` and
2660 /// `Baz<T>: Send`. Proving `Bar<T>: Send` in turn required `Foo<T>: Send`.
2661 /// For non-auto traits, this cycle would be an error, but for auto traits (because
2662 /// they are coinductive) it is considered ok.
2664 /// However, there is a complication: at the point where we have
2665 /// "proven" `Bar<T>: Send`, we have in fact only proven it
2666 /// *provisionally*. In particular, we proved that `Bar<T>: Send`
2667 /// *under the assumption* that `Foo<T>: Send`. But what if we later
2668 /// find out this assumption is wrong? Specifically, we could
2669 /// encounter some kind of error proving `Baz<T>: Send`. In that case,
2670 /// `Bar<T>: Send` didn't turn out to be true.
2672 /// In Issue #60010, we found a bug in rustc where it would cache
2673 /// these intermediate results. This was fixed in #60444 by disabling
2674 /// *all* caching for things involved in a cycle -- in our example,
2675 /// that would mean we don't cache that `Bar<T>: Send`. But this led
2676 /// to large slowdowns.
2678 /// Specifically, imagine this scenario, where proving `Baz<T>: Send`
2679 /// first requires proving `Bar<T>: Send` (which is true:
2681 /// - `Foo<T>: Send` :-
2682 /// - `Bar<T>: Send` :-
2683 /// - `Foo<T>: Send` -- cycle, but ok
2684 /// - `Baz<T>: Send`
2685 /// - `Bar<T>: Send` -- would be nice for this to be a cache hit!
2686 /// - `*const T: Send` -- but what if we later encounter an error?
2688 /// The *provisional evaluation cache* resolves this issue. It stores
2689 /// cache results that we've proven but which were involved in a cycle
2690 /// in some way. We track the minimal stack depth (i.e., the
2691 /// farthest from the top of the stack) that we are dependent on.
2692 /// The idea is that the cache results within are all valid -- so long as
2693 /// none of the nodes in between the current node and the node at that minimum
2694 /// depth result in an error (in which case the cached results are just thrown away).
2696 /// During evaluation, we consult this provisional cache and rely on
2697 /// it. Accessing a cached value is considered equivalent to accessing
2698 /// a result at `reached_depth`, so it marks the *current* solution as
2699 /// provisional as well. If an error is encountered, we toss out any
2700 /// provisional results added from the subtree that encountered the
2701 /// error. When we pop the node at `reached_depth` from the stack, we
2702 /// can commit all the things that remain in the provisional cache.
2703 struct ProvisionalEvaluationCache<'tcx> {
2704 /// next "depth first number" to issue -- just a counter
2707 /// Map from cache key to the provisionally evaluated thing.
2708 /// The cache entries contain the result but also the DFN in which they
2709 /// were added. The DFN is used to clear out values on failure.
2711 /// Imagine we have a stack like:
2713 /// - `A B C` and we add a cache for the result of C (DFN 2)
2714 /// - Then we have a stack `A B D` where `D` has DFN 3
2715 /// - We try to solve D by evaluating E: `A B D E` (DFN 4)
2716 /// - `E` generates various cache entries which have cyclic dependencies on `B`
2717 /// - `A B D E F` and so forth
2718 /// - the DFN of `F` for example would be 5
2719 /// - then we determine that `E` is in error -- we will then clear
2720 /// all cache values whose DFN is >= 4 -- in this case, that
2721 /// means the cached value for `F`.
2722 map: RefCell<FxHashMap<ty::PolyTraitPredicate<'tcx>, ProvisionalEvaluation>>,
2724 /// The stack of args that we assume to be true because a `WF(arg)` predicate
2725 /// is on the stack above (and because of wellformedness is coinductive).
2726 /// In an "ideal" world, this would share a stack with trait predicates in
2727 /// `TraitObligationStack`. However, trait predicates are *much* hotter than
2728 /// `WellFormed` predicates, and it's very likely that the additional matches
2729 /// will have a perf effect. The value here is the well-formed `GenericArg`
2730 /// and the depth of the trait predicate *above* that well-formed predicate.
2731 wf_args: RefCell<Vec<(ty::GenericArg<'tcx>, usize)>>,
2734 /// A cache value for the provisional cache: contains the depth-first
2735 /// number (DFN) and result.
2736 #[derive(Copy, Clone, Debug)]
2737 struct ProvisionalEvaluation {
2739 reached_depth: usize,
2740 result: EvaluationResult,
2743 impl<'tcx> Default for ProvisionalEvaluationCache<'tcx> {
2744 fn default() -> Self {
2745 Self { dfn: Cell::new(0), map: Default::default(), wf_args: Default::default() }
2749 impl<'tcx> ProvisionalEvaluationCache<'tcx> {
2750 /// Get the next DFN in sequence (basically a counter).
2751 fn next_dfn(&self) -> usize {
2752 let result = self.dfn.get();
2753 self.dfn.set(result + 1);
2757 /// Check the provisional cache for any result for
2758 /// `fresh_trait_ref`. If there is a hit, then you must consider
2759 /// it an access to the stack slots at depth
2760 /// `reached_depth` (from the returned value).
2763 fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
2764 ) -> Option<ProvisionalEvaluation> {
2767 "get_provisional = {:#?}",
2768 self.map.borrow().get(&fresh_trait_pred),
2770 Some(*self.map.borrow().get(&fresh_trait_pred)?)
2773 /// Insert a provisional result into the cache. The result came
2774 /// from the node with the given DFN. It accessed a minimum depth
2775 /// of `reached_depth` to compute. It evaluated `fresh_trait_pred`
2776 /// and resulted in `result`.
2777 fn insert_provisional(
2780 reached_depth: usize,
2781 fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
2782 result: EvaluationResult,
2784 debug!(?from_dfn, ?fresh_trait_pred, ?result, "insert_provisional");
2786 let mut map = self.map.borrow_mut();
2788 // Subtle: when we complete working on the DFN `from_dfn`, anything
2789 // that remains in the provisional cache must be dependent on some older
2790 // stack entry than `from_dfn`. We have to update their depth with our transitive
2791 // depth in that case or else it would be referring to some popped note.
2794 // A (reached depth 0)
2796 // B // depth 1 -- reached depth = 0
2797 // C // depth 2 -- reached depth = 1 (should be 0)
2800 // D (reached depth 1)
2801 // C (cache -- reached depth = 2)
2802 for (_k, v) in &mut *map {
2803 if v.from_dfn >= from_dfn {
2804 v.reached_depth = reached_depth.min(v.reached_depth);
2808 map.insert(fresh_trait_pred, ProvisionalEvaluation { from_dfn, reached_depth, result });
2811 /// Invoked when the node with dfn `dfn` does not get a successful
2812 /// result. This will clear out any provisional cache entries
2813 /// that were added since `dfn` was created. This is because the
2814 /// provisional entries are things which must assume that the
2815 /// things on the stack at the time of their creation succeeded --
2816 /// since the failing node is presently at the top of the stack,
2817 /// these provisional entries must either depend on it or some
2819 fn on_failure(&self, dfn: usize) {
2820 debug!(?dfn, "on_failure");
2821 self.map.borrow_mut().retain(|key, eval| {
2822 if !eval.from_dfn >= dfn {
2823 debug!("on_failure: removing {:?}", key);
2831 /// Invoked when the node at depth `depth` completed without
2832 /// depending on anything higher in the stack (if that completion
2833 /// was a failure, then `on_failure` should have been invoked
2836 /// Note that we may still have provisional cache items remaining
2837 /// in the cache when this is done. For example, if there is a
2840 /// * A depends on...
2841 /// * B depends on A
2842 /// * C depends on...
2843 /// * D depends on C
2846 /// Then as we complete the C node we will have a provisional cache
2847 /// with results for A, B, C, and D. This method would clear out
2848 /// the C and D results, but leave A and B provisional.
2850 /// This is determined based on the DFN: we remove any provisional
2851 /// results created since `dfn` started (e.g., in our example, dfn
2852 /// would be 2, representing the C node, and hence we would
2853 /// remove the result for D, which has DFN 3, but not the results for
2854 /// A and B, which have DFNs 0 and 1 respectively).
2856 /// Note that we *do not* attempt to cache these cycle participants
2857 /// in the evaluation cache. Doing so would require carefully computing
2858 /// the correct `DepNode` to store in the cache entry:
2859 /// cycle participants may implicitly depend on query results
2860 /// related to other participants in the cycle, due to our logic
2861 /// which examines the evaluation stack.
2863 /// We used to try to perform this caching,
2864 /// but it lead to multiple incremental compilation ICEs
2865 /// (see #92987 and #96319), and was very hard to understand.
2866 /// Fortunately, removing the caching didn't seem to
2867 /// have a performance impact in practice.
2868 fn on_completion(&self, dfn: usize) {
2869 debug!(?dfn, "on_completion");
2871 for (fresh_trait_pred, eval) in
2872 self.map.borrow_mut().drain_filter(|_k, eval| eval.from_dfn >= dfn)
2874 debug!(?fresh_trait_pred, ?eval, "on_completion");
2879 #[derive(Copy, Clone)]
2880 struct TraitObligationStackList<'o, 'tcx> {
2881 cache: &'o ProvisionalEvaluationCache<'tcx>,
2882 head: Option<&'o TraitObligationStack<'o, 'tcx>>,
2885 impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> {
2886 fn empty(cache: &'o ProvisionalEvaluationCache<'tcx>) -> TraitObligationStackList<'o, 'tcx> {
2887 TraitObligationStackList { cache, head: None }
2890 fn with(r: &'o TraitObligationStack<'o, 'tcx>) -> TraitObligationStackList<'o, 'tcx> {
2891 TraitObligationStackList { cache: r.cache(), head: Some(r) }
2894 fn head(&self) -> Option<&'o TraitObligationStack<'o, 'tcx>> {
2898 fn depth(&self) -> usize {
2899 if let Some(head) = self.head { head.depth } else { 0 }
2903 impl<'o, 'tcx> Iterator for TraitObligationStackList<'o, 'tcx> {
2904 type Item = &'o TraitObligationStack<'o, 'tcx>;
2906 fn next(&mut self) -> Option<&'o TraitObligationStack<'o, 'tcx>> {
2913 impl<'o, 'tcx> fmt::Debug for TraitObligationStack<'o, 'tcx> {
2914 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2915 write!(f, "TraitObligationStack({:?})", self.obligation)
2919 pub enum ProjectionMatchesProjection {