• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Candidate selection. See the [rustc dev guide] for more information on how this works.
2 //!
3 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html#selection
4 
5 use self::EvaluationResult::*;
6 use self::SelectionCandidate::*;
7 
8 use super::coherence::{self, Conflict};
9 use super::const_evaluatable;
10 use super::project;
11 use super::project::normalize_with_depth_to;
12 use super::project::ProjectionTyObligation;
13 use super::util;
14 use super::util::closure_trait_ref_and_return_type;
15 use super::wf;
16 use super::{
17     ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, Normalized, Obligation,
18     ObligationCause, ObligationCauseCode, Overflow, PolyTraitObligation, PredicateObligation,
19     Selection, SelectionError, SelectionResult, TraitQueryMode,
20 };
21 
22 use crate::infer::{InferCtxt, InferOk, TypeFreshener};
23 use crate::solve::InferCtxtSelectExt;
24 use crate::traits::error_reporting::TypeErrCtxtExt;
25 use crate::traits::project::try_normalize_with_depth_to;
26 use crate::traits::project::ProjectAndUnifyResult;
27 use crate::traits::project::ProjectionCacheKeyExt;
28 use crate::traits::ProjectionCacheKey;
29 use crate::traits::Unimplemented;
30 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
31 use rustc_data_structures::stack::ensure_sufficient_stack;
32 use rustc_errors::Diagnostic;
33 use rustc_hir as hir;
34 use rustc_hir::def_id::DefId;
35 use rustc_infer::infer::DefineOpaqueTypes;
36 use rustc_infer::infer::LateBoundRegionConversionTime;
37 use rustc_infer::traits::TraitObligation;
38 use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
39 use rustc_middle::mir::interpret::ErrorHandled;
40 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
41 use rustc_middle::ty::fold::BottomUpFolder;
42 use rustc_middle::ty::relate::TypeRelation;
43 use rustc_middle::ty::SubstsRef;
44 use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
45 use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
46 use rustc_span::symbol::sym;
47 
48 use std::cell::{Cell, RefCell};
49 use std::cmp;
50 use std::fmt::{self, Display};
51 use std::iter;
52 
53 pub use rustc_middle::traits::select::*;
54 use rustc_middle::ty::print::with_no_trimmed_paths;
55 
56 mod candidate_assembly;
57 mod confirmation;
58 
59 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
60 pub enum IntercrateAmbiguityCause {
61     DownstreamCrate { trait_desc: String, self_desc: Option<String> },
62     UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> },
63     ReservationImpl { message: String },
64 }
65 
66 impl IntercrateAmbiguityCause {
67     /// Emits notes when the overlap is caused by complex intercrate ambiguities.
68     /// See #23980 for details.
add_intercrate_ambiguity_hint(&self, err: &mut Diagnostic)69     pub fn add_intercrate_ambiguity_hint(&self, err: &mut Diagnostic) {
70         err.note(self.intercrate_ambiguity_hint());
71     }
72 
intercrate_ambiguity_hint(&self) -> String73     pub fn intercrate_ambiguity_hint(&self) -> String {
74         match self {
75             IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } => {
76                 let self_desc = if let Some(ty) = self_desc {
77                     format!(" for type `{}`", ty)
78                 } else {
79                     String::new()
80                 };
81                 format!("downstream crates may implement trait `{}`{}", trait_desc, self_desc)
82             }
83             IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc } => {
84                 let self_desc = if let Some(ty) = self_desc {
85                     format!(" for type `{}`", ty)
86                 } else {
87                     String::new()
88                 };
89                 format!(
90                     "upstream crates may add a new impl of trait `{}`{} \
91                      in future versions",
92                     trait_desc, self_desc
93                 )
94             }
95             IntercrateAmbiguityCause::ReservationImpl { message } => message.clone(),
96         }
97     }
98 }
99 
100 pub struct SelectionContext<'cx, 'tcx> {
101     pub infcx: &'cx InferCtxt<'tcx>,
102 
103     /// Freshener used specifically for entries on the obligation
104     /// stack. This ensures that all entries on the stack at one time
105     /// will have the same set of placeholder entries, which is
106     /// important for checking for trait bounds that recursively
107     /// require themselves.
108     freshener: TypeFreshener<'cx, 'tcx>,
109 
110     /// If `intercrate` is set, we remember predicates which were
111     /// considered ambiguous because of impls potentially added in other crates.
112     /// This is used in coherence to give improved diagnostics.
113     /// We don't do his until we detect a coherence error because it can
114     /// lead to false overflow results (#47139) and because always
115     /// computing it may negatively impact performance.
116     intercrate_ambiguity_causes: Option<FxIndexSet<IntercrateAmbiguityCause>>,
117 
118     /// The mode that trait queries run in, which informs our error handling
119     /// policy. In essence, canonicalized queries need their errors propagated
120     /// rather than immediately reported because we do not have accurate spans.
121     query_mode: TraitQueryMode,
122 }
123 
124 // A stack that walks back up the stack frame.
125 struct TraitObligationStack<'prev, 'tcx> {
126     obligation: &'prev PolyTraitObligation<'tcx>,
127 
128     /// The trait predicate from `obligation` but "freshened" with the
129     /// selection-context's freshener. Used to check for recursion.
130     fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
131 
132     /// Starts out equal to `depth` -- if, during evaluation, we
133     /// encounter a cycle, then we will set this flag to the minimum
134     /// depth of that cycle for all participants in the cycle. These
135     /// participants will then forego caching their results. This is
136     /// not the most efficient solution, but it addresses #60010. The
137     /// problem we are trying to prevent:
138     ///
139     /// - If you have `A: AutoTrait` requires `B: AutoTrait` and `C: NonAutoTrait`
140     /// - `B: AutoTrait` requires `A: AutoTrait` (coinductive cycle, ok)
141     /// - `C: NonAutoTrait` requires `A: AutoTrait` (non-coinductive cycle, not ok)
142     ///
143     /// you don't want to cache that `B: AutoTrait` or `A: AutoTrait`
144     /// is `EvaluatedToOk`; this is because they were only considered
145     /// ok on the premise that if `A: AutoTrait` held, but we indeed
146     /// encountered a problem (later on) with `A: AutoTrait`. So we
147     /// currently set a flag on the stack node for `B: AutoTrait` (as
148     /// well as the second instance of `A: AutoTrait`) to suppress
149     /// caching.
150     ///
151     /// This is a simple, targeted fix. A more-performant fix requires
152     /// deeper changes, but would permit more caching: we could
153     /// basically defer caching until we have fully evaluated the
154     /// tree, and then cache the entire tree at once. In any case, the
155     /// performance impact here shouldn't be so horrible: every time
156     /// this is hit, we do cache at least one trait, so we only
157     /// evaluate each member of a cycle up to N times, where N is the
158     /// length of the cycle. This means the performance impact is
159     /// bounded and we shouldn't have any terrible worst-cases.
160     reached_depth: Cell<usize>,
161 
162     previous: TraitObligationStackList<'prev, 'tcx>,
163 
164     /// The number of parent frames plus one (thus, the topmost frame has depth 1).
165     depth: usize,
166 
167     /// The depth-first number of this node in the search graph -- a
168     /// pre-order index. Basically, a freshly incremented counter.
169     dfn: usize,
170 }
171 
172 struct SelectionCandidateSet<'tcx> {
173     /// A list of candidates that definitely apply to the current
174     /// obligation (meaning: types unify).
175     vec: Vec<SelectionCandidate<'tcx>>,
176 
177     /// If `true`, then there were candidates that might or might
178     /// not have applied, but we couldn't tell. This occurs when some
179     /// of the input types are type variables, in which case there are
180     /// various "builtin" rules that might or might not trigger.
181     ambiguous: bool,
182 }
183 
184 #[derive(PartialEq, Eq, Debug, Clone)]
185 struct EvaluatedCandidate<'tcx> {
186     candidate: SelectionCandidate<'tcx>,
187     evaluation: EvaluationResult,
188 }
189 
190 /// When does the builtin impl for `T: Trait` apply?
191 #[derive(Debug)]
192 enum BuiltinImplConditions<'tcx> {
193     /// The impl is conditional on `T1, T2, ...: Trait`.
194     Where(ty::Binder<'tcx, Vec<Ty<'tcx>>>),
195     /// There is no built-in impl. There may be some other
196     /// candidate (a where-clause or user-defined impl).
197     None,
198     /// It is unknown whether there is an impl.
199     Ambiguous,
200 }
201 
202 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
new(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx>203     pub fn new(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> {
204         SelectionContext {
205             infcx,
206             freshener: infcx.freshener(),
207             intercrate_ambiguity_causes: None,
208             query_mode: TraitQueryMode::Standard,
209         }
210     }
211 
with_query_mode( infcx: &'cx InferCtxt<'tcx>, query_mode: TraitQueryMode, ) -> SelectionContext<'cx, 'tcx>212     pub fn with_query_mode(
213         infcx: &'cx InferCtxt<'tcx>,
214         query_mode: TraitQueryMode,
215     ) -> SelectionContext<'cx, 'tcx> {
216         debug!(?query_mode, "with_query_mode");
217         SelectionContext { query_mode, ..SelectionContext::new(infcx) }
218     }
219 
220     /// Enables tracking of intercrate ambiguity causes. See
221     /// the documentation of [`Self::intercrate_ambiguity_causes`] for more.
enable_tracking_intercrate_ambiguity_causes(&mut self)222     pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
223         assert!(self.is_intercrate());
224         assert!(self.intercrate_ambiguity_causes.is_none());
225         self.intercrate_ambiguity_causes = Some(FxIndexSet::default());
226         debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
227     }
228 
229     /// Gets the intercrate ambiguity causes collected since tracking
230     /// was enabled and disables tracking at the same time. If
231     /// tracking is not enabled, just returns an empty vector.
take_intercrate_ambiguity_causes(&mut self) -> FxIndexSet<IntercrateAmbiguityCause>232     pub fn take_intercrate_ambiguity_causes(&mut self) -> FxIndexSet<IntercrateAmbiguityCause> {
233         assert!(self.is_intercrate());
234         self.intercrate_ambiguity_causes.take().unwrap_or_default()
235     }
236 
tcx(&self) -> TyCtxt<'tcx>237     pub fn tcx(&self) -> TyCtxt<'tcx> {
238         self.infcx.tcx
239     }
240 
is_intercrate(&self) -> bool241     pub fn is_intercrate(&self) -> bool {
242         self.infcx.intercrate
243     }
244 
245     ///////////////////////////////////////////////////////////////////////////
246     // Selection
247     //
248     // The selection phase tries to identify *how* an obligation will
249     // be resolved. For example, it will identify which impl or
250     // parameter bound is to be used. The process can be inconclusive
251     // if the self type in the obligation is not fully inferred. Selection
252     // can result in an error in one of two ways:
253     //
254     // 1. If no applicable impl or parameter bound can be found.
255     // 2. If the output type parameters in the obligation do not match
256     //    those specified by the impl/bound. For example, if the obligation
257     //    is `Vec<Foo>: Iterable<Bar>`, but the impl specifies
258     //    `impl<T> Iterable<T> for Vec<T>`, than an error would result.
259 
260     /// Attempts to satisfy the obligation. If successful, this will affect the surrounding
261     /// type environment by performing unification.
262     #[instrument(level = "debug", skip(self), ret)]
poly_select( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> SelectionResult<'tcx, Selection<'tcx>>263     pub fn poly_select(
264         &mut self,
265         obligation: &PolyTraitObligation<'tcx>,
266     ) -> SelectionResult<'tcx, Selection<'tcx>> {
267         if self.infcx.next_trait_solver() {
268             return self.infcx.select_in_new_trait_solver(obligation);
269         }
270 
271         let candidate = match self.select_from_obligation(obligation) {
272             Err(SelectionError::Overflow(OverflowError::Canonical)) => {
273                 // In standard mode, overflow must have been caught and reported
274                 // earlier.
275                 assert!(self.query_mode == TraitQueryMode::Canonical);
276                 return Err(SelectionError::Overflow(OverflowError::Canonical));
277             }
278             Err(e) => {
279                 return Err(e);
280             }
281             Ok(None) => {
282                 return Ok(None);
283             }
284             Ok(Some(candidate)) => candidate,
285         };
286 
287         match self.confirm_candidate(obligation, candidate) {
288             Err(SelectionError::Overflow(OverflowError::Canonical)) => {
289                 assert!(self.query_mode == TraitQueryMode::Canonical);
290                 Err(SelectionError::Overflow(OverflowError::Canonical))
291             }
292             Err(e) => Err(e),
293             Ok(candidate) => Ok(Some(candidate)),
294         }
295     }
296 
select( &mut self, obligation: &TraitObligation<'tcx>, ) -> SelectionResult<'tcx, Selection<'tcx>>297     pub fn select(
298         &mut self,
299         obligation: &TraitObligation<'tcx>,
300     ) -> SelectionResult<'tcx, Selection<'tcx>> {
301         self.poly_select(&Obligation {
302             cause: obligation.cause.clone(),
303             param_env: obligation.param_env,
304             predicate: ty::Binder::dummy(obligation.predicate),
305             recursion_depth: obligation.recursion_depth,
306         })
307     }
308 
select_from_obligation( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>>309     fn select_from_obligation(
310         &mut self,
311         obligation: &PolyTraitObligation<'tcx>,
312     ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
313         debug_assert!(!obligation.predicate.has_escaping_bound_vars());
314 
315         let pec = &ProvisionalEvaluationCache::default();
316         let stack = self.push_stack(TraitObligationStackList::empty(pec), obligation);
317 
318         self.candidate_from_obligation(&stack)
319     }
320 
321     #[instrument(level = "debug", skip(self), ret)]
candidate_from_obligation<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>>322     fn candidate_from_obligation<'o>(
323         &mut self,
324         stack: &TraitObligationStack<'o, 'tcx>,
325     ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
326         debug_assert!(!self.infcx.next_trait_solver());
327         // Watch out for overflow. This intentionally bypasses (and does
328         // not update) the cache.
329         self.check_recursion_limit(&stack.obligation, &stack.obligation)?;
330 
331         // Check the cache. Note that we freshen the trait-ref
332         // separately rather than using `stack.fresh_trait_ref` --
333         // this is because we want the unbound variables to be
334         // replaced with fresh types starting from index 0.
335         let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate);
336         debug!(?cache_fresh_trait_pred);
337         debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars());
338 
339         if let Some(c) =
340             self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred)
341         {
342             debug!("CACHE HIT");
343             return c;
344         }
345 
346         // If no match, compute result and insert into cache.
347         //
348         // FIXME(nikomatsakis) -- this cache is not taking into
349         // account cycles that may have occurred in forming the
350         // candidate. I don't know of any specific problems that
351         // result but it seems awfully suspicious.
352         let (candidate, dep_node) =
353             self.in_task(|this| this.candidate_from_obligation_no_cache(stack));
354 
355         debug!("CACHE MISS");
356         self.insert_candidate_cache(
357             stack.obligation.param_env,
358             cache_fresh_trait_pred,
359             dep_node,
360             candidate.clone(),
361         );
362         candidate
363     }
364 
candidate_from_obligation_no_cache<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>>365     fn candidate_from_obligation_no_cache<'o>(
366         &mut self,
367         stack: &TraitObligationStack<'o, 'tcx>,
368     ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
369         if let Err(conflict) = self.is_knowable(stack) {
370             debug!("coherence stage: not knowable");
371             if self.intercrate_ambiguity_causes.is_some() {
372                 debug!("evaluate_stack: intercrate_ambiguity_causes is some");
373                 // Heuristics: show the diagnostics when there are no candidates in crate.
374                 if let Ok(candidate_set) = self.assemble_candidates(stack) {
375                     let mut no_candidates_apply = true;
376 
377                     for c in candidate_set.vec.iter() {
378                         if self.evaluate_candidate(stack, &c)?.may_apply() {
379                             no_candidates_apply = false;
380                             break;
381                         }
382                     }
383 
384                     if !candidate_set.ambiguous && no_candidates_apply {
385                         let trait_ref = self.infcx.resolve_vars_if_possible(
386                             stack.obligation.predicate.skip_binder().trait_ref,
387                         );
388                         if !trait_ref.references_error() {
389                             let self_ty = trait_ref.self_ty();
390                             let (trait_desc, self_desc) = with_no_trimmed_paths!({
391                                 let trait_desc = trait_ref.print_only_trait_path().to_string();
392                                 let self_desc =
393                                     self_ty.has_concrete_skeleton().then(|| self_ty.to_string());
394                                 (trait_desc, self_desc)
395                             });
396                             let cause = if let Conflict::Upstream = conflict {
397                                 IntercrateAmbiguityCause::UpstreamCrateUpdate {
398                                     trait_desc,
399                                     self_desc,
400                                 }
401                             } else {
402                                 IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
403                             };
404                             debug!(?cause, "evaluate_stack: pushing cause");
405                             self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause);
406                         }
407                     }
408                 }
409             }
410             return Ok(None);
411         }
412 
413         let candidate_set = self.assemble_candidates(stack)?;
414 
415         if candidate_set.ambiguous {
416             debug!("candidate set contains ambig");
417             return Ok(None);
418         }
419 
420         let candidates = candidate_set.vec;
421 
422         debug!(?stack, ?candidates, "assembled {} candidates", candidates.len());
423 
424         // At this point, we know that each of the entries in the
425         // candidate set is *individually* applicable. Now we have to
426         // figure out if they contain mutual incompatibilities. This
427         // frequently arises if we have an unconstrained input type --
428         // for example, we are looking for `$0: Eq` where `$0` is some
429         // unconstrained type variable. In that case, we'll get a
430         // candidate which assumes $0 == int, one that assumes `$0 ==
431         // usize`, etc. This spells an ambiguity.
432 
433         let mut candidates = self.filter_impls(candidates, stack.obligation);
434 
435         // If there is more than one candidate, first winnow them down
436         // by considering extra conditions (nested obligations and so
437         // forth). We don't winnow if there is exactly one
438         // candidate. This is a relatively minor distinction but it
439         // can lead to better inference and error-reporting. An
440         // example would be if there was an impl:
441         //
442         //     impl<T:Clone> Vec<T> { fn push_clone(...) { ... } }
443         //
444         // and we were to see some code `foo.push_clone()` where `boo`
445         // is a `Vec<Bar>` and `Bar` does not implement `Clone`. If
446         // we were to winnow, we'd wind up with zero candidates.
447         // Instead, we select the right impl now but report "`Bar` does
448         // not implement `Clone`".
449         if candidates.len() == 1 {
450             return self.filter_reservation_impls(candidates.pop().unwrap(), stack.obligation);
451         }
452 
453         // Winnow, but record the exact outcome of evaluation, which
454         // is needed for specialization. Propagate overflow if it occurs.
455         let mut candidates = candidates
456             .into_iter()
457             .map(|c| match self.evaluate_candidate(stack, &c) {
458                 Ok(eval) if eval.may_apply() => {
459                     Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
460                 }
461                 Ok(_) => Ok(None),
462                 Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)),
463                 Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
464                 Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))),
465             })
466             .flat_map(Result::transpose)
467             .collect::<Result<Vec<_>, _>>()?;
468 
469         debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len());
470 
471         let has_non_region_infer = stack.obligation.predicate.has_non_region_infer();
472 
473         // If there are STILL multiple candidates, we can further
474         // reduce the list by dropping duplicates -- including
475         // resolving specializations.
476         if candidates.len() > 1 {
477             let mut i = 0;
478             while i < candidates.len() {
479                 let should_drop_i = (0..candidates.len()).filter(|&j| i != j).any(|j| {
480                     self.candidate_should_be_dropped_in_favor_of(
481                         &candidates[i],
482                         &candidates[j],
483                         has_non_region_infer,
484                     ) == DropVictim::Yes
485                 });
486                 if should_drop_i {
487                     debug!(candidate = ?candidates[i], "Dropping candidate #{}/{}", i, candidates.len());
488                     candidates.swap_remove(i);
489                 } else {
490                     debug!(candidate = ?candidates[i], "Retaining candidate #{}/{}", i, candidates.len());
491                     i += 1;
492 
493                     // If there are *STILL* multiple candidates, give up
494                     // and report ambiguity.
495                     if i > 1 {
496                         debug!("multiple matches, ambig");
497                         return Ok(None);
498                     }
499                 }
500             }
501         }
502 
503         // If there are *NO* candidates, then there are no impls --
504         // that we know of, anyway. Note that in the case where there
505         // are unbound type variables within the obligation, it might
506         // be the case that you could still satisfy the obligation
507         // from another crate by instantiating the type variables with
508         // a type from another crate that does have an impl. This case
509         // is checked for in `evaluate_stack` (and hence users
510         // who might care about this case, like coherence, should use
511         // that function).
512         if candidates.is_empty() {
513             // If there's an error type, 'downgrade' our result from
514             // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid
515             // emitting additional spurious errors, since we're guaranteed
516             // to have emitted at least one.
517             if stack.obligation.predicate.references_error() {
518                 debug!(?stack.obligation.predicate, "found error type in predicate, treating as ambiguous");
519                 return Ok(None);
520             }
521             return Err(Unimplemented);
522         }
523 
524         // Just one candidate left.
525         self.filter_reservation_impls(candidates.pop().unwrap().candidate, stack.obligation)
526     }
527 
528     ///////////////////////////////////////////////////////////////////////////
529     // EVALUATION
530     //
531     // Tests whether an obligation can be selected or whether an impl
532     // can be applied to particular types. It skips the "confirmation"
533     // step and hence completely ignores output type parameters.
534     //
535     // The result is "true" if the obligation *may* hold and "false" if
536     // we can be sure it does not.
537 
538     /// Evaluates whether the obligation `obligation` can be satisfied
539     /// and returns an `EvaluationResult`. This is meant for the
540     /// *initial* call.
541     ///
542     /// Do not use this directly, use `infcx.evaluate_obligation` instead.
evaluate_root_obligation( &mut self, obligation: &PredicateObligation<'tcx>, ) -> Result<EvaluationResult, OverflowError>543     pub fn evaluate_root_obligation(
544         &mut self,
545         obligation: &PredicateObligation<'tcx>,
546     ) -> Result<EvaluationResult, OverflowError> {
547         debug_assert!(!self.infcx.next_trait_solver());
548         self.evaluation_probe(|this| {
549             let goal =
550                 this.infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env));
551             let mut result = this.evaluate_predicate_recursively(
552                 TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
553                 obligation.clone(),
554             )?;
555             // If the predicate has done any inference, then downgrade the
556             // result to ambiguous.
557             if this.infcx.shallow_resolve(goal) != goal {
558                 result = result.max(EvaluatedToAmbig);
559             }
560             Ok(result)
561         })
562     }
563 
evaluation_probe( &mut self, op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>, ) -> Result<EvaluationResult, OverflowError>564     fn evaluation_probe(
565         &mut self,
566         op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>,
567     ) -> Result<EvaluationResult, OverflowError> {
568         self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
569             let outer_universe = self.infcx.universe();
570             let result = op(self)?;
571 
572             match self.infcx.leak_check(outer_universe, Some(snapshot)) {
573                 Ok(()) => {}
574                 Err(_) => return Ok(EvaluatedToErr),
575             }
576 
577             if self.infcx.opaque_types_added_in_snapshot(snapshot) {
578                 return Ok(result.max(EvaluatedToOkModuloOpaqueTypes));
579             }
580 
581             if self.infcx.region_constraints_added_in_snapshot(snapshot) {
582                 Ok(result.max(EvaluatedToOkModuloRegions))
583             } else {
584                 Ok(result)
585             }
586         })
587     }
588 
589     /// Evaluates the predicates in `predicates` recursively. Note that
590     /// this applies projections in the predicates, and therefore
591     /// is run within an inference probe.
592     #[instrument(skip(self, stack), level = "debug")]
evaluate_predicates_recursively<'o, I>( &mut self, stack: TraitObligationStackList<'o, 'tcx>, predicates: I, ) -> Result<EvaluationResult, OverflowError> where I: IntoIterator<Item = PredicateObligation<'tcx>> + std::fmt::Debug,593     fn evaluate_predicates_recursively<'o, I>(
594         &mut self,
595         stack: TraitObligationStackList<'o, 'tcx>,
596         predicates: I,
597     ) -> Result<EvaluationResult, OverflowError>
598     where
599         I: IntoIterator<Item = PredicateObligation<'tcx>> + std::fmt::Debug,
600     {
601         let mut result = EvaluatedToOk;
602         for mut obligation in predicates {
603             obligation.set_depth_from_parent(stack.depth());
604             let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?;
605             if let EvaluatedToErr = eval {
606                 // fast-path - EvaluatedToErr is the top of the lattice,
607                 // so we don't need to look on the other predicates.
608                 return Ok(EvaluatedToErr);
609             } else {
610                 result = cmp::max(result, eval);
611             }
612         }
613         Ok(result)
614     }
615 
616     #[instrument(
617         level = "debug",
618         skip(self, previous_stack),
619         fields(previous_stack = ?previous_stack.head())
620         ret,
621     )]
evaluate_predicate_recursively<'o>( &mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: PredicateObligation<'tcx>, ) -> Result<EvaluationResult, OverflowError>622     fn evaluate_predicate_recursively<'o>(
623         &mut self,
624         previous_stack: TraitObligationStackList<'o, 'tcx>,
625         obligation: PredicateObligation<'tcx>,
626     ) -> Result<EvaluationResult, OverflowError> {
627         debug_assert!(!self.infcx.next_trait_solver());
628         // `previous_stack` stores a `PolyTraitObligation`, while `obligation` is
629         // a `PredicateObligation`. These are distinct types, so we can't
630         // use any `Option` combinator method that would force them to be
631         // the same.
632         match previous_stack.head() {
633             Some(h) => self.check_recursion_limit(&obligation, h.obligation)?,
634             None => self.check_recursion_limit(&obligation, &obligation)?,
635         }
636 
637         ensure_sufficient_stack(|| {
638             let bound_predicate = obligation.predicate.kind();
639             match bound_predicate.skip_binder() {
640                 ty::PredicateKind::Clause(ty::ClauseKind::Trait(t)) => {
641                     let t = bound_predicate.rebind(t);
642                     debug_assert!(!t.has_escaping_bound_vars());
643                     let obligation = obligation.with(self.tcx(), t);
644                     self.evaluate_trait_predicate_recursively(previous_stack, obligation)
645                 }
646 
647                 ty::PredicateKind::Subtype(p) => {
648                     let p = bound_predicate.rebind(p);
649                     // Does this code ever run?
650                     match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
651                         Ok(Ok(InferOk { obligations, .. })) => {
652                             self.evaluate_predicates_recursively(previous_stack, obligations)
653                         }
654                         Ok(Err(_)) => Ok(EvaluatedToErr),
655                         Err(..) => Ok(EvaluatedToAmbig),
656                     }
657                 }
658 
659                 ty::PredicateKind::Coerce(p) => {
660                     let p = bound_predicate.rebind(p);
661                     // Does this code ever run?
662                     match self.infcx.coerce_predicate(&obligation.cause, obligation.param_env, p) {
663                         Ok(Ok(InferOk { obligations, .. })) => {
664                             self.evaluate_predicates_recursively(previous_stack, obligations)
665                         }
666                         Ok(Err(_)) => Ok(EvaluatedToErr),
667                         Err(..) => Ok(EvaluatedToAmbig),
668                     }
669                 }
670 
671                 ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
672                     // So, there is a bit going on here. First, `WellFormed` predicates
673                     // are coinductive, like trait predicates with auto traits.
674                     // This means that we need to detect if we have recursively
675                     // evaluated `WellFormed(X)`. Otherwise, we would run into
676                     // a "natural" overflow error.
677                     //
678                     // Now, the next question is whether we need to do anything
679                     // special with caching. Considering the following tree:
680                     // - `WF(Foo<T>)`
681                     //   - `Bar<T>: Send`
682                     //     - `WF(Foo<T>)`
683                     //   - `Foo<T>: Trait`
684                     // In this case, the innermost `WF(Foo<T>)` should return
685                     // `EvaluatedToOk`, since it's coinductive. Then if
686                     // `Bar<T>: Send` is resolved to `EvaluatedToOk`, it can be
687                     // inserted into a cache (because without thinking about `WF`
688                     // goals, it isn't in a cycle). If `Foo<T>: Trait` later doesn't
689                     // hold, then `Bar<T>: Send` shouldn't hold. Therefore, we
690                     // *do* need to keep track of coinductive cycles.
691 
692                     let cache = previous_stack.cache;
693                     let dfn = cache.next_dfn();
694 
695                     for stack_arg in previous_stack.cache.wf_args.borrow().iter().rev() {
696                         if stack_arg.0 != arg {
697                             continue;
698                         }
699                         debug!("WellFormed({:?}) on stack", arg);
700                         if let Some(stack) = previous_stack.head {
701                             // Okay, let's imagine we have two different stacks:
702                             //   `T: NonAutoTrait -> WF(T) -> T: NonAutoTrait`
703                             //   `WF(T) -> T: NonAutoTrait -> WF(T)`
704                             // Because of this, we need to check that all
705                             // predicates between the WF goals are coinductive.
706                             // Otherwise, we can say that `T: NonAutoTrait` is
707                             // true.
708                             // Let's imagine we have a predicate stack like
709                             //         `Foo: Bar -> WF(T) -> T: NonAutoTrait -> T: Auto`
710                             // depth   ^1                    ^2                 ^3
711                             // and the current predicate is `WF(T)`. `wf_args`
712                             // would contain `(T, 1)`. We want to check all
713                             // trait predicates greater than `1`. The previous
714                             // stack would be `T: Auto`.
715                             let cycle = stack.iter().take_while(|s| s.depth > stack_arg.1);
716                             let tcx = self.tcx();
717                             let cycle =
718                                 cycle.map(|stack| stack.obligation.predicate.to_predicate(tcx));
719                             if self.coinductive_match(cycle) {
720                                 stack.update_reached_depth(stack_arg.1);
721                                 return Ok(EvaluatedToOk);
722                             } else {
723                                 return Ok(EvaluatedToRecur);
724                             }
725                         }
726                         return Ok(EvaluatedToOk);
727                     }
728 
729                     match wf::obligations(
730                         self.infcx,
731                         obligation.param_env,
732                         obligation.cause.body_id,
733                         obligation.recursion_depth + 1,
734                         arg,
735                         obligation.cause.span,
736                     ) {
737                         Some(obligations) => {
738                             cache.wf_args.borrow_mut().push((arg, previous_stack.depth()));
739                             let result =
740                                 self.evaluate_predicates_recursively(previous_stack, obligations);
741                             cache.wf_args.borrow_mut().pop();
742 
743                             let result = result?;
744 
745                             if !result.must_apply_modulo_regions() {
746                                 cache.on_failure(dfn);
747                             }
748 
749                             cache.on_completion(dfn);
750 
751                             Ok(result)
752                         }
753                         None => Ok(EvaluatedToAmbig),
754                     }
755                 }
756 
757                 ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(pred)) => {
758                     // A global type with no free lifetimes or generic parameters
759                     // outlives anything.
760                     if pred.0.has_free_regions()
761                         || pred.0.has_late_bound_regions()
762                         || pred.0.has_non_region_infer()
763                         || pred.0.has_non_region_infer()
764                     {
765                         Ok(EvaluatedToOkModuloRegions)
766                     } else {
767                         Ok(EvaluatedToOk)
768                     }
769                 }
770 
771                 ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) => {
772                     // We do not consider region relationships when evaluating trait matches.
773                     Ok(EvaluatedToOkModuloRegions)
774                 }
775 
776                 ty::PredicateKind::ObjectSafe(trait_def_id) => {
777                     if self.tcx().check_is_object_safe(trait_def_id) {
778                         Ok(EvaluatedToOk)
779                     } else {
780                         Ok(EvaluatedToErr)
781                     }
782                 }
783 
784                 ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
785                     let data = bound_predicate.rebind(data);
786                     let project_obligation = obligation.with(self.tcx(), data);
787                     match project::poly_project_and_unify_type(self, &project_obligation) {
788                         ProjectAndUnifyResult::Holds(mut subobligations) => {
789                             'compute_res: {
790                                 // If we've previously marked this projection as 'complete', then
791                                 // use the final cached result (either `EvaluatedToOk` or
792                                 // `EvaluatedToOkModuloRegions`), and skip re-evaluating the
793                                 // sub-obligations.
794                                 if let Some(key) =
795                                     ProjectionCacheKey::from_poly_projection_predicate(self, data)
796                                 {
797                                     if let Some(cached_res) = self
798                                         .infcx
799                                         .inner
800                                         .borrow_mut()
801                                         .projection_cache()
802                                         .is_complete(key)
803                                     {
804                                         break 'compute_res Ok(cached_res);
805                                     }
806                                 }
807 
808                                 // Need to explicitly set the depth of nested goals here as
809                                 // projection obligations can cycle by themselves and in
810                                 // `evaluate_predicates_recursively` we only add the depth
811                                 // for parent trait goals because only these get added to the
812                                 // `TraitObligationStackList`.
813                                 for subobligation in subobligations.iter_mut() {
814                                     subobligation.set_depth_from_parent(obligation.recursion_depth);
815                                 }
816                                 let res = self.evaluate_predicates_recursively(
817                                     previous_stack,
818                                     subobligations,
819                                 );
820                                 if let Ok(eval_rslt) = res
821                                     && (eval_rslt == EvaluatedToOk || eval_rslt == EvaluatedToOkModuloRegions)
822                                     && let Some(key) =
823                                         ProjectionCacheKey::from_poly_projection_predicate(
824                                             self, data,
825                                         )
826                                 {
827                                     // If the result is something that we can cache, then mark this
828                                     // entry as 'complete'. This will allow us to skip evaluating the
829                                     // subobligations at all the next time we evaluate the projection
830                                     // predicate.
831                                     self.infcx
832                                         .inner
833                                         .borrow_mut()
834                                         .projection_cache()
835                                         .complete(key, eval_rslt);
836                                 }
837                                 res
838                             }
839                         }
840                         ProjectAndUnifyResult::FailedNormalization => Ok(EvaluatedToAmbig),
841                         ProjectAndUnifyResult::Recursive => Ok(EvaluatedToRecur),
842                         ProjectAndUnifyResult::MismatchedProjectionTypes(_) => Ok(EvaluatedToErr),
843                     }
844                 }
845 
846                 ty::PredicateKind::ClosureKind(_, closure_substs, kind) => {
847                     match self.infcx.closure_kind(closure_substs) {
848                         Some(closure_kind) => {
849                             if closure_kind.extends(kind) {
850                                 Ok(EvaluatedToOk)
851                             } else {
852                                 Ok(EvaluatedToErr)
853                             }
854                         }
855                         None => Ok(EvaluatedToAmbig),
856                     }
857                 }
858 
859                 ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(uv)) => {
860                     match const_evaluatable::is_const_evaluatable(
861                         self.infcx,
862                         uv,
863                         obligation.param_env,
864                         obligation.cause.span,
865                     ) {
866                         Ok(()) => Ok(EvaluatedToOk),
867                         Err(NotConstEvaluatable::MentionsInfer) => Ok(EvaluatedToAmbig),
868                         Err(NotConstEvaluatable::MentionsParam) => Ok(EvaluatedToErr),
869                         Err(_) => Ok(EvaluatedToErr),
870                     }
871                 }
872 
873                 ty::PredicateKind::ConstEquate(c1, c2) => {
874                     let tcx = self.tcx();
875                     assert!(
876                         tcx.features().generic_const_exprs,
877                         "`ConstEquate` without a feature gate: {c1:?} {c2:?}",
878                     );
879 
880                     {
881                         let c1 = tcx.expand_abstract_consts(c1);
882                         let c2 = tcx.expand_abstract_consts(c2);
883                         debug!(
884                             "evaluate_predicate_recursively: equating consts:\nc1= {:?}\nc2= {:?}",
885                             c1, c2
886                         );
887 
888                         use rustc_hir::def::DefKind;
889                         use ty::Unevaluated;
890                         match (c1.kind(), c2.kind()) {
891                             (Unevaluated(a), Unevaluated(b))
892                                 if a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst =>
893                             {
894                                 if let Ok(InferOk { obligations, value: () }) = self
895                                     .infcx
896                                     .at(&obligation.cause, obligation.param_env)
897                                     .trace(c1, c2)
898                                     .eq(DefineOpaqueTypes::No, a.substs, b.substs)
899                                 {
900                                     return self.evaluate_predicates_recursively(
901                                         previous_stack,
902                                         obligations,
903                                     );
904                                 }
905                             }
906                             (_, Unevaluated(_)) | (Unevaluated(_), _) => (),
907                             (_, _) => {
908                                 if let Ok(InferOk { obligations, value: () }) = self
909                                     .infcx
910                                     .at(&obligation.cause, obligation.param_env)
911                                     .eq(DefineOpaqueTypes::No, c1, c2)
912                                 {
913                                     return self.evaluate_predicates_recursively(
914                                         previous_stack,
915                                         obligations,
916                                     );
917                                 }
918                             }
919                         }
920                     }
921 
922                     let evaluate = |c: ty::Const<'tcx>| {
923                         if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
924                             match self.infcx.try_const_eval_resolve(
925                                 obligation.param_env,
926                                 unevaluated,
927                                 c.ty(),
928                                 Some(obligation.cause.span),
929                             ) {
930                                 Ok(val) => Ok(val),
931                                 Err(e) => Err(e),
932                             }
933                         } else {
934                             Ok(c)
935                         }
936                     };
937 
938                     match (evaluate(c1), evaluate(c2)) {
939                         (Ok(c1), Ok(c2)) => {
940                             match self.infcx.at(&obligation.cause, obligation.param_env).eq(
941                                 DefineOpaqueTypes::No,
942                                 c1,
943                                 c2,
944                             ) {
945                                 Ok(inf_ok) => self.evaluate_predicates_recursively(
946                                     previous_stack,
947                                     inf_ok.into_obligations(),
948                                 ),
949                                 Err(_) => Ok(EvaluatedToErr),
950                             }
951                         }
952                         (Err(ErrorHandled::Reported(_)), _)
953                         | (_, Err(ErrorHandled::Reported(_))) => Ok(EvaluatedToErr),
954                         (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => {
955                             if c1.has_non_region_infer() || c2.has_non_region_infer() {
956                                 Ok(EvaluatedToAmbig)
957                             } else {
958                                 // Two different constants using generic parameters ~> error.
959                                 Ok(EvaluatedToErr)
960                             }
961                         }
962                     }
963                 }
964                 ty::PredicateKind::AliasRelate(..) => {
965                     bug!("AliasRelate is only used for new solver")
966                 }
967                 ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
968                 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
969                     match self.infcx.at(&obligation.cause, obligation.param_env).eq(
970                         DefineOpaqueTypes::No,
971                         ct.ty(),
972                         ty,
973                     ) {
974                         Ok(inf_ok) => self.evaluate_predicates_recursively(
975                             previous_stack,
976                             inf_ok.into_obligations(),
977                         ),
978                         Err(_) => Ok(EvaluatedToErr),
979                     }
980                 }
981             }
982         })
983     }
984 
985     #[instrument(skip(self, previous_stack), level = "debug", ret)]
evaluate_trait_predicate_recursively<'o>( &mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, mut obligation: PolyTraitObligation<'tcx>, ) -> Result<EvaluationResult, OverflowError>986     fn evaluate_trait_predicate_recursively<'o>(
987         &mut self,
988         previous_stack: TraitObligationStackList<'o, 'tcx>,
989         mut obligation: PolyTraitObligation<'tcx>,
990     ) -> Result<EvaluationResult, OverflowError> {
991         if !self.is_intercrate()
992             && obligation.is_global()
993             && obligation.param_env.caller_bounds().iter().all(|bound| bound.has_param())
994         {
995             // If a param env has no global bounds, global obligations do not
996             // depend on its particular value in order to work, so we can clear
997             // out the param env and get better caching.
998             debug!("in global");
999             obligation.param_env = obligation.param_env.without_caller_bounds();
1000         }
1001 
1002         let stack = self.push_stack(previous_stack, &obligation);
1003         let mut fresh_trait_pred = stack.fresh_trait_pred;
1004         let mut param_env = obligation.param_env;
1005 
1006         fresh_trait_pred = fresh_trait_pred.map_bound(|mut pred| {
1007             pred.remap_constness(&mut param_env);
1008             pred
1009         });
1010 
1011         debug!(?fresh_trait_pred);
1012 
1013         // If a trait predicate is in the (local or global) evaluation cache,
1014         // then we know it holds without cycles.
1015         if let Some(result) = self.check_evaluation_cache(param_env, fresh_trait_pred) {
1016             debug!("CACHE HIT");
1017             return Ok(result);
1018         }
1019 
1020         if let Some(result) = stack.cache().get_provisional(fresh_trait_pred) {
1021             debug!("PROVISIONAL CACHE HIT");
1022             stack.update_reached_depth(result.reached_depth);
1023             return Ok(result.result);
1024         }
1025 
1026         // Check if this is a match for something already on the
1027         // stack. If so, we don't want to insert the result into the
1028         // main cache (it is cycle dependent) nor the provisional
1029         // cache (which is meant for things that have completed but
1030         // for a "backedge" -- this result *is* the backedge).
1031         if let Some(cycle_result) = self.check_evaluation_cycle(&stack) {
1032             return Ok(cycle_result);
1033         }
1034 
1035         let (result, dep_node) = self.in_task(|this| {
1036             let mut result = this.evaluate_stack(&stack)?;
1037 
1038             // fix issue #103563, we don't normalize
1039             // nested obligations which produced by `TraitDef` candidate
1040             // (i.e. using bounds on assoc items as assumptions).
1041             // because we don't have enough information to
1042             // normalize these obligations before evaluating.
1043             // so we will try to normalize the obligation and evaluate again.
1044             // we will replace it with new solver in the future.
1045             if EvaluationResult::EvaluatedToErr == result
1046                 && fresh_trait_pred.has_projections()
1047                 && fresh_trait_pred.is_global()
1048             {
1049                 let mut nested_obligations = Vec::new();
1050                 let predicate = try_normalize_with_depth_to(
1051                     this,
1052                     param_env,
1053                     obligation.cause.clone(),
1054                     obligation.recursion_depth + 1,
1055                     obligation.predicate,
1056                     &mut nested_obligations,
1057                 );
1058                 if predicate != obligation.predicate {
1059                     let mut nested_result = EvaluationResult::EvaluatedToOk;
1060                     for obligation in nested_obligations {
1061                         nested_result = cmp::max(
1062                             this.evaluate_predicate_recursively(previous_stack, obligation)?,
1063                             nested_result,
1064                         );
1065                     }
1066 
1067                     if nested_result.must_apply_modulo_regions() {
1068                         let obligation = obligation.with(this.tcx(), predicate);
1069                         result = cmp::max(
1070                             nested_result,
1071                             this.evaluate_trait_predicate_recursively(previous_stack, obligation)?,
1072                         );
1073                     }
1074                 }
1075             }
1076 
1077             Ok::<_, OverflowError>(result)
1078         });
1079 
1080         let result = result?;
1081 
1082         if !result.must_apply_modulo_regions() {
1083             stack.cache().on_failure(stack.dfn);
1084         }
1085 
1086         let reached_depth = stack.reached_depth.get();
1087         if reached_depth >= stack.depth {
1088             debug!("CACHE MISS");
1089             self.insert_evaluation_cache(param_env, fresh_trait_pred, dep_node, result);
1090             stack.cache().on_completion(stack.dfn);
1091         } else {
1092             debug!("PROVISIONAL");
1093             debug!(
1094                 "caching provisionally because {:?} \
1095                  is a cycle participant (at depth {}, reached depth {})",
1096                 fresh_trait_pred, stack.depth, reached_depth,
1097             );
1098 
1099             stack.cache().insert_provisional(stack.dfn, reached_depth, fresh_trait_pred, result);
1100         }
1101 
1102         Ok(result)
1103     }
1104 
1105     /// If there is any previous entry on the stack that precisely
1106     /// matches this obligation, then we can assume that the
1107     /// obligation is satisfied for now (still all other conditions
1108     /// must be met of course). One obvious case this comes up is
1109     /// marker traits like `Send`. Think of a linked list:
1110     ///
1111     ///     struct List<T> { data: T, next: Option<Box<List<T>>> }
1112     ///
1113     /// `Box<List<T>>` will be `Send` if `T` is `Send` and
1114     /// `Option<Box<List<T>>>` is `Send`, and in turn
1115     /// `Option<Box<List<T>>>` is `Send` if `Box<List<T>>` is
1116     /// `Send`.
1117     ///
1118     /// Note that we do this comparison using the `fresh_trait_ref`
1119     /// fields. Because these have all been freshened using
1120     /// `self.freshener`, we can be sure that (a) this will not
1121     /// affect the inferencer state and (b) that if we see two
1122     /// fresh regions with the same index, they refer to the same
1123     /// unbound type variable.
check_evaluation_cycle( &mut self, stack: &TraitObligationStack<'_, 'tcx>, ) -> Option<EvaluationResult>1124     fn check_evaluation_cycle(
1125         &mut self,
1126         stack: &TraitObligationStack<'_, 'tcx>,
1127     ) -> Option<EvaluationResult> {
1128         if let Some(cycle_depth) = stack
1129             .iter()
1130             .skip(1) // Skip top-most frame.
1131             .find(|prev| {
1132                 stack.obligation.param_env == prev.obligation.param_env
1133                     && stack.fresh_trait_pred == prev.fresh_trait_pred
1134             })
1135             .map(|stack| stack.depth)
1136         {
1137             debug!("evaluate_stack --> recursive at depth {}", cycle_depth);
1138 
1139             // If we have a stack like `A B C D E A`, where the top of
1140             // the stack is the final `A`, then this will iterate over
1141             // `A, E, D, C, B` -- i.e., all the participants apart
1142             // from the cycle head. We mark them as participating in a
1143             // cycle. This suppresses caching for those nodes. See
1144             // `in_cycle` field for more details.
1145             stack.update_reached_depth(cycle_depth);
1146 
1147             // Subtle: when checking for a coinductive cycle, we do
1148             // not compare using the "freshened trait refs" (which
1149             // have erased regions) but rather the fully explicit
1150             // trait refs. This is important because it's only a cycle
1151             // if the regions match exactly.
1152             let cycle = stack.iter().skip(1).take_while(|s| s.depth >= cycle_depth);
1153             let tcx = self.tcx();
1154             let cycle = cycle.map(|stack| stack.obligation.predicate.to_predicate(tcx));
1155             if self.coinductive_match(cycle) {
1156                 debug!("evaluate_stack --> recursive, coinductive");
1157                 Some(EvaluatedToOk)
1158             } else {
1159                 debug!("evaluate_stack --> recursive, inductive");
1160                 Some(EvaluatedToRecur)
1161             }
1162         } else {
1163             None
1164         }
1165     }
1166 
evaluate_stack<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> Result<EvaluationResult, OverflowError>1167     fn evaluate_stack<'o>(
1168         &mut self,
1169         stack: &TraitObligationStack<'o, 'tcx>,
1170     ) -> Result<EvaluationResult, OverflowError> {
1171         debug_assert!(!self.infcx.next_trait_solver());
1172         // In intercrate mode, whenever any of the generics are unbound,
1173         // there can always be an impl. Even if there are no impls in
1174         // this crate, perhaps the type would be unified with
1175         // something from another crate that does provide an impl.
1176         //
1177         // In intra mode, we must still be conservative. The reason is
1178         // that we want to avoid cycles. Imagine an impl like:
1179         //
1180         //     impl<T:Eq> Eq for Vec<T>
1181         //
1182         // and a trait reference like `$0 : Eq` where `$0` is an
1183         // unbound variable. When we evaluate this trait-reference, we
1184         // will unify `$0` with `Vec<$1>` (for some fresh variable
1185         // `$1`), on the condition that `$1 : Eq`. We will then wind
1186         // up with many candidates (since that are other `Eq` impls
1187         // that apply) and try to winnow things down. This results in
1188         // a recursive evaluation that `$1 : Eq` -- as you can
1189         // imagine, this is just where we started. To avoid that, we
1190         // check for unbound variables and return an ambiguous (hence possible)
1191         // match if we've seen this trait before.
1192         //
1193         // This suffices to allow chains like `FnMut` implemented in
1194         // terms of `Fn` etc, but we could probably make this more
1195         // precise still.
1196         let unbound_input_types =
1197             stack.fresh_trait_pred.skip_binder().trait_ref.substs.types().any(|ty| ty.is_fresh());
1198 
1199         if unbound_input_types
1200             && stack.iter().skip(1).any(|prev| {
1201                 stack.obligation.param_env == prev.obligation.param_env
1202                     && self.match_fresh_trait_refs(
1203                         stack.fresh_trait_pred,
1204                         prev.fresh_trait_pred,
1205                         prev.obligation.param_env,
1206                     )
1207             })
1208         {
1209             debug!("evaluate_stack --> unbound argument, recursive --> giving up",);
1210             return Ok(EvaluatedToUnknown);
1211         }
1212 
1213         match self.candidate_from_obligation(stack) {
1214             Ok(Some(c)) => self.evaluate_candidate(stack, &c),
1215             Ok(None) => Ok(EvaluatedToAmbig),
1216             Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
1217             Err(ErrorReporting) => Err(OverflowError::ErrorReporting),
1218             Err(..) => Ok(EvaluatedToErr),
1219         }
1220     }
1221 
1222     /// For defaulted traits, we use a co-inductive strategy to solve, so
1223     /// that recursion is ok. This routine returns `true` if the top of the
1224     /// stack (`cycle[0]`):
1225     ///
1226     /// - is a defaulted trait,
1227     /// - it also appears in the backtrace at some position `X`,
1228     /// - all the predicates at positions `X..` between `X` and the top are
1229     ///   also defaulted traits.
coinductive_match<I>(&mut self, mut cycle: I) -> bool where I: Iterator<Item = ty::Predicate<'tcx>>,1230     pub(crate) fn coinductive_match<I>(&mut self, mut cycle: I) -> bool
1231     where
1232         I: Iterator<Item = ty::Predicate<'tcx>>,
1233     {
1234         cycle.all(|predicate| predicate.is_coinductive(self.tcx()))
1235     }
1236 
1237     /// Further evaluates `candidate` to decide whether all type parameters match and whether nested
1238     /// obligations are met. Returns whether `candidate` remains viable after this further
1239     /// scrutiny.
1240     #[instrument(
1241         level = "debug",
1242         skip(self, stack),
1243         fields(depth = stack.obligation.recursion_depth),
1244         ret
1245     )]
evaluate_candidate<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, candidate: &SelectionCandidate<'tcx>, ) -> Result<EvaluationResult, OverflowError>1246     fn evaluate_candidate<'o>(
1247         &mut self,
1248         stack: &TraitObligationStack<'o, 'tcx>,
1249         candidate: &SelectionCandidate<'tcx>,
1250     ) -> Result<EvaluationResult, OverflowError> {
1251         let mut result = self.evaluation_probe(|this| {
1252             let candidate = (*candidate).clone();
1253             match this.confirm_candidate(stack.obligation, candidate) {
1254                 Ok(selection) => {
1255                     debug!(?selection);
1256                     this.evaluate_predicates_recursively(
1257                         stack.list(),
1258                         selection.nested_obligations().into_iter(),
1259                     )
1260                 }
1261                 Err(..) => Ok(EvaluatedToErr),
1262             }
1263         })?;
1264 
1265         // If we erased any lifetimes, then we want to use
1266         // `EvaluatedToOkModuloRegions` instead of `EvaluatedToOk`
1267         // as your final result. The result will be cached using
1268         // the freshened trait predicate as a key, so we need
1269         // our result to be correct by *any* choice of original lifetimes,
1270         // not just the lifetime choice for this particular (non-erased)
1271         // predicate.
1272         // See issue #80691
1273         if stack.fresh_trait_pred.has_erased_regions() {
1274             result = result.max(EvaluatedToOkModuloRegions);
1275         }
1276 
1277         Ok(result)
1278     }
1279 
check_evaluation_cache( &self, param_env: ty::ParamEnv<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> Option<EvaluationResult>1280     fn check_evaluation_cache(
1281         &self,
1282         param_env: ty::ParamEnv<'tcx>,
1283         trait_pred: ty::PolyTraitPredicate<'tcx>,
1284     ) -> Option<EvaluationResult> {
1285         // Neither the global nor local cache is aware of intercrate
1286         // mode, so don't do any caching. In particular, we might
1287         // re-use the same `InferCtxt` with both an intercrate
1288         // and non-intercrate `SelectionContext`
1289         if self.is_intercrate() {
1290             return None;
1291         }
1292 
1293         let tcx = self.tcx();
1294         if self.can_use_global_caches(param_env) {
1295             if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) {
1296                 return Some(res);
1297             }
1298         }
1299         self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx)
1300     }
1301 
insert_evaluation_cache( &mut self, param_env: ty::ParamEnv<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>, dep_node: DepNodeIndex, result: EvaluationResult, )1302     fn insert_evaluation_cache(
1303         &mut self,
1304         param_env: ty::ParamEnv<'tcx>,
1305         trait_pred: ty::PolyTraitPredicate<'tcx>,
1306         dep_node: DepNodeIndex,
1307         result: EvaluationResult,
1308     ) {
1309         // Avoid caching results that depend on more than just the trait-ref
1310         // - the stack can create recursion.
1311         if result.is_stack_dependent() {
1312             return;
1313         }
1314 
1315         // Neither the global nor local cache is aware of intercrate
1316         // mode, so don't do any caching. In particular, we might
1317         // re-use the same `InferCtxt` with both an intercrate
1318         // and non-intercrate `SelectionContext`
1319         if self.is_intercrate() {
1320             return;
1321         }
1322 
1323         if self.can_use_global_caches(param_env) {
1324             if !trait_pred.has_infer() {
1325                 debug!(?trait_pred, ?result, "insert_evaluation_cache global");
1326                 // This may overwrite the cache with the same value
1327                 // FIXME: Due to #50507 this overwrites the different values
1328                 // This should be changed to use HashMapExt::insert_same
1329                 // when that is fixed
1330                 self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result);
1331                 return;
1332             }
1333         }
1334 
1335         debug!(?trait_pred, ?result, "insert_evaluation_cache");
1336         self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result);
1337     }
1338 
check_recursion_depth<T>( &self, depth: usize, error_obligation: &Obligation<'tcx, T>, ) -> Result<(), OverflowError> where T: ToPredicate<'tcx> + Clone,1339     fn check_recursion_depth<T>(
1340         &self,
1341         depth: usize,
1342         error_obligation: &Obligation<'tcx, T>,
1343     ) -> Result<(), OverflowError>
1344     where
1345         T: ToPredicate<'tcx> + Clone,
1346     {
1347         if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
1348             match self.query_mode {
1349                 TraitQueryMode::Standard => {
1350                     if let Some(e) = self.infcx.tainted_by_errors() {
1351                         return Err(OverflowError::Error(e));
1352                     }
1353                     self.infcx.err_ctxt().report_overflow_obligation(error_obligation, true);
1354                 }
1355                 TraitQueryMode::Canonical => {
1356                     return Err(OverflowError::Canonical);
1357                 }
1358             }
1359         }
1360         Ok(())
1361     }
1362 
1363     /// Checks that the recursion limit has not been exceeded.
1364     ///
1365     /// The weird return type of this function allows it to be used with the `try` (`?`)
1366     /// operator within certain functions.
1367     #[inline(always)]
check_recursion_limit<T: Display + TypeFoldable<TyCtxt<'tcx>>, V>( &self, obligation: &Obligation<'tcx, T>, error_obligation: &Obligation<'tcx, V>, ) -> Result<(), OverflowError> where V: ToPredicate<'tcx> + Clone,1368     fn check_recursion_limit<T: Display + TypeFoldable<TyCtxt<'tcx>>, V>(
1369         &self,
1370         obligation: &Obligation<'tcx, T>,
1371         error_obligation: &Obligation<'tcx, V>,
1372     ) -> Result<(), OverflowError>
1373     where
1374         V: ToPredicate<'tcx> + Clone,
1375     {
1376         self.check_recursion_depth(obligation.recursion_depth, error_obligation)
1377     }
1378 
in_task<OP, R>(&mut self, op: OP) -> (R, DepNodeIndex) where OP: FnOnce(&mut Self) -> R,1379     fn in_task<OP, R>(&mut self, op: OP) -> (R, DepNodeIndex)
1380     where
1381         OP: FnOnce(&mut Self) -> R,
1382     {
1383         let (result, dep_node) =
1384             self.tcx().dep_graph.with_anon_task(self.tcx(), DepKind::TraitSelect, || op(self));
1385         self.tcx().dep_graph.read_index(dep_node);
1386         (result, dep_node)
1387     }
1388 
1389     /// filter_impls filters constant trait obligations and candidates that have a positive impl
1390     /// for a negative goal and a negative impl for a positive goal
1391     #[instrument(level = "debug", skip(self, candidates))]
filter_impls( &mut self, candidates: Vec<SelectionCandidate<'tcx>>, obligation: &PolyTraitObligation<'tcx>, ) -> Vec<SelectionCandidate<'tcx>>1392     fn filter_impls(
1393         &mut self,
1394         candidates: Vec<SelectionCandidate<'tcx>>,
1395         obligation: &PolyTraitObligation<'tcx>,
1396     ) -> Vec<SelectionCandidate<'tcx>> {
1397         trace!("{candidates:#?}");
1398         let tcx = self.tcx();
1399         let mut result = Vec::with_capacity(candidates.len());
1400 
1401         for candidate in candidates {
1402             // Respect const trait obligations
1403             if obligation.is_const() {
1404                 match candidate {
1405                     // const impl
1406                     ImplCandidate(def_id) if tcx.constness(def_id) == hir::Constness::Const => {}
1407                     // const param
1408                     ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
1409                     // const projection
1410                     ProjectionCandidate(_, ty::BoundConstness::ConstIfConst)
1411                     // auto trait impl
1412                     | AutoImplCandidate
1413                     // generator / future, this will raise error in other places
1414                     // or ignore error with const_async_blocks feature
1415                     | GeneratorCandidate
1416                     | FutureCandidate
1417                     // FnDef where the function is const
1418                     | FnPointerCandidate { is_const: true }
1419                     | ConstDestructCandidate(_)
1420                     | ClosureCandidate { is_const: true } => {}
1421 
1422                     FnPointerCandidate { is_const: false } => {
1423                         if let ty::FnDef(def_id, _) = obligation.self_ty().skip_binder().kind() && tcx.trait_of_item(*def_id).is_some() {
1424                             // Trait methods are not seen as const unless the trait is implemented as const.
1425                             // We do not filter that out in here, but nested obligations will be needed to confirm this.
1426                         } else {
1427                             continue
1428                         }
1429                     }
1430 
1431                     _ => {
1432                         // reject all other types of candidates
1433                         continue;
1434                     }
1435                 }
1436             }
1437 
1438             if let ImplCandidate(def_id) = candidate {
1439                 if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id)
1440                     || obligation.polarity() == tcx.impl_polarity(def_id)
1441                 {
1442                     result.push(candidate);
1443                 }
1444             } else {
1445                 result.push(candidate);
1446             }
1447         }
1448 
1449         trace!("{result:#?}");
1450         result
1451     }
1452 
1453     /// filter_reservation_impls filter reservation impl for any goal as ambiguous
1454     #[instrument(level = "debug", skip(self))]
filter_reservation_impls( &mut self, candidate: SelectionCandidate<'tcx>, obligation: &PolyTraitObligation<'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>>1455     fn filter_reservation_impls(
1456         &mut self,
1457         candidate: SelectionCandidate<'tcx>,
1458         obligation: &PolyTraitObligation<'tcx>,
1459     ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
1460         let tcx = self.tcx();
1461         // Treat reservation impls as ambiguity.
1462         if let ImplCandidate(def_id) = candidate {
1463             if let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) {
1464                 if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
1465                     let value = tcx
1466                         .get_attr(def_id, sym::rustc_reservation_impl)
1467                         .and_then(|a| a.value_str());
1468                     if let Some(value) = value {
1469                         debug!(
1470                             "filter_reservation_impls: \
1471                                  reservation impl ambiguity on {:?}",
1472                             def_id
1473                         );
1474                         intercrate_ambiguity_clauses.insert(
1475                             IntercrateAmbiguityCause::ReservationImpl {
1476                                 message: value.to_string(),
1477                             },
1478                         );
1479                     }
1480                 }
1481                 return Ok(None);
1482             }
1483         }
1484         Ok(Some(candidate))
1485     }
1486 
is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict>1487     fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
1488         debug!("is_knowable(intercrate={:?})", self.is_intercrate());
1489 
1490         if !self.is_intercrate() || stack.obligation.polarity() == ty::ImplPolarity::Negative {
1491             return Ok(());
1492         }
1493 
1494         let obligation = &stack.obligation;
1495         let predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
1496 
1497         // Okay to skip binder because of the nature of the
1498         // trait-ref-is-knowable check, which does not care about
1499         // bound regions.
1500         let trait_ref = predicate.skip_binder().trait_ref;
1501 
1502         coherence::trait_ref_is_knowable(self.tcx(), trait_ref)
1503     }
1504 
1505     /// Returns `true` if the global caches can be used.
can_use_global_caches(&self, param_env: ty::ParamEnv<'tcx>) -> bool1506     fn can_use_global_caches(&self, param_env: ty::ParamEnv<'tcx>) -> bool {
1507         // If there are any inference variables in the `ParamEnv`, then we
1508         // always use a cache local to this particular scope. Otherwise, we
1509         // switch to a global cache.
1510         if param_env.has_infer() {
1511             return false;
1512         }
1513 
1514         // Avoid using the master cache during coherence and just rely
1515         // on the local cache. This effectively disables caching
1516         // during coherence. It is really just a simplification to
1517         // avoid us having to fear that coherence results "pollute"
1518         // the master cache. Since coherence executes pretty quickly,
1519         // it's not worth going to more trouble to increase the
1520         // hit-rate, I don't think.
1521         if self.is_intercrate() {
1522             return false;
1523         }
1524 
1525         // Otherwise, we can use the global cache.
1526         true
1527     }
1528 
check_candidate_cache( &mut self, mut param_env: ty::ParamEnv<'tcx>, cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>>1529     fn check_candidate_cache(
1530         &mut self,
1531         mut param_env: ty::ParamEnv<'tcx>,
1532         cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
1533     ) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> {
1534         // Neither the global nor local cache is aware of intercrate
1535         // mode, so don't do any caching. In particular, we might
1536         // re-use the same `InferCtxt` with both an intercrate
1537         // and non-intercrate `SelectionContext`
1538         if self.is_intercrate() {
1539             return None;
1540         }
1541         let tcx = self.tcx();
1542         let mut pred = cache_fresh_trait_pred.skip_binder();
1543         pred.remap_constness(&mut param_env);
1544 
1545         if self.can_use_global_caches(param_env) {
1546             if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
1547                 return Some(res);
1548             }
1549         }
1550         self.infcx.selection_cache.get(&(param_env, pred), tcx)
1551     }
1552 
1553     /// Determines whether can we safely cache the result
1554     /// of selecting an obligation. This is almost always `true`,
1555     /// except when dealing with certain `ParamCandidate`s.
1556     ///
1557     /// Ordinarily, a `ParamCandidate` will contain no inference variables,
1558     /// since it was usually produced directly from a `DefId`. However,
1559     /// certain cases (currently only librustdoc's blanket impl finder),
1560     /// a `ParamEnv` may be explicitly constructed with inference types.
1561     /// When this is the case, we do *not* want to cache the resulting selection
1562     /// candidate. This is due to the fact that it might not always be possible
1563     /// to equate the obligation's trait ref and the candidate's trait ref,
1564     /// if more constraints end up getting added to an inference variable.
1565     ///
1566     /// Because of this, we always want to re-run the full selection
1567     /// process for our obligation the next time we see it, since
1568     /// we might end up picking a different `SelectionCandidate` (or none at all).
can_cache_candidate( &self, result: &SelectionResult<'tcx, SelectionCandidate<'tcx>>, ) -> bool1569     fn can_cache_candidate(
1570         &self,
1571         result: &SelectionResult<'tcx, SelectionCandidate<'tcx>>,
1572     ) -> bool {
1573         // Neither the global nor local cache is aware of intercrate
1574         // mode, so don't do any caching. In particular, we might
1575         // re-use the same `InferCtxt` with both an intercrate
1576         // and non-intercrate `SelectionContext`
1577         if self.is_intercrate() {
1578             return false;
1579         }
1580         match result {
1581             Ok(Some(SelectionCandidate::ParamCandidate(trait_ref))) => !trait_ref.has_infer(),
1582             _ => true,
1583         }
1584     }
1585 
1586     #[instrument(skip(self, param_env, cache_fresh_trait_pred, dep_node), level = "debug")]
insert_candidate_cache( &mut self, mut param_env: ty::ParamEnv<'tcx>, cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, dep_node: DepNodeIndex, candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>, )1587     fn insert_candidate_cache(
1588         &mut self,
1589         mut param_env: ty::ParamEnv<'tcx>,
1590         cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
1591         dep_node: DepNodeIndex,
1592         candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>,
1593     ) {
1594         let tcx = self.tcx();
1595         let mut pred = cache_fresh_trait_pred.skip_binder();
1596 
1597         pred.remap_constness(&mut param_env);
1598 
1599         if !self.can_cache_candidate(&candidate) {
1600             debug!(?pred, ?candidate, "insert_candidate_cache - candidate is not cacheable");
1601             return;
1602         }
1603 
1604         if self.can_use_global_caches(param_env) {
1605             if let Err(Overflow(OverflowError::Canonical)) = candidate {
1606                 // Don't cache overflow globally; we only produce this in certain modes.
1607             } else if !pred.has_infer() {
1608                 if !candidate.has_infer() {
1609                     debug!(?pred, ?candidate, "insert_candidate_cache global");
1610                     // This may overwrite the cache with the same value.
1611                     tcx.selection_cache.insert((param_env, pred), dep_node, candidate);
1612                     return;
1613                 }
1614             }
1615         }
1616 
1617         debug!(?pred, ?candidate, "insert_candidate_cache local");
1618         self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate);
1619     }
1620 
1621     /// Matches a predicate against the bounds of its self type.
1622     ///
1623     /// Given an obligation like `<T as Foo>::Bar: Baz` where the self type is
1624     /// a projection, look at the bounds of `T::Bar`, see if we can find a
1625     /// `Baz` bound. We return indexes into the list returned by
1626     /// `tcx.item_bounds` for any applicable bounds.
1627     #[instrument(level = "debug", skip(self), ret)]
match_projection_obligation_against_definition_bounds( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]>1628     fn match_projection_obligation_against_definition_bounds(
1629         &mut self,
1630         obligation: &PolyTraitObligation<'tcx>,
1631     ) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]> {
1632         let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
1633         let placeholder_trait_predicate =
1634             self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate);
1635         debug!(?placeholder_trait_predicate);
1636 
1637         let tcx = self.infcx.tcx;
1638         let (def_id, substs) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() {
1639             ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
1640                 (def_id, substs)
1641             }
1642             _ => {
1643                 span_bug!(
1644                     obligation.cause.span,
1645                     "match_projection_obligation_against_definition_bounds() called \
1646                      but self-ty is not a projection: {:?}",
1647                     placeholder_trait_predicate.trait_ref.self_ty()
1648                 );
1649             }
1650         };
1651         let bounds = tcx.item_bounds(def_id).subst(tcx, substs);
1652 
1653         // The bounds returned by `item_bounds` may contain duplicates after
1654         // normalization, so try to deduplicate when possible to avoid
1655         // unnecessary ambiguity.
1656         let mut distinct_normalized_bounds = FxHashSet::default();
1657 
1658         bounds
1659             .iter()
1660             .enumerate()
1661             .filter_map(|(idx, bound)| {
1662                 let bound_predicate = bound.kind();
1663                 if let ty::ClauseKind::Trait(pred) = bound_predicate.skip_binder() {
1664                     let bound = bound_predicate.rebind(pred.trait_ref);
1665                     if self.infcx.probe(|_| {
1666                         match self.match_normalize_trait_ref(
1667                             obligation,
1668                             bound,
1669                             placeholder_trait_predicate.trait_ref,
1670                         ) {
1671                             Ok(None) => true,
1672                             Ok(Some(normalized_trait))
1673                                 if distinct_normalized_bounds.insert(normalized_trait) =>
1674                             {
1675                                 true
1676                             }
1677                             _ => false,
1678                         }
1679                     }) {
1680                         return Some((idx, pred.constness));
1681                     }
1682                 }
1683                 None
1684             })
1685             .collect()
1686     }
1687 
1688     /// Equates the trait in `obligation` with trait bound. If the two traits
1689     /// can be equated and the normalized trait bound doesn't contain inference
1690     /// variables or placeholders, the normalized bound is returned.
match_normalize_trait_ref( &mut self, obligation: &PolyTraitObligation<'tcx>, trait_bound: ty::PolyTraitRef<'tcx>, placeholder_trait_ref: ty::TraitRef<'tcx>, ) -> Result<Option<ty::PolyTraitRef<'tcx>>, ()>1691     fn match_normalize_trait_ref(
1692         &mut self,
1693         obligation: &PolyTraitObligation<'tcx>,
1694         trait_bound: ty::PolyTraitRef<'tcx>,
1695         placeholder_trait_ref: ty::TraitRef<'tcx>,
1696     ) -> Result<Option<ty::PolyTraitRef<'tcx>>, ()> {
1697         debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars());
1698         if placeholder_trait_ref.def_id != trait_bound.def_id() {
1699             // Avoid unnecessary normalization
1700             return Err(());
1701         }
1702 
1703         let Normalized { value: trait_bound, obligations: _ } = ensure_sufficient_stack(|| {
1704             project::normalize_with_depth(
1705                 self,
1706                 obligation.param_env,
1707                 obligation.cause.clone(),
1708                 obligation.recursion_depth + 1,
1709                 trait_bound,
1710             )
1711         });
1712         self.infcx
1713             .at(&obligation.cause, obligation.param_env)
1714             .sup(DefineOpaqueTypes::No, ty::Binder::dummy(placeholder_trait_ref), trait_bound)
1715             .map(|InferOk { obligations: _, value: () }| {
1716                 // This method is called within a probe, so we can't have
1717                 // inference variables and placeholders escape.
1718                 if !trait_bound.has_infer() && !trait_bound.has_placeholders() {
1719                     Some(trait_bound)
1720                 } else {
1721                     None
1722                 }
1723             })
1724             .map_err(|_| ())
1725     }
1726 
where_clause_may_apply<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, where_clause_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result<EvaluationResult, OverflowError>1727     fn where_clause_may_apply<'o>(
1728         &mut self,
1729         stack: &TraitObligationStack<'o, 'tcx>,
1730         where_clause_trait_ref: ty::PolyTraitRef<'tcx>,
1731     ) -> Result<EvaluationResult, OverflowError> {
1732         self.evaluation_probe(|this| {
1733             match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
1734                 Ok(obligations) => this.evaluate_predicates_recursively(stack.list(), obligations),
1735                 Err(()) => Ok(EvaluatedToErr),
1736             }
1737         })
1738     }
1739 
1740     /// Return `Yes` if the obligation's predicate type applies to the env_predicate, and
1741     /// `No` if it does not. Return `Ambiguous` in the case that the projection type is a GAT,
1742     /// and applying this env_predicate constrains any of the obligation's GAT substitutions.
1743     ///
1744     /// This behavior is a somewhat of a hack to prevent over-constraining inference variables
1745     /// in cases like #91762.
match_projection_projections( &mut self, obligation: &ProjectionTyObligation<'tcx>, env_predicate: PolyProjectionPredicate<'tcx>, potentially_unnormalized_candidates: bool, ) -> ProjectionMatchesProjection1746     pub(super) fn match_projection_projections(
1747         &mut self,
1748         obligation: &ProjectionTyObligation<'tcx>,
1749         env_predicate: PolyProjectionPredicate<'tcx>,
1750         potentially_unnormalized_candidates: bool,
1751     ) -> ProjectionMatchesProjection {
1752         let mut nested_obligations = Vec::new();
1753         let infer_predicate = self.infcx.instantiate_binder_with_fresh_vars(
1754             obligation.cause.span,
1755             LateBoundRegionConversionTime::HigherRankedType,
1756             env_predicate,
1757         );
1758         let infer_projection = if potentially_unnormalized_candidates {
1759             ensure_sufficient_stack(|| {
1760                 project::normalize_with_depth_to(
1761                     self,
1762                     obligation.param_env,
1763                     obligation.cause.clone(),
1764                     obligation.recursion_depth + 1,
1765                     infer_predicate.projection_ty,
1766                     &mut nested_obligations,
1767                 )
1768             })
1769         } else {
1770             infer_predicate.projection_ty
1771         };
1772 
1773         let is_match = self
1774             .infcx
1775             .at(&obligation.cause, obligation.param_env)
1776             .sup(DefineOpaqueTypes::No, obligation.predicate, infer_projection)
1777             .is_ok_and(|InferOk { obligations, value: () }| {
1778                 self.evaluate_predicates_recursively(
1779                     TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
1780                     nested_obligations.into_iter().chain(obligations),
1781                 )
1782                 .is_ok_and(|res| res.may_apply())
1783             });
1784 
1785         if is_match {
1786             let generics = self.tcx().generics_of(obligation.predicate.def_id);
1787             // FIXME(generic-associated-types): Addresses aggressive inference in #92917.
1788             // If this type is a GAT, and of the GAT substs resolve to something new,
1789             // that means that we must have newly inferred something about the GAT.
1790             // We should give up in that case.
1791             if !generics.params.is_empty()
1792                 && obligation.predicate.substs[generics.parent_count..]
1793                     .iter()
1794                     .any(|&p| p.has_non_region_infer() && self.infcx.shallow_resolve(p) != p)
1795             {
1796                 ProjectionMatchesProjection::Ambiguous
1797             } else {
1798                 ProjectionMatchesProjection::Yes
1799             }
1800         } else {
1801             ProjectionMatchesProjection::No
1802         }
1803     }
1804 }
1805 
1806 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
1807 enum DropVictim {
1808     Yes,
1809     No,
1810 }
1811 
1812 impl DropVictim {
drop_if(should_drop: bool) -> DropVictim1813     fn drop_if(should_drop: bool) -> DropVictim {
1814         if should_drop { DropVictim::Yes } else { DropVictim::No }
1815     }
1816 }
1817 
1818 /// ## Winnowing
1819 ///
1820 /// Winnowing is the process of attempting to resolve ambiguity by
1821 /// probing further. During the winnowing process, we unify all
1822 /// type variables and then we also attempt to evaluate recursive
1823 /// bounds to see if they are satisfied.
1824 impl<'tcx> SelectionContext<'_, 'tcx> {
1825     /// Returns `DropVictim::Yes` if `victim` should be dropped in favor of
1826     /// `other`. Generally speaking we will drop duplicate
1827     /// candidates and prefer where-clause candidates.
1828     ///
1829     /// See the comment for "SelectionCandidate" for more details.
candidate_should_be_dropped_in_favor_of( &mut self, victim: &EvaluatedCandidate<'tcx>, other: &EvaluatedCandidate<'tcx>, has_non_region_infer: bool, ) -> DropVictim1830     fn candidate_should_be_dropped_in_favor_of(
1831         &mut self,
1832         victim: &EvaluatedCandidate<'tcx>,
1833         other: &EvaluatedCandidate<'tcx>,
1834         has_non_region_infer: bool,
1835     ) -> DropVictim {
1836         if victim.candidate == other.candidate {
1837             return DropVictim::Yes;
1838         }
1839 
1840         // Check if a bound would previously have been removed when normalizing
1841         // the param_env so that it can be given the lowest priority. See
1842         // #50825 for the motivation for this.
1843         let is_global =
1844             |cand: &ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_late_bound_vars();
1845 
1846         // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
1847         // `DiscriminantKindCandidate`, `ConstDestructCandidate`
1848         // to anything else.
1849         //
1850         // This is a fix for #53123 and prevents winnowing from accidentally extending the
1851         // lifetime of a variable.
1852         match (&other.candidate, &victim.candidate) {
1853             (_, AutoImplCandidate) | (AutoImplCandidate, _) => {
1854                 bug!(
1855                     "default implementations shouldn't be recorded \
1856                     when there are other valid candidates"
1857                 );
1858             }
1859 
1860             // FIXME(@jswrenn): this should probably be more sophisticated
1861             (TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => DropVictim::No,
1862 
1863             // (*)
1864             (BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_), _) => {
1865                 DropVictim::Yes
1866             }
1867             (_, BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_)) => {
1868                 DropVictim::No
1869             }
1870 
1871             (ParamCandidate(other), ParamCandidate(victim)) => {
1872                 let same_except_bound_vars = other.skip_binder().trait_ref
1873                     == victim.skip_binder().trait_ref
1874                     && other.skip_binder().constness == victim.skip_binder().constness
1875                     && other.skip_binder().polarity == victim.skip_binder().polarity
1876                     && !other.skip_binder().trait_ref.has_escaping_bound_vars();
1877                 if same_except_bound_vars {
1878                     // See issue #84398. In short, we can generate multiple ParamCandidates which are
1879                     // the same except for unused bound vars. Just pick the one with the fewest bound vars
1880                     // or the current one if tied (they should both evaluate to the same answer). This is
1881                     // probably best characterized as a "hack", since we might prefer to just do our
1882                     // best to *not* create essentially duplicate candidates in the first place.
1883                     DropVictim::drop_if(other.bound_vars().len() <= victim.bound_vars().len())
1884                 } else if other.skip_binder().trait_ref == victim.skip_binder().trait_ref
1885                     && victim.skip_binder().constness == ty::BoundConstness::NotConst
1886                     && other.skip_binder().polarity == victim.skip_binder().polarity
1887                 {
1888                     // Drop otherwise equivalent non-const candidates in favor of const candidates.
1889                     DropVictim::Yes
1890                 } else {
1891                     DropVictim::No
1892                 }
1893             }
1894 
1895             // Drop otherwise equivalent non-const fn pointer candidates
1896             (FnPointerCandidate { .. }, FnPointerCandidate { is_const: false }) => DropVictim::Yes,
1897 
1898             (
1899                 ParamCandidate(ref other_cand),
1900                 ImplCandidate(..)
1901                 | ClosureCandidate { .. }
1902                 | GeneratorCandidate
1903                 | FutureCandidate
1904                 | FnPointerCandidate { .. }
1905                 | BuiltinObjectCandidate
1906                 | BuiltinUnsizeCandidate
1907                 | TraitUpcastingUnsizeCandidate(_)
1908                 | BuiltinCandidate { .. }
1909                 | TraitAliasCandidate
1910                 | ObjectCandidate(_)
1911                 | ProjectionCandidate(..),
1912             ) => {
1913                 // We have a where clause so don't go around looking
1914                 // for impls. Arbitrarily give param candidates priority
1915                 // over projection and object candidates.
1916                 //
1917                 // Global bounds from the where clause should be ignored
1918                 // here (see issue #50825).
1919                 DropVictim::drop_if(!is_global(other_cand))
1920             }
1921             (ObjectCandidate(_) | ProjectionCandidate(..), ParamCandidate(ref victim_cand)) => {
1922                 // Prefer these to a global where-clause bound
1923                 // (see issue #50825).
1924                 if is_global(victim_cand) { DropVictim::Yes } else { DropVictim::No }
1925             }
1926             (
1927                 ImplCandidate(_)
1928                 | ClosureCandidate { .. }
1929                 | GeneratorCandidate
1930                 | FutureCandidate
1931                 | FnPointerCandidate { .. }
1932                 | BuiltinObjectCandidate
1933                 | BuiltinUnsizeCandidate
1934                 | TraitUpcastingUnsizeCandidate(_)
1935                 | BuiltinCandidate { has_nested: true }
1936                 | TraitAliasCandidate,
1937                 ParamCandidate(ref victim_cand),
1938             ) => {
1939                 // Prefer these to a global where-clause bound
1940                 // (see issue #50825).
1941                 DropVictim::drop_if(
1942                     is_global(victim_cand) && other.evaluation.must_apply_modulo_regions(),
1943                 )
1944             }
1945 
1946             (ProjectionCandidate(i, _), ProjectionCandidate(j, _))
1947             | (ObjectCandidate(i), ObjectCandidate(j)) => {
1948                 // Arbitrarily pick the lower numbered candidate for backwards
1949                 // compatibility reasons. Don't let this affect inference.
1950                 DropVictim::drop_if(i < j && !has_non_region_infer)
1951             }
1952             (ObjectCandidate(_), ProjectionCandidate(..))
1953             | (ProjectionCandidate(..), ObjectCandidate(_)) => {
1954                 bug!("Have both object and projection candidate")
1955             }
1956 
1957             // Arbitrarily give projection and object candidates priority.
1958             (
1959                 ObjectCandidate(_) | ProjectionCandidate(..),
1960                 ImplCandidate(..)
1961                 | ClosureCandidate { .. }
1962                 | GeneratorCandidate
1963                 | FutureCandidate
1964                 | FnPointerCandidate { .. }
1965                 | BuiltinObjectCandidate
1966                 | BuiltinUnsizeCandidate
1967                 | TraitUpcastingUnsizeCandidate(_)
1968                 | BuiltinCandidate { .. }
1969                 | TraitAliasCandidate,
1970             ) => DropVictim::Yes,
1971 
1972             (
1973                 ImplCandidate(..)
1974                 | ClosureCandidate { .. }
1975                 | GeneratorCandidate
1976                 | FutureCandidate
1977                 | FnPointerCandidate { .. }
1978                 | BuiltinObjectCandidate
1979                 | BuiltinUnsizeCandidate
1980                 | TraitUpcastingUnsizeCandidate(_)
1981                 | BuiltinCandidate { .. }
1982                 | TraitAliasCandidate,
1983                 ObjectCandidate(_) | ProjectionCandidate(..),
1984             ) => DropVictim::No,
1985 
1986             (&ImplCandidate(other_def), &ImplCandidate(victim_def)) => {
1987                 // See if we can toss out `victim` based on specialization.
1988                 // While this requires us to know *for sure* that the `other` impl applies
1989                 // we still use modulo regions here.
1990                 //
1991                 // This is fine as specialization currently assumes that specializing
1992                 // impls have to be always applicable, meaning that the only allowed
1993                 // region constraints may be constraints also present on the default impl.
1994                 let tcx = self.tcx();
1995                 if other.evaluation.must_apply_modulo_regions() {
1996                     if tcx.specializes((other_def, victim_def)) {
1997                         return DropVictim::Yes;
1998                     }
1999                 }
2000 
2001                 match tcx.impls_are_allowed_to_overlap(other_def, victim_def) {
2002                     // For #33140 the impl headers must be exactly equal, the trait must not have
2003                     // any associated items and there are no where-clauses.
2004                     //
2005                     // We can just arbitrarily drop one of the impls.
2006                     Some(ty::ImplOverlapKind::Issue33140) => {
2007                         assert_eq!(other.evaluation, victim.evaluation);
2008                         DropVictim::Yes
2009                     }
2010                     // For candidates which already reference errors it doesn't really
2011                     // matter what we do ��
2012                     Some(ty::ImplOverlapKind::Permitted { marker: false }) => {
2013                         DropVictim::drop_if(other.evaluation.must_apply_considering_regions())
2014                     }
2015                     Some(ty::ImplOverlapKind::Permitted { marker: true }) => {
2016                         // Subtle: If the predicate we are evaluating has inference
2017                         // variables, do *not* allow discarding candidates due to
2018                         // marker trait impls.
2019                         //
2020                         // Without this restriction, we could end up accidentally
2021                         // constraining inference variables based on an arbitrarily
2022                         // chosen trait impl.
2023                         //
2024                         // Imagine we have the following code:
2025                         //
2026                         // ```rust
2027                         // #[marker] trait MyTrait {}
2028                         // impl MyTrait for u8 {}
2029                         // impl MyTrait for bool {}
2030                         // ```
2031                         //
2032                         // And we are evaluating the predicate `<_#0t as MyTrait>`.
2033                         //
2034                         // During selection, we will end up with one candidate for each
2035                         // impl of `MyTrait`. If we were to discard one impl in favor
2036                         // of the other, we would be left with one candidate, causing
2037                         // us to "successfully" select the predicate, unifying
2038                         // _#0t with (for example) `u8`.
2039                         //
2040                         // However, we have no reason to believe that this unification
2041                         // is correct - we've essentially just picked an arbitrary
2042                         // *possibility* for _#0t, and required that this be the *only*
2043                         // possibility.
2044                         //
2045                         // Eventually, we will either:
2046                         // 1) Unify all inference variables in the predicate through
2047                         // some other means (e.g. type-checking of a function). We will
2048                         // then be in a position to drop marker trait candidates
2049                         // without constraining inference variables (since there are
2050                         // none left to constrain)
2051                         // 2) Be left with some unconstrained inference variables. We
2052                         // will then correctly report an inference error, since the
2053                         // existence of multiple marker trait impls tells us nothing
2054                         // about which one should actually apply.
2055                         DropVictim::drop_if(
2056                             !has_non_region_infer
2057                                 && other.evaluation.must_apply_considering_regions(),
2058                         )
2059                     }
2060                     None => DropVictim::No,
2061                 }
2062             }
2063 
2064             // Everything else is ambiguous
2065             (
2066                 ImplCandidate(_)
2067                 | ClosureCandidate { .. }
2068                 | GeneratorCandidate
2069                 | FutureCandidate
2070                 | FnPointerCandidate { .. }
2071                 | BuiltinObjectCandidate
2072                 | BuiltinUnsizeCandidate
2073                 | TraitUpcastingUnsizeCandidate(_)
2074                 | BuiltinCandidate { has_nested: true }
2075                 | TraitAliasCandidate,
2076                 ImplCandidate(_)
2077                 | ClosureCandidate { .. }
2078                 | GeneratorCandidate
2079                 | FutureCandidate
2080                 | FnPointerCandidate { .. }
2081                 | BuiltinObjectCandidate
2082                 | BuiltinUnsizeCandidate
2083                 | TraitUpcastingUnsizeCandidate(_)
2084                 | BuiltinCandidate { has_nested: true }
2085                 | TraitAliasCandidate,
2086             ) => DropVictim::No,
2087         }
2088     }
2089 }
2090 
2091 impl<'tcx> SelectionContext<'_, 'tcx> {
sized_conditions( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> BuiltinImplConditions<'tcx>2092     fn sized_conditions(
2093         &mut self,
2094         obligation: &PolyTraitObligation<'tcx>,
2095     ) -> BuiltinImplConditions<'tcx> {
2096         use self::BuiltinImplConditions::{Ambiguous, None, Where};
2097 
2098         // NOTE: binder moved to (*)
2099         let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
2100 
2101         match self_ty.kind() {
2102             ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
2103             | ty::Uint(_)
2104             | ty::Int(_)
2105             | ty::Bool
2106             | ty::Float(_)
2107             | ty::FnDef(..)
2108             | ty::FnPtr(_)
2109             | ty::RawPtr(..)
2110             | ty::Char
2111             | ty::Ref(..)
2112             | ty::Generator(..)
2113             | ty::GeneratorWitness(..)
2114             | ty::GeneratorWitnessMIR(..)
2115             | ty::Array(..)
2116             | ty::Closure(..)
2117             | ty::Never
2118             | ty::Dynamic(_, _, ty::DynStar)
2119             | ty::Error(_) => {
2120                 // safe for everything
2121                 Where(ty::Binder::dummy(Vec::new()))
2122             }
2123 
2124             ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None,
2125 
2126             ty::Tuple(tys) => Where(
2127                 obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])),
2128             ),
2129 
2130             ty::Adt(def, substs) => {
2131                 let sized_crit = def.sized_constraint(self.tcx());
2132                 // (*) binder moved here
2133                 Where(
2134                     obligation
2135                         .predicate
2136                         .rebind(sized_crit.subst_iter_copied(self.tcx(), substs).collect()),
2137                 )
2138             }
2139 
2140             ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None,
2141             ty::Infer(ty::TyVar(_)) => Ambiguous,
2142 
2143             // We can make this an ICE if/once we actually instantiate the trait obligation eagerly.
2144             ty::Bound(..) => None,
2145 
2146             ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
2147                 bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty);
2148             }
2149         }
2150     }
2151 
copy_clone_conditions( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> BuiltinImplConditions<'tcx>2152     fn copy_clone_conditions(
2153         &mut self,
2154         obligation: &PolyTraitObligation<'tcx>,
2155     ) -> BuiltinImplConditions<'tcx> {
2156         // NOTE: binder moved to (*)
2157         let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
2158 
2159         use self::BuiltinImplConditions::{Ambiguous, None, Where};
2160 
2161         match *self_ty.kind() {
2162             ty::Infer(ty::IntVar(_))
2163             | ty::Infer(ty::FloatVar(_))
2164             | ty::FnDef(..)
2165             | ty::FnPtr(_)
2166             | ty::Error(_) => Where(ty::Binder::dummy(Vec::new())),
2167 
2168             ty::Uint(_)
2169             | ty::Int(_)
2170             | ty::Bool
2171             | ty::Float(_)
2172             | ty::Char
2173             | ty::RawPtr(..)
2174             | ty::Never
2175             | ty::Ref(_, _, hir::Mutability::Not)
2176             | ty::Array(..) => {
2177                 // Implementations provided in libcore
2178                 None
2179             }
2180 
2181             ty::Dynamic(..)
2182             | ty::Str
2183             | ty::Slice(..)
2184             | ty::Generator(_, _, hir::Movability::Static)
2185             | ty::Foreign(..)
2186             | ty::Ref(_, _, hir::Mutability::Mut) => None,
2187 
2188             ty::Tuple(tys) => {
2189                 // (*) binder moved here
2190                 Where(obligation.predicate.rebind(tys.iter().collect()))
2191             }
2192 
2193             ty::Generator(_, substs, hir::Movability::Movable) => {
2194                 if self.tcx().features().generator_clone {
2195                     let resolved_upvars =
2196                         self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
2197                     let resolved_witness =
2198                         self.infcx.shallow_resolve(substs.as_generator().witness());
2199                     if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
2200                         // Not yet resolved.
2201                         Ambiguous
2202                     } else {
2203                         let all = substs
2204                             .as_generator()
2205                             .upvar_tys()
2206                             .chain(iter::once(substs.as_generator().witness()))
2207                             .collect::<Vec<_>>();
2208                         Where(obligation.predicate.rebind(all))
2209                     }
2210                 } else {
2211                     None
2212                 }
2213             }
2214 
2215             ty::GeneratorWitness(binder) => {
2216                 let witness_tys = binder.skip_binder();
2217                 for witness_ty in witness_tys.iter() {
2218                     let resolved = self.infcx.shallow_resolve(witness_ty);
2219                     if resolved.is_ty_var() {
2220                         return Ambiguous;
2221                     }
2222                 }
2223                 // (*) binder moved here
2224                 let all_vars = self.tcx().mk_bound_variable_kinds_from_iter(
2225                     obligation.predicate.bound_vars().iter().chain(binder.bound_vars().iter()),
2226                 );
2227                 Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars))
2228             }
2229 
2230             ty::GeneratorWitnessMIR(def_id, ref substs) => {
2231                 let hidden_types = bind_generator_hidden_types_above(
2232                     self.infcx,
2233                     def_id,
2234                     substs,
2235                     obligation.predicate.bound_vars(),
2236                 );
2237                 Where(hidden_types)
2238             }
2239 
2240             ty::Closure(_, substs) => {
2241                 // (*) binder moved here
2242                 let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
2243                 if let ty::Infer(ty::TyVar(_)) = ty.kind() {
2244                     // Not yet resolved.
2245                     Ambiguous
2246                 } else {
2247                     Where(obligation.predicate.rebind(substs.as_closure().upvar_tys().collect()))
2248                 }
2249             }
2250 
2251             ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {
2252                 // Fallback to whatever user-defined impls exist in this case.
2253                 None
2254             }
2255 
2256             ty::Infer(ty::TyVar(_)) => {
2257                 // Unbound type variable. Might or might not have
2258                 // applicable impls and so forth, depending on what
2259                 // those type variables wind up being bound to.
2260                 Ambiguous
2261             }
2262 
2263             // We can make this an ICE if/once we actually instantiate the trait obligation eagerly.
2264             ty::Bound(..) => None,
2265 
2266             ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
2267                 bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty);
2268             }
2269         }
2270     }
2271 
2272     /// For default impls, we need to break apart a type into its
2273     /// "constituent types" -- meaning, the types that it contains.
2274     ///
2275     /// Here are some (simple) examples:
2276     ///
2277     /// ```ignore (illustrative)
2278     /// (i32, u32) -> [i32, u32]
2279     /// Foo where struct Foo { x: i32, y: u32 } -> [i32, u32]
2280     /// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
2281     /// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
2282     /// ```
2283     #[instrument(level = "debug", skip(self), ret)]
constituent_types_for_ty( &self, t: ty::Binder<'tcx, Ty<'tcx>>, ) -> Result<ty::Binder<'tcx, Vec<Ty<'tcx>>>, SelectionError<'tcx>>2284     fn constituent_types_for_ty(
2285         &self,
2286         t: ty::Binder<'tcx, Ty<'tcx>>,
2287     ) -> Result<ty::Binder<'tcx, Vec<Ty<'tcx>>>, SelectionError<'tcx>> {
2288         Ok(match *t.skip_binder().kind() {
2289             ty::Uint(_)
2290             | ty::Int(_)
2291             | ty::Bool
2292             | ty::Float(_)
2293             | ty::FnDef(..)
2294             | ty::FnPtr(_)
2295             | ty::Error(_)
2296             | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
2297             | ty::Never
2298             | ty::Char => ty::Binder::dummy(Vec::new()),
2299 
2300             // Treat this like `struct str([u8]);`
2301             ty::Str => ty::Binder::dummy(vec![Ty::new_slice(self.tcx(), self.tcx().types.u8)]),
2302 
2303             ty::Placeholder(..)
2304             | ty::Dynamic(..)
2305             | ty::Param(..)
2306             | ty::Foreign(..)
2307             | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
2308             | ty::Bound(..)
2309             | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
2310                 bug!("asked to assemble constituent types of unexpected type: {:?}", t);
2311             }
2312 
2313             ty::RawPtr(ty::TypeAndMut { ty: element_ty, .. }) | ty::Ref(_, element_ty, _) => {
2314                 t.rebind(vec![element_ty])
2315             }
2316 
2317             ty::Array(element_ty, _) | ty::Slice(element_ty) => t.rebind(vec![element_ty]),
2318 
2319             ty::Tuple(ref tys) => {
2320                 // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
2321                 t.rebind(tys.iter().collect())
2322             }
2323 
2324             ty::Closure(_, ref substs) => {
2325                 let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
2326                 t.rebind(vec![ty])
2327             }
2328 
2329             ty::Generator(_, ref substs, _) => {
2330                 let ty = self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
2331                 let witness = substs.as_generator().witness();
2332                 t.rebind([ty].into_iter().chain(iter::once(witness)).collect())
2333             }
2334 
2335             ty::GeneratorWitness(types) => {
2336                 debug_assert!(!types.has_escaping_bound_vars());
2337                 types.map_bound(|types| types.to_vec())
2338             }
2339 
2340             ty::GeneratorWitnessMIR(def_id, ref substs) => {
2341                 bind_generator_hidden_types_above(self.infcx, def_id, substs, t.bound_vars())
2342             }
2343 
2344             // For `PhantomData<T>`, we pass `T`.
2345             ty::Adt(def, substs) if def.is_phantom_data() => t.rebind(substs.types().collect()),
2346 
2347             ty::Adt(def, substs) => {
2348                 t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect())
2349             }
2350 
2351             ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
2352                 let ty = self.tcx().type_of(def_id);
2353                 if ty.skip_binder().references_error() {
2354                     return Err(SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id));
2355                 }
2356                 // We can resolve the `impl Trait` to its concrete type,
2357                 // which enforces a DAG between the functions requiring
2358                 // the auto trait bounds in question.
2359                 t.rebind(vec![ty.subst(self.tcx(), substs)])
2360             }
2361         })
2362     }
2363 
collect_predicates_for_types( &mut self, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, recursion_depth: usize, trait_def_id: DefId, types: ty::Binder<'tcx, Vec<Ty<'tcx>>>, ) -> Vec<PredicateObligation<'tcx>>2364     fn collect_predicates_for_types(
2365         &mut self,
2366         param_env: ty::ParamEnv<'tcx>,
2367         cause: ObligationCause<'tcx>,
2368         recursion_depth: usize,
2369         trait_def_id: DefId,
2370         types: ty::Binder<'tcx, Vec<Ty<'tcx>>>,
2371     ) -> Vec<PredicateObligation<'tcx>> {
2372         // Because the types were potentially derived from
2373         // higher-ranked obligations they may reference late-bound
2374         // regions. For example, `for<'a> Foo<&'a i32> : Copy` would
2375         // yield a type like `for<'a> &'a i32`. In general, we
2376         // maintain the invariant that we never manipulate bound
2377         // regions, so we have to process these bound regions somehow.
2378         //
2379         // The strategy is to:
2380         //
2381         // 1. Instantiate those regions to placeholder regions (e.g.,
2382         //    `for<'a> &'a i32` becomes `&0 i32`.
2383         // 2. Produce something like `&'0 i32 : Copy`
2384         // 3. Re-bind the regions back to `for<'a> &'a i32 : Copy`
2385 
2386         types
2387             .as_ref()
2388             .skip_binder() // binder moved -\
2389             .iter()
2390             .flat_map(|ty| {
2391                 let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(*ty); // <----/
2392 
2393                 let placeholder_ty = self.infcx.instantiate_binder_with_placeholders(ty);
2394                 let Normalized { value: normalized_ty, mut obligations } =
2395                     ensure_sufficient_stack(|| {
2396                         project::normalize_with_depth(
2397                             self,
2398                             param_env,
2399                             cause.clone(),
2400                             recursion_depth,
2401                             placeholder_ty,
2402                         )
2403                     });
2404 
2405                 let obligation = Obligation::new(
2406                     self.tcx(),
2407                     cause.clone(),
2408                     param_env,
2409                     ty::TraitRef::new(self.tcx(), trait_def_id, [normalized_ty]),
2410                 );
2411                 obligations.push(obligation);
2412                 obligations
2413             })
2414             .collect()
2415     }
2416 
2417     ///////////////////////////////////////////////////////////////////////////
2418     // Matching
2419     //
2420     // Matching is a common path used for both evaluation and
2421     // confirmation. It basically unifies types that appear in impls
2422     // and traits. This does affect the surrounding environment;
2423     // therefore, when used during evaluation, match routines must be
2424     // run inside of a `probe()` so that their side-effects are
2425     // contained.
2426 
rematch_impl( &mut self, impl_def_id: DefId, obligation: &PolyTraitObligation<'tcx>, ) -> Normalized<'tcx, SubstsRef<'tcx>>2427     fn rematch_impl(
2428         &mut self,
2429         impl_def_id: DefId,
2430         obligation: &PolyTraitObligation<'tcx>,
2431     ) -> Normalized<'tcx, SubstsRef<'tcx>> {
2432         let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
2433         match self.match_impl(impl_def_id, impl_trait_ref, obligation) {
2434             Ok(substs) => substs,
2435             Err(()) => {
2436                 // FIXME: A rematch may fail when a candidate cache hit occurs
2437                 // on thefreshened form of the trait predicate, but the match
2438                 // fails for some reason that is not captured in the freshened
2439                 // cache key. For example, equating an impl trait ref against
2440                 // the placeholder trait ref may fail due the Generalizer relation
2441                 // raising a CyclicalTy error due to a sub_root_var relation
2442                 // for a variable being generalized...
2443                 let guar = self.infcx.tcx.sess.delay_span_bug(
2444                     obligation.cause.span,
2445                     format!(
2446                         "Impl {:?} was matchable against {:?} but now is not",
2447                         impl_def_id, obligation
2448                     ),
2449                 );
2450                 let value = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
2451                 let err = Ty::new_error(self.tcx(), guar);
2452                 let value = value.fold_with(&mut BottomUpFolder {
2453                     tcx: self.tcx(),
2454                     ty_op: |_| err,
2455                     lt_op: |l| l,
2456                     ct_op: |c| c,
2457                 });
2458                 Normalized { value, obligations: vec![] }
2459             }
2460         }
2461     }
2462 
2463     #[instrument(level = "debug", skip(self), ret)]
match_impl( &mut self, impl_def_id: DefId, impl_trait_ref: EarlyBinder<ty::TraitRef<'tcx>>, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()>2464     fn match_impl(
2465         &mut self,
2466         impl_def_id: DefId,
2467         impl_trait_ref: EarlyBinder<ty::TraitRef<'tcx>>,
2468         obligation: &PolyTraitObligation<'tcx>,
2469     ) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> {
2470         let placeholder_obligation =
2471             self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
2472         let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref;
2473 
2474         let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
2475 
2476         let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs);
2477         if impl_trait_ref.references_error() {
2478             return Err(());
2479         }
2480 
2481         debug!(?impl_trait_ref);
2482 
2483         let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } =
2484             ensure_sufficient_stack(|| {
2485                 project::normalize_with_depth(
2486                     self,
2487                     obligation.param_env,
2488                     obligation.cause.clone(),
2489                     obligation.recursion_depth + 1,
2490                     impl_trait_ref,
2491                 )
2492             });
2493 
2494         debug!(?impl_trait_ref, ?placeholder_obligation_trait_ref);
2495 
2496         let cause = ObligationCause::new(
2497             obligation.cause.span,
2498             obligation.cause.body_id,
2499             ObligationCauseCode::MatchImpl(obligation.cause.clone(), impl_def_id),
2500         );
2501 
2502         let InferOk { obligations, .. } = self
2503             .infcx
2504             .at(&cause, obligation.param_env)
2505             .eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref)
2506             .map_err(|e| {
2507                 debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx()))
2508             })?;
2509         nested_obligations.extend(obligations);
2510 
2511         if !self.is_intercrate()
2512             && self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation
2513         {
2514             debug!("reservation impls only apply in intercrate mode");
2515             return Err(());
2516         }
2517 
2518         Ok(Normalized { value: impl_substs, obligations: nested_obligations })
2519     }
2520 
2521     /// Normalize `where_clause_trait_ref` and try to match it against
2522     /// `obligation`. If successful, return any predicates that
2523     /// result from the normalization.
match_where_clause_trait_ref( &mut self, obligation: &PolyTraitObligation<'tcx>, where_clause_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, ()>2524     fn match_where_clause_trait_ref(
2525         &mut self,
2526         obligation: &PolyTraitObligation<'tcx>,
2527         where_clause_trait_ref: ty::PolyTraitRef<'tcx>,
2528     ) -> Result<Vec<PredicateObligation<'tcx>>, ()> {
2529         self.match_poly_trait_ref(obligation, where_clause_trait_ref)
2530     }
2531 
2532     /// Returns `Ok` if `poly_trait_ref` being true implies that the
2533     /// obligation is satisfied.
2534     #[instrument(skip(self), level = "debug")]
match_poly_trait_ref( &mut self, obligation: &PolyTraitObligation<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, ()>2535     fn match_poly_trait_ref(
2536         &mut self,
2537         obligation: &PolyTraitObligation<'tcx>,
2538         poly_trait_ref: ty::PolyTraitRef<'tcx>,
2539     ) -> Result<Vec<PredicateObligation<'tcx>>, ()> {
2540         self.infcx
2541             .at(&obligation.cause, obligation.param_env)
2542             .sup(DefineOpaqueTypes::No, obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
2543             .map(|InferOk { obligations, .. }| obligations)
2544             .map_err(|_| ())
2545     }
2546 
2547     ///////////////////////////////////////////////////////////////////////////
2548     // Miscellany
2549 
match_fresh_trait_refs( &self, previous: ty::PolyTraitPredicate<'tcx>, current: ty::PolyTraitPredicate<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> bool2550     fn match_fresh_trait_refs(
2551         &self,
2552         previous: ty::PolyTraitPredicate<'tcx>,
2553         current: ty::PolyTraitPredicate<'tcx>,
2554         param_env: ty::ParamEnv<'tcx>,
2555     ) -> bool {
2556         let mut matcher = ty::_match::Match::new(self.tcx(), param_env);
2557         matcher.relate(previous, current).is_ok()
2558     }
2559 
push_stack<'o>( &mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: &'o PolyTraitObligation<'tcx>, ) -> TraitObligationStack<'o, 'tcx>2560     fn push_stack<'o>(
2561         &mut self,
2562         previous_stack: TraitObligationStackList<'o, 'tcx>,
2563         obligation: &'o PolyTraitObligation<'tcx>,
2564     ) -> TraitObligationStack<'o, 'tcx> {
2565         let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener);
2566 
2567         let dfn = previous_stack.cache.next_dfn();
2568         let depth = previous_stack.depth() + 1;
2569         TraitObligationStack {
2570             obligation,
2571             fresh_trait_pred,
2572             reached_depth: Cell::new(depth),
2573             previous: previous_stack,
2574             dfn,
2575             depth,
2576         }
2577     }
2578 
2579     #[instrument(skip(self), level = "debug")]
closure_trait_ref_unnormalized( &mut self, obligation: &PolyTraitObligation<'tcx>, substs: SubstsRef<'tcx>, ) -> ty::PolyTraitRef<'tcx>2580     fn closure_trait_ref_unnormalized(
2581         &mut self,
2582         obligation: &PolyTraitObligation<'tcx>,
2583         substs: SubstsRef<'tcx>,
2584     ) -> ty::PolyTraitRef<'tcx> {
2585         let closure_sig = substs.as_closure().sig();
2586 
2587         debug!(?closure_sig);
2588 
2589         // NOTE: The self-type is an unboxed closure type and hence is
2590         // in fact unparameterized (or at least does not reference any
2591         // regions bound in the obligation).
2592         let self_ty = obligation
2593             .predicate
2594             .self_ty()
2595             .no_bound_vars()
2596             .expect("unboxed closure type should not capture bound vars from the predicate");
2597 
2598         closure_trait_ref_and_return_type(
2599             self.tcx(),
2600             obligation.predicate.def_id(),
2601             self_ty,
2602             closure_sig,
2603             util::TupleArgumentsFlag::No,
2604         )
2605         .map_bound(|(trait_ref, _)| trait_ref)
2606     }
2607 
2608     /// Returns the obligations that are implied by instantiating an
2609     /// impl or trait. The obligations are substituted and fully
2610     /// normalized. This is used when confirming an impl or default
2611     /// impl.
2612     #[instrument(level = "debug", skip(self, cause, param_env))]
impl_or_trait_obligations( &mut self, cause: &ObligationCause<'tcx>, recursion_depth: usize, param_env: ty::ParamEnv<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, ) -> Vec<PredicateObligation<'tcx>>2613     fn impl_or_trait_obligations(
2614         &mut self,
2615         cause: &ObligationCause<'tcx>,
2616         recursion_depth: usize,
2617         param_env: ty::ParamEnv<'tcx>,
2618         def_id: DefId,           // of impl or trait
2619         substs: SubstsRef<'tcx>, // for impl or trait
2620         parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
2621     ) -> Vec<PredicateObligation<'tcx>> {
2622         let tcx = self.tcx();
2623 
2624         // To allow for one-pass evaluation of the nested obligation,
2625         // each predicate must be preceded by the obligations required
2626         // to normalize it.
2627         // for example, if we have:
2628         //    impl<U: Iterator<Item: Copy>, V: Iterator<Item = U>> Foo for V
2629         // the impl will have the following predicates:
2630         //    <V as Iterator>::Item = U,
2631         //    U: Iterator, U: Sized,
2632         //    V: Iterator, V: Sized,
2633         //    <U as Iterator>::Item: Copy
2634         // When we substitute, say, `V => IntoIter<u32>, U => $0`, the last
2635         // obligation will normalize to `<$0 as Iterator>::Item = $1` and
2636         // `$1: Copy`, so we must ensure the obligations are emitted in
2637         // that order.
2638         let predicates = tcx.predicates_of(def_id);
2639         assert_eq!(predicates.parent, None);
2640         let predicates = predicates.instantiate_own(tcx, substs);
2641         let mut obligations = Vec::with_capacity(predicates.len());
2642         for (index, (predicate, span)) in predicates.into_iter().enumerate() {
2643             let cause =
2644                 if Some(parent_trait_pred.def_id()) == tcx.lang_items().coerce_unsized_trait() {
2645                     cause.clone()
2646                 } else {
2647                     cause.clone().derived_cause(parent_trait_pred, |derived| {
2648                         ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
2649                             derived,
2650                             impl_or_alias_def_id: def_id,
2651                             impl_def_predicate_index: Some(index),
2652                             span,
2653                         }))
2654                     })
2655                 };
2656             let clause = normalize_with_depth_to(
2657                 self,
2658                 param_env,
2659                 cause.clone(),
2660                 recursion_depth,
2661                 predicate,
2662                 &mut obligations,
2663             );
2664             obligations.push(Obligation {
2665                 cause,
2666                 recursion_depth,
2667                 param_env,
2668                 predicate: clause.as_predicate(),
2669             });
2670         }
2671 
2672         obligations
2673     }
2674 }
2675 
2676 impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {
list(&'o self) -> TraitObligationStackList<'o, 'tcx>2677     fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> {
2678         TraitObligationStackList::with(self)
2679     }
2680 
cache(&self) -> &'o ProvisionalEvaluationCache<'tcx>2681     fn cache(&self) -> &'o ProvisionalEvaluationCache<'tcx> {
2682         self.previous.cache
2683     }
2684 
iter(&'o self) -> TraitObligationStackList<'o, 'tcx>2685     fn iter(&'o self) -> TraitObligationStackList<'o, 'tcx> {
2686         self.list()
2687     }
2688 
2689     /// Indicates that attempting to evaluate this stack entry
2690     /// required accessing something from the stack at depth `reached_depth`.
update_reached_depth(&self, reached_depth: usize)2691     fn update_reached_depth(&self, reached_depth: usize) {
2692         assert!(
2693             self.depth >= reached_depth,
2694             "invoked `update_reached_depth` with something under this stack: \
2695              self.depth={} reached_depth={}",
2696             self.depth,
2697             reached_depth,
2698         );
2699         debug!(reached_depth, "update_reached_depth");
2700         let mut p = self;
2701         while reached_depth < p.depth {
2702             debug!(?p.fresh_trait_pred, "update_reached_depth: marking as cycle participant");
2703             p.reached_depth.set(p.reached_depth.get().min(reached_depth));
2704             p = p.previous.head.unwrap();
2705         }
2706     }
2707 }
2708 
2709 /// The "provisional evaluation cache" is used to store intermediate cache results
2710 /// when solving auto traits. Auto traits are unusual in that they can support
2711 /// cycles. So, for example, a "proof tree" like this would be ok:
2712 ///
2713 /// - `Foo<T>: Send` :-
2714 ///   - `Bar<T>: Send` :-
2715 ///     - `Foo<T>: Send` -- cycle, but ok
2716 ///   - `Baz<T>: Send`
2717 ///
2718 /// Here, to prove `Foo<T>: Send`, we have to prove `Bar<T>: Send` and
2719 /// `Baz<T>: Send`. Proving `Bar<T>: Send` in turn required `Foo<T>: Send`.
2720 /// For non-auto traits, this cycle would be an error, but for auto traits (because
2721 /// they are coinductive) it is considered ok.
2722 ///
2723 /// However, there is a complication: at the point where we have
2724 /// "proven" `Bar<T>: Send`, we have in fact only proven it
2725 /// *provisionally*. In particular, we proved that `Bar<T>: Send`
2726 /// *under the assumption* that `Foo<T>: Send`. But what if we later
2727 /// find out this assumption is wrong?  Specifically, we could
2728 /// encounter some kind of error proving `Baz<T>: Send`. In that case,
2729 /// `Bar<T>: Send` didn't turn out to be true.
2730 ///
2731 /// In Issue #60010, we found a bug in rustc where it would cache
2732 /// these intermediate results. This was fixed in #60444 by disabling
2733 /// *all* caching for things involved in a cycle -- in our example,
2734 /// that would mean we don't cache that `Bar<T>: Send`. But this led
2735 /// to large slowdowns.
2736 ///
2737 /// Specifically, imagine this scenario, where proving `Baz<T>: Send`
2738 /// first requires proving `Bar<T>: Send` (which is true:
2739 ///
2740 /// - `Foo<T>: Send` :-
2741 ///   - `Bar<T>: Send` :-
2742 ///     - `Foo<T>: Send` -- cycle, but ok
2743 ///   - `Baz<T>: Send`
2744 ///     - `Bar<T>: Send` -- would be nice for this to be a cache hit!
2745 ///     - `*const T: Send` -- but what if we later encounter an error?
2746 ///
2747 /// The *provisional evaluation cache* resolves this issue. It stores
2748 /// cache results that we've proven but which were involved in a cycle
2749 /// in some way. We track the minimal stack depth (i.e., the
2750 /// farthest from the top of the stack) that we are dependent on.
2751 /// The idea is that the cache results within are all valid -- so long as
2752 /// none of the nodes in between the current node and the node at that minimum
2753 /// depth result in an error (in which case the cached results are just thrown away).
2754 ///
2755 /// During evaluation, we consult this provisional cache and rely on
2756 /// it. Accessing a cached value is considered equivalent to accessing
2757 /// a result at `reached_depth`, so it marks the *current* solution as
2758 /// provisional as well. If an error is encountered, we toss out any
2759 /// provisional results added from the subtree that encountered the
2760 /// error. When we pop the node at `reached_depth` from the stack, we
2761 /// can commit all the things that remain in the provisional cache.
2762 struct ProvisionalEvaluationCache<'tcx> {
2763     /// next "depth first number" to issue -- just a counter
2764     dfn: Cell<usize>,
2765 
2766     /// Map from cache key to the provisionally evaluated thing.
2767     /// The cache entries contain the result but also the DFN in which they
2768     /// were added. The DFN is used to clear out values on failure.
2769     ///
2770     /// Imagine we have a stack like:
2771     ///
2772     /// - `A B C` and we add a cache for the result of C (DFN 2)
2773     /// - Then we have a stack `A B D` where `D` has DFN 3
2774     /// - We try to solve D by evaluating E: `A B D E` (DFN 4)
2775     /// - `E` generates various cache entries which have cyclic dependencies on `B`
2776     ///   - `A B D E F` and so forth
2777     ///   - the DFN of `F` for example would be 5
2778     /// - then we determine that `E` is in error -- we will then clear
2779     ///   all cache values whose DFN is >= 4 -- in this case, that
2780     ///   means the cached value for `F`.
2781     map: RefCell<FxIndexMap<ty::PolyTraitPredicate<'tcx>, ProvisionalEvaluation>>,
2782 
2783     /// The stack of args that we assume to be true because a `WF(arg)` predicate
2784     /// is on the stack above (and because of wellformedness is coinductive).
2785     /// In an "ideal" world, this would share a stack with trait predicates in
2786     /// `TraitObligationStack`. However, trait predicates are *much* hotter than
2787     /// `WellFormed` predicates, and it's very likely that the additional matches
2788     /// will have a perf effect. The value here is the well-formed `GenericArg`
2789     /// and the depth of the trait predicate *above* that well-formed predicate.
2790     wf_args: RefCell<Vec<(ty::GenericArg<'tcx>, usize)>>,
2791 }
2792 
2793 /// A cache value for the provisional cache: contains the depth-first
2794 /// number (DFN) and result.
2795 #[derive(Copy, Clone, Debug)]
2796 struct ProvisionalEvaluation {
2797     from_dfn: usize,
2798     reached_depth: usize,
2799     result: EvaluationResult,
2800 }
2801 
2802 impl<'tcx> Default for ProvisionalEvaluationCache<'tcx> {
default() -> Self2803     fn default() -> Self {
2804         Self { dfn: Cell::new(0), map: Default::default(), wf_args: Default::default() }
2805     }
2806 }
2807 
2808 impl<'tcx> ProvisionalEvaluationCache<'tcx> {
2809     /// Get the next DFN in sequence (basically a counter).
next_dfn(&self) -> usize2810     fn next_dfn(&self) -> usize {
2811         let result = self.dfn.get();
2812         self.dfn.set(result + 1);
2813         result
2814     }
2815 
2816     /// Check the provisional cache for any result for
2817     /// `fresh_trait_ref`. If there is a hit, then you must consider
2818     /// it an access to the stack slots at depth
2819     /// `reached_depth` (from the returned value).
get_provisional( &self, fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> Option<ProvisionalEvaluation>2820     fn get_provisional(
2821         &self,
2822         fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
2823     ) -> Option<ProvisionalEvaluation> {
2824         debug!(
2825             ?fresh_trait_pred,
2826             "get_provisional = {:#?}",
2827             self.map.borrow().get(&fresh_trait_pred),
2828         );
2829         Some(*self.map.borrow().get(&fresh_trait_pred)?)
2830     }
2831 
2832     /// Insert a provisional result into the cache. The result came
2833     /// from the node with the given DFN. It accessed a minimum depth
2834     /// of `reached_depth` to compute. It evaluated `fresh_trait_pred`
2835     /// and resulted in `result`.
insert_provisional( &self, from_dfn: usize, reached_depth: usize, fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, result: EvaluationResult, )2836     fn insert_provisional(
2837         &self,
2838         from_dfn: usize,
2839         reached_depth: usize,
2840         fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
2841         result: EvaluationResult,
2842     ) {
2843         debug!(?from_dfn, ?fresh_trait_pred, ?result, "insert_provisional");
2844 
2845         let mut map = self.map.borrow_mut();
2846 
2847         // Subtle: when we complete working on the DFN `from_dfn`, anything
2848         // that remains in the provisional cache must be dependent on some older
2849         // stack entry than `from_dfn`. We have to update their depth with our transitive
2850         // depth in that case or else it would be referring to some popped note.
2851         //
2852         // Example:
2853         // A (reached depth 0)
2854         //   ...
2855         //      B // depth 1 -- reached depth = 0
2856         //          C // depth 2 -- reached depth = 1 (should be 0)
2857         //              B
2858         //          A // depth 0
2859         //   D (reached depth 1)
2860         //      C (cache -- reached depth = 2)
2861         for (_k, v) in &mut *map {
2862             if v.from_dfn >= from_dfn {
2863                 v.reached_depth = reached_depth.min(v.reached_depth);
2864             }
2865         }
2866 
2867         map.insert(fresh_trait_pred, ProvisionalEvaluation { from_dfn, reached_depth, result });
2868     }
2869 
2870     /// Invoked when the node with dfn `dfn` does not get a successful
2871     /// result. This will clear out any provisional cache entries
2872     /// that were added since `dfn` was created. This is because the
2873     /// provisional entries are things which must assume that the
2874     /// things on the stack at the time of their creation succeeded --
2875     /// since the failing node is presently at the top of the stack,
2876     /// these provisional entries must either depend on it or some
2877     /// ancestor of it.
on_failure(&self, dfn: usize)2878     fn on_failure(&self, dfn: usize) {
2879         debug!(?dfn, "on_failure");
2880         self.map.borrow_mut().retain(|key, eval| {
2881             if !eval.from_dfn >= dfn {
2882                 debug!("on_failure: removing {:?}", key);
2883                 false
2884             } else {
2885                 true
2886             }
2887         });
2888     }
2889 
2890     /// Invoked when the node at depth `depth` completed without
2891     /// depending on anything higher in the stack (if that completion
2892     /// was a failure, then `on_failure` should have been invoked
2893     /// already).
2894     ///
2895     /// Note that we may still have provisional cache items remaining
2896     /// in the cache when this is done. For example, if there is a
2897     /// cycle:
2898     ///
2899     /// * A depends on...
2900     ///     * B depends on A
2901     ///     * C depends on...
2902     ///         * D depends on C
2903     ///     * ...
2904     ///
2905     /// Then as we complete the C node we will have a provisional cache
2906     /// with results for A, B, C, and D. This method would clear out
2907     /// the C and D results, but leave A and B provisional.
2908     ///
2909     /// This is determined based on the DFN: we remove any provisional
2910     /// results created since `dfn` started (e.g., in our example, dfn
2911     /// would be 2, representing the C node, and hence we would
2912     /// remove the result for D, which has DFN 3, but not the results for
2913     /// A and B, which have DFNs 0 and 1 respectively).
2914     ///
2915     /// Note that we *do not* attempt to cache these cycle participants
2916     /// in the evaluation cache. Doing so would require carefully computing
2917     /// the correct `DepNode` to store in the cache entry:
2918     /// cycle participants may implicitly depend on query results
2919     /// related to other participants in the cycle, due to our logic
2920     /// which examines the evaluation stack.
2921     ///
2922     /// We used to try to perform this caching,
2923     /// but it lead to multiple incremental compilation ICEs
2924     /// (see #92987 and #96319), and was very hard to understand.
2925     /// Fortunately, removing the caching didn't seem to
2926     /// have a performance impact in practice.
on_completion(&self, dfn: usize)2927     fn on_completion(&self, dfn: usize) {
2928         debug!(?dfn, "on_completion");
2929         self.map.borrow_mut().retain(|fresh_trait_pred, eval| {
2930             if eval.from_dfn >= dfn {
2931                 debug!(?fresh_trait_pred, ?eval, "on_completion");
2932                 return false;
2933             }
2934             true
2935         });
2936     }
2937 }
2938 
2939 #[derive(Copy, Clone)]
2940 struct TraitObligationStackList<'o, 'tcx> {
2941     cache: &'o ProvisionalEvaluationCache<'tcx>,
2942     head: Option<&'o TraitObligationStack<'o, 'tcx>>,
2943 }
2944 
2945 impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> {
empty(cache: &'o ProvisionalEvaluationCache<'tcx>) -> TraitObligationStackList<'o, 'tcx>2946     fn empty(cache: &'o ProvisionalEvaluationCache<'tcx>) -> TraitObligationStackList<'o, 'tcx> {
2947         TraitObligationStackList { cache, head: None }
2948     }
2949 
with(r: &'o TraitObligationStack<'o, 'tcx>) -> TraitObligationStackList<'o, 'tcx>2950     fn with(r: &'o TraitObligationStack<'o, 'tcx>) -> TraitObligationStackList<'o, 'tcx> {
2951         TraitObligationStackList { cache: r.cache(), head: Some(r) }
2952     }
2953 
head(&self) -> Option<&'o TraitObligationStack<'o, 'tcx>>2954     fn head(&self) -> Option<&'o TraitObligationStack<'o, 'tcx>> {
2955         self.head
2956     }
2957 
depth(&self) -> usize2958     fn depth(&self) -> usize {
2959         if let Some(head) = self.head { head.depth } else { 0 }
2960     }
2961 }
2962 
2963 impl<'o, 'tcx> Iterator for TraitObligationStackList<'o, 'tcx> {
2964     type Item = &'o TraitObligationStack<'o, 'tcx>;
2965 
next(&mut self) -> Option<&'o TraitObligationStack<'o, 'tcx>>2966     fn next(&mut self) -> Option<&'o TraitObligationStack<'o, 'tcx>> {
2967         let o = self.head?;
2968         *self = o.previous;
2969         Some(o)
2970     }
2971 }
2972 
2973 impl<'o, 'tcx> fmt::Debug for TraitObligationStack<'o, 'tcx> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2974     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2975         write!(f, "TraitObligationStack({:?})", self.obligation)
2976     }
2977 }
2978 
2979 pub enum ProjectionMatchesProjection {
2980     Yes,
2981     Ambiguous,
2982     No,
2983 }
2984 
2985 /// Replace all regions inside the generator interior with late bound regions.
2986 /// Note that each region slot in the types gets a new fresh late bound region, which means that
2987 /// none of the regions inside relate to any other, even if typeck had previously found constraints
2988 /// that would cause them to be related.
2989 #[instrument(level = "trace", skip(infcx), ret)]
bind_generator_hidden_types_above<'tcx>( infcx: &InferCtxt<'tcx>, def_id: DefId, substs: ty::SubstsRef<'tcx>, bound_vars: &ty::List<ty::BoundVariableKind>, ) -> ty::Binder<'tcx, Vec<Ty<'tcx>>>2990 fn bind_generator_hidden_types_above<'tcx>(
2991     infcx: &InferCtxt<'tcx>,
2992     def_id: DefId,
2993     substs: ty::SubstsRef<'tcx>,
2994     bound_vars: &ty::List<ty::BoundVariableKind>,
2995 ) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
2996     let tcx = infcx.tcx;
2997     let mut seen_tys = FxHashSet::default();
2998 
2999     let considering_regions = infcx.considering_regions;
3000 
3001     let num_bound_variables = bound_vars.len() as u32;
3002     let mut counter = num_bound_variables;
3003 
3004     let hidden_types: Vec<_> = tcx
3005         .generator_hidden_types(def_id)
3006         // Deduplicate tys to avoid repeated work.
3007         .filter(|bty| seen_tys.insert(*bty))
3008         .map(|bty| {
3009             let mut ty = bty.subst(tcx, substs);
3010 
3011             // Only remap erased regions if we use them.
3012             if considering_regions {
3013                 ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() {
3014                     ty::ReErased => {
3015                         let br = ty::BoundRegion {
3016                             var: ty::BoundVar::from_u32(counter),
3017                             kind: ty::BrAnon(None),
3018                         };
3019                         counter += 1;
3020                         ty::Region::new_late_bound(tcx, current_depth, br)
3021                     }
3022                     r => bug!("unexpected region: {r:?}"),
3023                 })
3024             }
3025 
3026             ty
3027         })
3028         .collect();
3029     if considering_regions {
3030         debug_assert!(!hidden_types.has_erased_regions());
3031     }
3032     let bound_vars = tcx.mk_bound_variable_kinds_from_iter(bound_vars.iter().chain(
3033         (num_bound_variables..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon(None))),
3034     ));
3035     ty::Binder::bind_with_vars(hidden_types, bound_vars)
3036 }
3037