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