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