• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Code for projecting associated types out of trait references.
2 
3 use super::check_substs_compatible;
4 use super::specialization_graph;
5 use super::translate_substs;
6 use super::util;
7 use super::ImplSourceUserDefinedData;
8 use super::MismatchedProjectionTypes;
9 use super::Obligation;
10 use super::ObligationCause;
11 use super::PredicateObligation;
12 use super::Selection;
13 use super::SelectionContext;
14 use super::SelectionError;
15 use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
16 
17 use crate::errors::InherentProjectionNormalizationOverflow;
18 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
19 use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
20 use crate::traits::error_reporting::TypeErrCtxtExt as _;
21 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
22 use crate::traits::select::ProjectionMatchesProjection;
23 use rustc_data_structures::sso::SsoHashSet;
24 use rustc_data_structures::stack::ensure_sufficient_stack;
25 use rustc_errors::ErrorGuaranteed;
26 use rustc_hir::def::DefKind;
27 use rustc_hir::lang_items::LangItem;
28 use rustc_infer::infer::at::At;
29 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
30 use rustc_infer::infer::DefineOpaqueTypes;
31 use rustc_infer::traits::FulfillmentError;
32 use rustc_infer::traits::ObligationCauseCode;
33 use rustc_infer::traits::TraitEngine;
34 use rustc_middle::traits::select::OverflowError;
35 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
36 use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
37 use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
38 use rustc_span::symbol::sym;
39 
40 use std::collections::BTreeMap;
41 
42 pub use rustc_middle::traits::Reveal;
43 
44 pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPredicate<'tcx>>;
45 
46 pub type ProjectionObligation<'tcx> = Obligation<'tcx, ty::ProjectionPredicate<'tcx>>;
47 
48 pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::AliasTy<'tcx>>;
49 
50 pub(super) struct InProgress;
51 
52 pub trait NormalizeExt<'tcx> {
53     /// Normalize a value using the `AssocTypeNormalizer`.
54     ///
55     /// This normalization should be used when the type contains inference variables or the
56     /// projection may be fallible.
normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>57     fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>;
58 
59     /// Deeply normalizes `value`, replacing all aliases which can by normalized in
60     /// the current environment. In the new solver this errors in case normalization
61     /// fails or is ambiguous. This only normalizes opaque types with `Reveal::All`.
62     ///
63     /// In the old solver this simply uses `normalizes` and adds the nested obligations
64     /// to the `fulfill_cx`. This is necessary as we otherwise end up recomputing the
65     /// same goals in both a temporary and the shared context which negatively impacts
66     /// performance as these don't share caching.
67     ///
68     /// FIXME(-Ztrait-solver=next): This has the same behavior as `traits::fully_normalize`
69     /// in the new solver, but because of performance reasons, we currently reuse an
70     /// existing fulfillment context in the old solver. Once we also eagerly prove goals with
71     /// the old solver or have removed the old solver, remove `traits::fully_normalize` and
72     /// rename this function to `At::fully_normalize`.
deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>( self, value: T, fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Result<T, Vec<FulfillmentError<'tcx>>>73     fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
74         self,
75         value: T,
76         fulfill_cx: &mut dyn TraitEngine<'tcx>,
77     ) -> Result<T, Vec<FulfillmentError<'tcx>>>;
78 }
79 
80 impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> InferOk<'tcx, T>81     fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> InferOk<'tcx, T> {
82         if self.infcx.next_trait_solver() {
83             InferOk { value, obligations: Vec::new() }
84         } else {
85             let mut selcx = SelectionContext::new(self.infcx);
86             let Normalized { value, obligations } =
87                 normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
88             InferOk { value, obligations }
89         }
90     }
91 
deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>( self, value: T, fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Result<T, Vec<FulfillmentError<'tcx>>>92     fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
93         self,
94         value: T,
95         fulfill_cx: &mut dyn TraitEngine<'tcx>,
96     ) -> Result<T, Vec<FulfillmentError<'tcx>>> {
97         if self.infcx.next_trait_solver() {
98             crate::solve::deeply_normalize(self, value)
99         } else {
100             let value = self
101                 .normalize(value)
102                 .into_value_registering_obligations(self.infcx, &mut *fulfill_cx);
103             let errors = fulfill_cx.select_where_possible(self.infcx);
104             let value = self.infcx.resolve_vars_if_possible(value);
105             if errors.is_empty() { Ok(value) } else { Err(errors) }
106         }
107     }
108 }
109 
110 /// When attempting to resolve `<T as TraitRef>::Name` ...
111 #[derive(Debug)]
112 pub enum ProjectionError<'tcx> {
113     /// ...we found multiple sources of information and couldn't resolve the ambiguity.
114     TooManyCandidates,
115 
116     /// ...an error occurred matching `T : TraitRef`
117     TraitSelectionError(SelectionError<'tcx>),
118 }
119 
120 #[derive(PartialEq, Eq, Debug)]
121 enum ProjectionCandidate<'tcx> {
122     /// From a where-clause in the env or object type
123     ParamEnv(ty::PolyProjectionPredicate<'tcx>),
124 
125     /// From the definition of `Trait` when you have something like
126     /// `<<A as Trait>::B as Trait2>::C`.
127     TraitDef(ty::PolyProjectionPredicate<'tcx>),
128 
129     /// Bounds specified on an object type
130     Object(ty::PolyProjectionPredicate<'tcx>),
131 
132     /// From an "impl" (or a "pseudo-impl" returned by select)
133     Select(Selection<'tcx>),
134 
135     ImplTraitInTrait(ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>),
136 }
137 
138 enum ProjectionCandidateSet<'tcx> {
139     None,
140     Single(ProjectionCandidate<'tcx>),
141     Ambiguous,
142     Error(SelectionError<'tcx>),
143 }
144 
145 impl<'tcx> ProjectionCandidateSet<'tcx> {
mark_ambiguous(&mut self)146     fn mark_ambiguous(&mut self) {
147         *self = ProjectionCandidateSet::Ambiguous;
148     }
149 
mark_error(&mut self, err: SelectionError<'tcx>)150     fn mark_error(&mut self, err: SelectionError<'tcx>) {
151         *self = ProjectionCandidateSet::Error(err);
152     }
153 
154     // Returns true if the push was successful, or false if the candidate
155     // was discarded -- this could be because of ambiguity, or because
156     // a higher-priority candidate is already there.
push_candidate(&mut self, candidate: ProjectionCandidate<'tcx>) -> bool157     fn push_candidate(&mut self, candidate: ProjectionCandidate<'tcx>) -> bool {
158         use self::ProjectionCandidate::*;
159         use self::ProjectionCandidateSet::*;
160 
161         // This wacky variable is just used to try and
162         // make code readable and avoid confusing paths.
163         // It is assigned a "value" of `()` only on those
164         // paths in which we wish to convert `*self` to
165         // ambiguous (and return false, because the candidate
166         // was not used). On other paths, it is not assigned,
167         // and hence if those paths *could* reach the code that
168         // comes after the match, this fn would not compile.
169         let convert_to_ambiguous;
170 
171         match self {
172             None => {
173                 *self = Single(candidate);
174                 return true;
175             }
176 
177             Single(current) => {
178                 // Duplicates can happen inside ParamEnv. In the case, we
179                 // perform a lazy deduplication.
180                 if current == &candidate {
181                     return false;
182                 }
183 
184                 // Prefer where-clauses. As in select, if there are multiple
185                 // candidates, we prefer where-clause candidates over impls. This
186                 // may seem a bit surprising, since impls are the source of
187                 // "truth" in some sense, but in fact some of the impls that SEEM
188                 // applicable are not, because of nested obligations. Where
189                 // clauses are the safer choice. See the comment on
190                 // `select::SelectionCandidate` and #21974 for more details.
191                 match (current, candidate) {
192                     (ParamEnv(..), ParamEnv(..)) => convert_to_ambiguous = (),
193                     (ParamEnv(..), _) => return false,
194                     (_, ParamEnv(..)) => unreachable!(),
195                     (_, _) => convert_to_ambiguous = (),
196                 }
197             }
198 
199             Ambiguous | Error(..) => {
200                 return false;
201             }
202         }
203 
204         // We only ever get here when we moved from a single candidate
205         // to ambiguous.
206         let () = convert_to_ambiguous;
207         *self = Ambiguous;
208         false
209     }
210 }
211 
212 /// States returned from `poly_project_and_unify_type`. Takes the place
213 /// of the old return type, which was:
214 /// ```ignore (not-rust)
215 /// Result<
216 ///     Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
217 ///     MismatchedProjectionTypes<'tcx>,
218 /// >
219 /// ```
220 pub(super) enum ProjectAndUnifyResult<'tcx> {
221     /// The projection bound holds subject to the given obligations. If the
222     /// projection cannot be normalized because the required trait bound does
223     /// not hold, this is returned, with `obligations` being a predicate that
224     /// cannot be proven.
225     Holds(Vec<PredicateObligation<'tcx>>),
226     /// The projection cannot be normalized due to ambiguity. Resolving some
227     /// inference variables in the projection may fix this.
228     FailedNormalization,
229     /// The project cannot be normalized because `poly_project_and_unify_type`
230     /// is called recursively while normalizing the same projection.
231     Recursive,
232     // the projection can be normalized, but is not equal to the expected type.
233     // Returns the type error that arose from the mismatch.
234     MismatchedProjectionTypes(MismatchedProjectionTypes<'tcx>),
235 }
236 
237 /// Evaluates constraints of the form:
238 /// ```ignore (not-rust)
239 /// for<...> <T as Trait>::U == V
240 /// ```
241 /// If successful, this may result in additional obligations. Also returns
242 /// the projection cache key used to track these additional obligations.
243 #[instrument(level = "debug", skip(selcx))]
poly_project_and_unify_type<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &PolyProjectionObligation<'tcx>, ) -> ProjectAndUnifyResult<'tcx>244 pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
245     selcx: &mut SelectionContext<'cx, 'tcx>,
246     obligation: &PolyProjectionObligation<'tcx>,
247 ) -> ProjectAndUnifyResult<'tcx> {
248     let infcx = selcx.infcx;
249     let r = infcx.commit_if_ok(|_snapshot| {
250         let old_universe = infcx.universe();
251         let placeholder_predicate =
252             infcx.instantiate_binder_with_placeholders(obligation.predicate);
253         let new_universe = infcx.universe();
254 
255         let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate);
256         match project_and_unify_type(selcx, &placeholder_obligation) {
257             ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e),
258             ProjectAndUnifyResult::Holds(obligations)
259                 if old_universe != new_universe
260                     && selcx.tcx().features().generic_associated_types_extended =>
261             {
262                 // If the `generic_associated_types_extended` feature is active, then we ignore any
263                 // obligations references lifetimes from any universe greater than or equal to the
264                 // universe just created. Otherwise, we can end up with something like `for<'a> I: 'a`,
265                 // which isn't quite what we want. Ideally, we want either an implied
266                 // `for<'a where I: 'a> I: 'a` or we want to "lazily" check these hold when we
267                 // substitute concrete regions. There is design work to be done here; until then,
268                 // however, this allows experimenting potential GAT features without running into
269                 // well-formedness issues.
270                 let new_obligations = obligations
271                     .into_iter()
272                     .filter(|obligation| {
273                         let mut visitor = MaxUniverse::new();
274                         obligation.predicate.visit_with(&mut visitor);
275                         visitor.max_universe() < new_universe
276                     })
277                     .collect();
278                 Ok(ProjectAndUnifyResult::Holds(new_obligations))
279             }
280             other => Ok(other),
281         }
282     });
283 
284     match r {
285         Ok(inner) => inner,
286         Err(err) => ProjectAndUnifyResult::MismatchedProjectionTypes(err),
287     }
288 }
289 
290 /// Evaluates constraints of the form:
291 /// ```ignore (not-rust)
292 /// <T as Trait>::U == V
293 /// ```
294 /// If successful, this may result in additional obligations.
295 ///
296 /// See [poly_project_and_unify_type] for an explanation of the return value.
297 #[instrument(level = "debug", skip(selcx))]
project_and_unify_type<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionObligation<'tcx>, ) -> ProjectAndUnifyResult<'tcx>298 fn project_and_unify_type<'cx, 'tcx>(
299     selcx: &mut SelectionContext<'cx, 'tcx>,
300     obligation: &ProjectionObligation<'tcx>,
301 ) -> ProjectAndUnifyResult<'tcx> {
302     let mut obligations = vec![];
303 
304     let infcx = selcx.infcx;
305     let normalized = match opt_normalize_projection_type(
306         selcx,
307         obligation.param_env,
308         obligation.predicate.projection_ty,
309         obligation.cause.clone(),
310         obligation.recursion_depth,
311         &mut obligations,
312     ) {
313         Ok(Some(n)) => n,
314         Ok(None) => return ProjectAndUnifyResult::FailedNormalization,
315         Err(InProgress) => return ProjectAndUnifyResult::Recursive,
316     };
317     debug!(?normalized, ?obligations, "project_and_unify_type result");
318     let actual = obligation.predicate.term;
319     // For an example where this is necessary see tests/ui/impl-trait/nested-return-type2.rs
320     // This allows users to omit re-mentioning all bounds on an associated type and just use an
321     // `impl Trait` for the assoc type to add more bounds.
322     let InferOk { value: actual, obligations: new } =
323         selcx.infcx.replace_opaque_types_with_inference_vars(
324             actual,
325             obligation.cause.body_id,
326             obligation.cause.span,
327             obligation.param_env,
328         );
329     obligations.extend(new);
330 
331     // Need to define opaque types to support nested opaque types like `impl Fn() -> impl Trait`
332     match infcx.at(&obligation.cause, obligation.param_env).eq(
333         DefineOpaqueTypes::Yes,
334         normalized,
335         actual,
336     ) {
337         Ok(InferOk { obligations: inferred_obligations, value: () }) => {
338             obligations.extend(inferred_obligations);
339             ProjectAndUnifyResult::Holds(obligations)
340         }
341         Err(err) => {
342             debug!("equating types encountered error {:?}", err);
343             ProjectAndUnifyResult::MismatchedProjectionTypes(MismatchedProjectionTypes { err })
344         }
345     }
346 }
347 
348 /// As `normalize`, but with a custom depth.
normalize_with_depth<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, depth: usize, value: T, ) -> Normalized<'tcx, T> where T: TypeFoldable<TyCtxt<'tcx>>,349 pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>(
350     selcx: &'a mut SelectionContext<'b, 'tcx>,
351     param_env: ty::ParamEnv<'tcx>,
352     cause: ObligationCause<'tcx>,
353     depth: usize,
354     value: T,
355 ) -> Normalized<'tcx, T>
356 where
357     T: TypeFoldable<TyCtxt<'tcx>>,
358 {
359     let mut obligations = Vec::new();
360     let value = normalize_with_depth_to(selcx, param_env, cause, depth, value, &mut obligations);
361     Normalized { value, obligations }
362 }
363 
364 #[instrument(level = "info", skip(selcx, param_env, cause, obligations))]
normalize_with_depth_to<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, depth: usize, value: T, obligations: &mut Vec<PredicateObligation<'tcx>>, ) -> T where T: TypeFoldable<TyCtxt<'tcx>>,365 pub(crate) fn normalize_with_depth_to<'a, 'b, 'tcx, T>(
366     selcx: &'a mut SelectionContext<'b, 'tcx>,
367     param_env: ty::ParamEnv<'tcx>,
368     cause: ObligationCause<'tcx>,
369     depth: usize,
370     value: T,
371     obligations: &mut Vec<PredicateObligation<'tcx>>,
372 ) -> T
373 where
374     T: TypeFoldable<TyCtxt<'tcx>>,
375 {
376     debug!(obligations.len = obligations.len());
377     let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth, obligations);
378     let result = ensure_sufficient_stack(|| normalizer.fold(value));
379     debug!(?result, obligations.len = normalizer.obligations.len());
380     debug!(?normalizer.obligations,);
381     result
382 }
383 
384 #[instrument(level = "info", skip(selcx, param_env, cause, obligations))]
try_normalize_with_depth_to<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, depth: usize, value: T, obligations: &mut Vec<PredicateObligation<'tcx>>, ) -> T where T: TypeFoldable<TyCtxt<'tcx>>,385 pub(crate) fn try_normalize_with_depth_to<'a, 'b, 'tcx, T>(
386     selcx: &'a mut SelectionContext<'b, 'tcx>,
387     param_env: ty::ParamEnv<'tcx>,
388     cause: ObligationCause<'tcx>,
389     depth: usize,
390     value: T,
391     obligations: &mut Vec<PredicateObligation<'tcx>>,
392 ) -> T
393 where
394     T: TypeFoldable<TyCtxt<'tcx>>,
395 {
396     debug!(obligations.len = obligations.len());
397     let mut normalizer = AssocTypeNormalizer::new_without_eager_inference_replacement(
398         selcx,
399         param_env,
400         cause,
401         depth,
402         obligations,
403     );
404     let result = ensure_sufficient_stack(|| normalizer.fold(value));
405     debug!(?result, obligations.len = normalizer.obligations.len());
406     debug!(?normalizer.obligations,);
407     result
408 }
409 
needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>( value: &T, reveal: Reveal, ) -> bool410 pub(crate) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
411     value: &T,
412     reveal: Reveal,
413 ) -> bool {
414     match reveal {
415         Reveal::UserFacing => value.has_type_flags(
416             ty::TypeFlags::HAS_TY_PROJECTION
417                 | ty::TypeFlags::HAS_TY_INHERENT
418                 | ty::TypeFlags::HAS_CT_PROJECTION,
419         ),
420         Reveal::All => value.has_type_flags(
421             ty::TypeFlags::HAS_TY_PROJECTION
422                 | ty::TypeFlags::HAS_TY_INHERENT
423                 | ty::TypeFlags::HAS_TY_OPAQUE
424                 | ty::TypeFlags::HAS_CT_PROJECTION,
425         ),
426     }
427 }
428 
429 struct AssocTypeNormalizer<'a, 'b, 'tcx> {
430     selcx: &'a mut SelectionContext<'b, 'tcx>,
431     param_env: ty::ParamEnv<'tcx>,
432     cause: ObligationCause<'tcx>,
433     obligations: &'a mut Vec<PredicateObligation<'tcx>>,
434     depth: usize,
435     universes: Vec<Option<ty::UniverseIndex>>,
436     /// If true, when a projection is unable to be completed, an inference
437     /// variable will be created and an obligation registered to project to that
438     /// inference variable. Also, constants will be eagerly evaluated.
439     eager_inference_replacement: bool,
440 }
441 
442 impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
new( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &'a mut Vec<PredicateObligation<'tcx>>, ) -> AssocTypeNormalizer<'a, 'b, 'tcx>443     fn new(
444         selcx: &'a mut SelectionContext<'b, 'tcx>,
445         param_env: ty::ParamEnv<'tcx>,
446         cause: ObligationCause<'tcx>,
447         depth: usize,
448         obligations: &'a mut Vec<PredicateObligation<'tcx>>,
449     ) -> AssocTypeNormalizer<'a, 'b, 'tcx> {
450         debug_assert!(!selcx.infcx.next_trait_solver());
451         AssocTypeNormalizer {
452             selcx,
453             param_env,
454             cause,
455             obligations,
456             depth,
457             universes: vec![],
458             eager_inference_replacement: true,
459         }
460     }
461 
new_without_eager_inference_replacement( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &'a mut Vec<PredicateObligation<'tcx>>, ) -> AssocTypeNormalizer<'a, 'b, 'tcx>462     fn new_without_eager_inference_replacement(
463         selcx: &'a mut SelectionContext<'b, 'tcx>,
464         param_env: ty::ParamEnv<'tcx>,
465         cause: ObligationCause<'tcx>,
466         depth: usize,
467         obligations: &'a mut Vec<PredicateObligation<'tcx>>,
468     ) -> AssocTypeNormalizer<'a, 'b, 'tcx> {
469         AssocTypeNormalizer {
470             selcx,
471             param_env,
472             cause,
473             obligations,
474             depth,
475             universes: vec![],
476             eager_inference_replacement: false,
477         }
478     }
479 
fold<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T480     fn fold<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T {
481         let value = self.selcx.infcx.resolve_vars_if_possible(value);
482         debug!(?value);
483 
484         assert!(
485             !value.has_escaping_bound_vars(),
486             "Normalizing {:?} without wrapping in a `Binder`",
487             value
488         );
489 
490         if !needs_normalization(&value, self.param_env.reveal()) {
491             value
492         } else {
493             value.fold_with(self)
494         }
495     }
496 }
497 
498 impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx> {
interner(&self) -> TyCtxt<'tcx>499     fn interner(&self) -> TyCtxt<'tcx> {
500         self.selcx.tcx()
501     }
502 
fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T>503     fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
504         &mut self,
505         t: ty::Binder<'tcx, T>,
506     ) -> ty::Binder<'tcx, T> {
507         self.universes.push(None);
508         let t = t.super_fold_with(self);
509         self.universes.pop();
510         t
511     }
512 
fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx>513     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
514         if !needs_normalization(&ty, self.param_env.reveal()) {
515             return ty;
516         }
517 
518         let (kind, data) = match *ty.kind() {
519             ty::Alias(kind, alias_ty) => (kind, alias_ty),
520             _ => return ty.super_fold_with(self),
521         };
522 
523         // We try to be a little clever here as a performance optimization in
524         // cases where there are nested projections under binders.
525         // For example:
526         // ```
527         // for<'a> fn(<T as Foo>::One<'a, Box<dyn Bar<'a, Item=<T as Foo>::Two<'a>>>>)
528         // ```
529         // We normalize the substs on the projection before the projecting, but
530         // if we're naive, we'll
531         //   replace bound vars on inner, project inner, replace placeholders on inner,
532         //   replace bound vars on outer, project outer, replace placeholders on outer
533         //
534         // However, if we're a bit more clever, we can replace the bound vars
535         // on the entire type before normalizing nested projections, meaning we
536         //   replace bound vars on outer, project inner,
537         //   project outer, replace placeholders on outer
538         //
539         // This is possible because the inner `'a` will already be a placeholder
540         // when we need to normalize the inner projection
541         //
542         // On the other hand, this does add a bit of complexity, since we only
543         // replace bound vars if the current type is a `Projection` and we need
544         // to make sure we don't forget to fold the substs regardless.
545 
546         match kind {
547             ty::Opaque => {
548                 // Only normalize `impl Trait` outside of type inference, usually in codegen.
549                 match self.param_env.reveal() {
550                     Reveal::UserFacing => ty.super_fold_with(self),
551 
552                     Reveal::All => {
553                         let recursion_limit = self.interner().recursion_limit();
554                         if !recursion_limit.value_within_limit(self.depth) {
555                             self.selcx.infcx.err_ctxt().report_overflow_error(
556                                 &ty,
557                                 self.cause.span,
558                                 true,
559                                 |_| {},
560                             );
561                         }
562 
563                         let substs = data.substs.fold_with(self);
564                         let generic_ty = self.interner().type_of(data.def_id);
565                         let concrete_ty = generic_ty.subst(self.interner(), substs);
566                         self.depth += 1;
567                         let folded_ty = self.fold_ty(concrete_ty);
568                         self.depth -= 1;
569                         folded_ty
570                     }
571                 }
572             }
573 
574             ty::Projection if !data.has_escaping_bound_vars() => {
575                 // This branch is *mostly* just an optimization: when we don't
576                 // have escaping bound vars, we don't need to replace them with
577                 // placeholders (see branch below). *Also*, we know that we can
578                 // register an obligation to *later* project, since we know
579                 // there won't be bound vars there.
580                 let data = data.fold_with(self);
581                 let normalized_ty = if self.eager_inference_replacement {
582                     normalize_projection_type(
583                         self.selcx,
584                         self.param_env,
585                         data,
586                         self.cause.clone(),
587                         self.depth,
588                         &mut self.obligations,
589                     )
590                 } else {
591                     opt_normalize_projection_type(
592                         self.selcx,
593                         self.param_env,
594                         data,
595                         self.cause.clone(),
596                         self.depth,
597                         &mut self.obligations,
598                     )
599                     .ok()
600                     .flatten()
601                     .unwrap_or_else(|| ty.super_fold_with(self).into())
602                 };
603                 debug!(
604                     ?self.depth,
605                     ?ty,
606                     ?normalized_ty,
607                     obligations.len = ?self.obligations.len(),
608                     "AssocTypeNormalizer: normalized type"
609                 );
610                 normalized_ty.ty().unwrap()
611             }
612 
613             ty::Projection => {
614                 // If there are escaping bound vars, we temporarily replace the
615                 // bound vars with placeholders. Note though, that in the case
616                 // that we still can't project for whatever reason (e.g. self
617                 // type isn't known enough), we *can't* register an obligation
618                 // and return an inference variable (since then that obligation
619                 // would have bound vars and that's a can of worms). Instead,
620                 // we just give up and fall back to pretending like we never tried!
621                 //
622                 // Note: this isn't necessarily the final approach here; we may
623                 // want to figure out how to register obligations with escaping vars
624                 // or handle this some other way.
625 
626                 let infcx = self.selcx.infcx;
627                 let (data, mapped_regions, mapped_types, mapped_consts) =
628                     BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
629                 let data = data.fold_with(self);
630                 let normalized_ty = opt_normalize_projection_type(
631                     self.selcx,
632                     self.param_env,
633                     data,
634                     self.cause.clone(),
635                     self.depth,
636                     &mut self.obligations,
637                 )
638                 .ok()
639                 .flatten()
640                 .map(|term| term.ty().unwrap())
641                 .map(|normalized_ty| {
642                     PlaceholderReplacer::replace_placeholders(
643                         infcx,
644                         mapped_regions,
645                         mapped_types,
646                         mapped_consts,
647                         &self.universes,
648                         normalized_ty,
649                     )
650                 })
651                 .unwrap_or_else(|| ty.super_fold_with(self));
652 
653                 debug!(
654                     ?self.depth,
655                     ?ty,
656                     ?normalized_ty,
657                     obligations.len = ?self.obligations.len(),
658                     "AssocTypeNormalizer: normalized type"
659                 );
660                 normalized_ty
661             }
662             ty::Weak => {
663                 let infcx = self.selcx.infcx;
664                 self.obligations.extend(
665                     infcx
666                         .tcx
667                         .predicates_of(data.def_id)
668                         .instantiate_own(infcx.tcx, data.substs)
669                         .map(|(mut predicate, span)| {
670                             if data.has_escaping_bound_vars() {
671                                 (predicate, ..) = BoundVarReplacer::replace_bound_vars(
672                                     infcx,
673                                     &mut self.universes,
674                                     predicate,
675                                 );
676                             }
677                             let mut cause = self.cause.clone();
678                             cause.map_code(|code| {
679                                 ObligationCauseCode::TypeAlias(code, span, data.def_id)
680                             });
681                             Obligation::new(infcx.tcx, cause, self.param_env, predicate)
682                         }),
683                 );
684                 infcx.tcx.type_of(data.def_id).subst(infcx.tcx, data.substs).fold_with(self)
685             }
686 
687             ty::Inherent if !data.has_escaping_bound_vars() => {
688                 // This branch is *mostly* just an optimization: when we don't
689                 // have escaping bound vars, we don't need to replace them with
690                 // placeholders (see branch below). *Also*, we know that we can
691                 // register an obligation to *later* project, since we know
692                 // there won't be bound vars there.
693 
694                 let data = data.fold_with(self);
695 
696                 // FIXME(inherent_associated_types): Do we need to honor `self.eager_inference_replacement`
697                 // here like `ty::Projection`?
698                 normalize_inherent_projection(
699                     self.selcx,
700                     self.param_env,
701                     data,
702                     self.cause.clone(),
703                     self.depth,
704                     &mut self.obligations,
705                 )
706             }
707 
708             ty::Inherent => {
709                 let infcx = self.selcx.infcx;
710                 let (data, mapped_regions, mapped_types, mapped_consts) =
711                     BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
712                 let data = data.fold_with(self);
713                 let ty = normalize_inherent_projection(
714                     self.selcx,
715                     self.param_env,
716                     data,
717                     self.cause.clone(),
718                     self.depth,
719                     &mut self.obligations,
720                 );
721 
722                 PlaceholderReplacer::replace_placeholders(
723                     infcx,
724                     mapped_regions,
725                     mapped_types,
726                     mapped_consts,
727                     &self.universes,
728                     ty,
729                 )
730             }
731         }
732     }
733 
734     #[instrument(skip(self), level = "debug")]
fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx>735     fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
736         let tcx = self.selcx.tcx();
737         if tcx.features().generic_const_exprs
738             || !needs_normalization(&constant, self.param_env.reveal())
739         {
740             constant
741         } else {
742             let constant = constant.super_fold_with(self);
743             debug!(?constant, ?self.param_env);
744             with_replaced_escaping_bound_vars(
745                 self.selcx.infcx,
746                 &mut self.universes,
747                 constant,
748                 |constant| constant.eval(tcx, self.param_env),
749             )
750         }
751     }
752 
753     #[inline]
fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx>754     fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
755         if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) {
756             p.super_fold_with(self)
757         } else {
758             p
759         }
760     }
761 }
762 
763 pub struct BoundVarReplacer<'me, 'tcx> {
764     infcx: &'me InferCtxt<'tcx>,
765     // These three maps track the bound variable that were replaced by placeholders. It might be
766     // nice to remove these since we already have the `kind` in the placeholder; we really just need
767     // the `var` (but we *could* bring that into scope if we were to track them as we pass them).
768     mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
769     mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
770     mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
771     // The current depth relative to *this* folding, *not* the entire normalization. In other words,
772     // the depth of binders we've passed here.
773     current_index: ty::DebruijnIndex,
774     // The `UniverseIndex` of the binding levels above us. These are optional, since we are lazy:
775     // we don't actually create a universe until we see a bound var we have to replace.
776     universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>,
777 }
778 
779 /// Executes `f` on `value` after replacing all escaping bound variables with placeholders
780 /// and then replaces these placeholders with the original bound variables in the result.
781 ///
782 /// In most places, bound variables should be replaced right when entering a binder, making
783 /// this function unnecessary. However, normalization currently does not do that, so we have
784 /// to do this lazily.
785 ///
786 /// You should not add any additional uses of this function, at least not without first
787 /// discussing it with t-types.
788 ///
789 /// FIXME(@lcnr): We may even consider experimenting with eagerly replacing bound vars during
790 /// normalization as well, at which point this function will be unnecessary and can be removed.
with_replaced_escaping_bound_vars< 'a, 'tcx, T: TypeFoldable<TyCtxt<'tcx>>, R: TypeFoldable<TyCtxt<'tcx>>, >( infcx: &'a InferCtxt<'tcx>, universe_indices: &'a mut Vec<Option<ty::UniverseIndex>>, value: T, f: impl FnOnce(T) -> R, ) -> R791 pub fn with_replaced_escaping_bound_vars<
792     'a,
793     'tcx,
794     T: TypeFoldable<TyCtxt<'tcx>>,
795     R: TypeFoldable<TyCtxt<'tcx>>,
796 >(
797     infcx: &'a InferCtxt<'tcx>,
798     universe_indices: &'a mut Vec<Option<ty::UniverseIndex>>,
799     value: T,
800     f: impl FnOnce(T) -> R,
801 ) -> R {
802     if value.has_escaping_bound_vars() {
803         let (value, mapped_regions, mapped_types, mapped_consts) =
804             BoundVarReplacer::replace_bound_vars(infcx, universe_indices, value);
805         let result = f(value);
806         PlaceholderReplacer::replace_placeholders(
807             infcx,
808             mapped_regions,
809             mapped_types,
810             mapped_consts,
811             universe_indices,
812             result,
813         )
814     } else {
815         f(value)
816     }
817 }
818 
819 impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
820     /// Returns `Some` if we *were* able to replace bound vars. If there are any bound vars that
821     /// use a binding level above `universe_indices.len()`, we fail.
replace_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>( infcx: &'me InferCtxt<'tcx>, universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>, value: T, ) -> ( T, BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>, BTreeMap<ty::PlaceholderType, ty::BoundTy>, BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>, )822     pub fn replace_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
823         infcx: &'me InferCtxt<'tcx>,
824         universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>,
825         value: T,
826     ) -> (
827         T,
828         BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
829         BTreeMap<ty::PlaceholderType, ty::BoundTy>,
830         BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
831     ) {
832         let mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion> = BTreeMap::new();
833         let mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy> = BTreeMap::new();
834         let mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar> = BTreeMap::new();
835 
836         let mut replacer = BoundVarReplacer {
837             infcx,
838             mapped_regions,
839             mapped_types,
840             mapped_consts,
841             current_index: ty::INNERMOST,
842             universe_indices,
843         };
844 
845         let value = value.fold_with(&mut replacer);
846 
847         (value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts)
848     }
849 
universe_for(&mut self, debruijn: ty::DebruijnIndex) -> ty::UniverseIndex850     fn universe_for(&mut self, debruijn: ty::DebruijnIndex) -> ty::UniverseIndex {
851         let infcx = self.infcx;
852         let index =
853             self.universe_indices.len() + self.current_index.as_usize() - debruijn.as_usize() - 1;
854         let universe = self.universe_indices[index].unwrap_or_else(|| {
855             for i in self.universe_indices.iter_mut().take(index + 1) {
856                 *i = i.or_else(|| Some(infcx.create_next_universe()))
857             }
858             self.universe_indices[index].unwrap()
859         });
860         universe
861     }
862 }
863 
864 impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> {
interner(&self) -> TyCtxt<'tcx>865     fn interner(&self) -> TyCtxt<'tcx> {
866         self.infcx.tcx
867     }
868 
fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T>869     fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
870         &mut self,
871         t: ty::Binder<'tcx, T>,
872     ) -> ty::Binder<'tcx, T> {
873         self.current_index.shift_in(1);
874         let t = t.super_fold_with(self);
875         self.current_index.shift_out(1);
876         t
877     }
878 
fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx>879     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
880         match *r {
881             ty::ReLateBound(debruijn, _)
882                 if debruijn.as_usize() + 1
883                     > self.current_index.as_usize() + self.universe_indices.len() =>
884             {
885                 bug!("Bound vars outside of `self.universe_indices`");
886             }
887             ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => {
888                 let universe = self.universe_for(debruijn);
889                 let p = ty::PlaceholderRegion { universe, bound: br };
890                 self.mapped_regions.insert(p, br);
891                 ty::Region::new_placeholder(self.infcx.tcx, p)
892             }
893             _ => r,
894         }
895     }
896 
fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx>897     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
898         match *t.kind() {
899             ty::Bound(debruijn, _)
900                 if debruijn.as_usize() + 1
901                     > self.current_index.as_usize() + self.universe_indices.len() =>
902             {
903                 bug!("Bound vars outside of `self.universe_indices`");
904             }
905             ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
906                 let universe = self.universe_for(debruijn);
907                 let p = ty::PlaceholderType { universe, bound: bound_ty };
908                 self.mapped_types.insert(p, bound_ty);
909                 Ty::new_placeholder(self.infcx.tcx, p)
910             }
911             _ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
912             _ => t,
913         }
914     }
915 
fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx>916     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
917         match ct.kind() {
918             ty::ConstKind::Bound(debruijn, _)
919                 if debruijn.as_usize() + 1
920                     > self.current_index.as_usize() + self.universe_indices.len() =>
921             {
922                 bug!("Bound vars outside of `self.universe_indices`");
923             }
924             ty::ConstKind::Bound(debruijn, bound_const) if debruijn >= self.current_index => {
925                 let universe = self.universe_for(debruijn);
926                 let p = ty::PlaceholderConst { universe, bound: bound_const };
927                 self.mapped_consts.insert(p, bound_const);
928                 ty::Const::new_placeholder(self.infcx.tcx, p, ct.ty())
929             }
930             _ => ct.super_fold_with(self),
931         }
932     }
933 
fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx>934     fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
935         if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
936     }
937 }
938 
939 /// The inverse of [`BoundVarReplacer`]: replaces placeholders with the bound vars from which they came.
940 pub struct PlaceholderReplacer<'me, 'tcx> {
941     infcx: &'me InferCtxt<'tcx>,
942     mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
943     mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
944     mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
945     universe_indices: &'me [Option<ty::UniverseIndex>],
946     current_index: ty::DebruijnIndex,
947 }
948 
949 impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
replace_placeholders<T: TypeFoldable<TyCtxt<'tcx>>>( infcx: &'me InferCtxt<'tcx>, mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>, mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>, mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>, universe_indices: &'me [Option<ty::UniverseIndex>], value: T, ) -> T950     pub fn replace_placeholders<T: TypeFoldable<TyCtxt<'tcx>>>(
951         infcx: &'me InferCtxt<'tcx>,
952         mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
953         mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
954         mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
955         universe_indices: &'me [Option<ty::UniverseIndex>],
956         value: T,
957     ) -> T {
958         let mut replacer = PlaceholderReplacer {
959             infcx,
960             mapped_regions,
961             mapped_types,
962             mapped_consts,
963             universe_indices,
964             current_index: ty::INNERMOST,
965         };
966         value.fold_with(&mut replacer)
967     }
968 }
969 
970 impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
interner(&self) -> TyCtxt<'tcx>971     fn interner(&self) -> TyCtxt<'tcx> {
972         self.infcx.tcx
973     }
974 
fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T>975     fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
976         &mut self,
977         t: ty::Binder<'tcx, T>,
978     ) -> ty::Binder<'tcx, T> {
979         if !t.has_placeholders() && !t.has_infer_regions() {
980             return t;
981         }
982         self.current_index.shift_in(1);
983         let t = t.super_fold_with(self);
984         self.current_index.shift_out(1);
985         t
986     }
987 
fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx>988     fn fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx> {
989         let r1 = match *r0 {
990             ty::ReVar(vid) => self
991                 .infcx
992                 .inner
993                 .borrow_mut()
994                 .unwrap_region_constraints()
995                 .opportunistic_resolve_var(self.infcx.tcx, vid),
996             _ => r0,
997         };
998 
999         let r2 = match *r1 {
1000             ty::RePlaceholder(p) => {
1001                 let replace_var = self.mapped_regions.get(&p);
1002                 match replace_var {
1003                     Some(replace_var) => {
1004                         let index = self
1005                             .universe_indices
1006                             .iter()
1007                             .position(|u| matches!(u, Some(pu) if *pu == p.universe))
1008                             .unwrap_or_else(|| bug!("Unexpected placeholder universe."));
1009                         let db = ty::DebruijnIndex::from_usize(
1010                             self.universe_indices.len() - index + self.current_index.as_usize() - 1,
1011                         );
1012                         ty::Region::new_late_bound(self.interner(), db, *replace_var)
1013                     }
1014                     None => r1,
1015                 }
1016             }
1017             _ => r1,
1018         };
1019 
1020         debug!(?r0, ?r1, ?r2, "fold_region");
1021 
1022         r2
1023     }
1024 
fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx>1025     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
1026         match *ty.kind() {
1027             ty::Placeholder(p) => {
1028                 let replace_var = self.mapped_types.get(&p);
1029                 match replace_var {
1030                     Some(replace_var) => {
1031                         let index = self
1032                             .universe_indices
1033                             .iter()
1034                             .position(|u| matches!(u, Some(pu) if *pu == p.universe))
1035                             .unwrap_or_else(|| bug!("Unexpected placeholder universe."));
1036                         let db = ty::DebruijnIndex::from_usize(
1037                             self.universe_indices.len() - index + self.current_index.as_usize() - 1,
1038                         );
1039                         Ty::new_bound(self.infcx.tcx, db, *replace_var)
1040                     }
1041                     None => ty,
1042                 }
1043             }
1044 
1045             _ if ty.has_placeholders() || ty.has_infer_regions() => ty.super_fold_with(self),
1046             _ => ty,
1047         }
1048     }
1049 
fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx>1050     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
1051         if let ty::ConstKind::Placeholder(p) = ct.kind() {
1052             let replace_var = self.mapped_consts.get(&p);
1053             match replace_var {
1054                 Some(replace_var) => {
1055                     let index = self
1056                         .universe_indices
1057                         .iter()
1058                         .position(|u| matches!(u, Some(pu) if *pu == p.universe))
1059                         .unwrap_or_else(|| bug!("Unexpected placeholder universe."));
1060                     let db = ty::DebruijnIndex::from_usize(
1061                         self.universe_indices.len() - index + self.current_index.as_usize() - 1,
1062                     );
1063                     ty::Const::new_bound(self.infcx.tcx, db, *replace_var, ct.ty())
1064                 }
1065                 None => ct,
1066             }
1067         } else {
1068             ct.super_fold_with(self)
1069         }
1070     }
1071 }
1072 
1073 /// The guts of `normalize`: normalize a specific projection like `<T
1074 /// as Trait>::Item`. The result is always a type (and possibly
1075 /// additional obligations). If ambiguity arises, which implies that
1076 /// there are unresolved type variables in the projection, we will
1077 /// substitute a fresh type variable `$X` and generate a new
1078 /// obligation `<T as Trait>::Item == $X` for later.
normalize_projection_type<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, projection_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &mut Vec<PredicateObligation<'tcx>>, ) -> Term<'tcx>1079 pub fn normalize_projection_type<'a, 'b, 'tcx>(
1080     selcx: &'a mut SelectionContext<'b, 'tcx>,
1081     param_env: ty::ParamEnv<'tcx>,
1082     projection_ty: ty::AliasTy<'tcx>,
1083     cause: ObligationCause<'tcx>,
1084     depth: usize,
1085     obligations: &mut Vec<PredicateObligation<'tcx>>,
1086 ) -> Term<'tcx> {
1087     opt_normalize_projection_type(
1088         selcx,
1089         param_env,
1090         projection_ty,
1091         cause.clone(),
1092         depth,
1093         obligations,
1094     )
1095     .ok()
1096     .flatten()
1097     .unwrap_or_else(move || {
1098         // if we bottom out in ambiguity, create a type variable
1099         // and a deferred predicate to resolve this when more type
1100         // information is available.
1101 
1102         selcx.infcx.infer_projection(param_env, projection_ty, cause, depth + 1, obligations).into()
1103     })
1104 }
1105 
1106 /// The guts of `normalize`: normalize a specific projection like `<T
1107 /// as Trait>::Item`. The result is always a type (and possibly
1108 /// additional obligations). Returns `None` in the case of ambiguity,
1109 /// which indicates that there are unbound type variables.
1110 ///
1111 /// This function used to return `Option<NormalizedTy<'tcx>>`, which contains a
1112 /// `Ty<'tcx>` and an obligations vector. But that obligation vector was very
1113 /// often immediately appended to another obligations vector. So now this
1114 /// function takes an obligations vector and appends to it directly, which is
1115 /// slightly uglier but avoids the need for an extra short-lived allocation.
1116 #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
opt_normalize_projection_type<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, projection_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &mut Vec<PredicateObligation<'tcx>>, ) -> Result<Option<Term<'tcx>>, InProgress>1117 fn opt_normalize_projection_type<'a, 'b, 'tcx>(
1118     selcx: &'a mut SelectionContext<'b, 'tcx>,
1119     param_env: ty::ParamEnv<'tcx>,
1120     projection_ty: ty::AliasTy<'tcx>,
1121     cause: ObligationCause<'tcx>,
1122     depth: usize,
1123     obligations: &mut Vec<PredicateObligation<'tcx>>,
1124 ) -> Result<Option<Term<'tcx>>, InProgress> {
1125     let infcx = selcx.infcx;
1126     debug_assert!(!selcx.infcx.next_trait_solver());
1127     // Don't use the projection cache in intercrate mode -
1128     // the `infcx` may be re-used between intercrate in non-intercrate
1129     // mode, which could lead to using incorrect cache results.
1130     let use_cache = !selcx.is_intercrate();
1131 
1132     let projection_ty = infcx.resolve_vars_if_possible(projection_ty);
1133     let cache_key = ProjectionCacheKey::new(projection_ty);
1134 
1135     // FIXME(#20304) For now, I am caching here, which is good, but it
1136     // means we don't capture the type variables that are created in
1137     // the case of ambiguity. Which means we may create a large stream
1138     // of such variables. OTOH, if we move the caching up a level, we
1139     // would not benefit from caching when proving `T: Trait<U=Foo>`
1140     // bounds. It might be the case that we want two distinct caches,
1141     // or else another kind of cache entry.
1142 
1143     let cache_result = if use_cache {
1144         infcx.inner.borrow_mut().projection_cache().try_start(cache_key)
1145     } else {
1146         Ok(())
1147     };
1148     match cache_result {
1149         Ok(()) => debug!("no cache"),
1150         Err(ProjectionCacheEntry::Ambiguous) => {
1151             // If we found ambiguity the last time, that means we will continue
1152             // to do so until some type in the key changes (and we know it
1153             // hasn't, because we just fully resolved it).
1154             debug!("found cache entry: ambiguous");
1155             return Ok(None);
1156         }
1157         Err(ProjectionCacheEntry::InProgress) => {
1158             // Under lazy normalization, this can arise when
1159             // bootstrapping. That is, imagine an environment with a
1160             // where-clause like `A::B == u32`. Now, if we are asked
1161             // to normalize `A::B`, we will want to check the
1162             // where-clauses in scope. So we will try to unify `A::B`
1163             // with `A::B`, which can trigger a recursive
1164             // normalization.
1165 
1166             debug!("found cache entry: in-progress");
1167 
1168             // Cache that normalizing this projection resulted in a cycle. This
1169             // should ensure that, unless this happens within a snapshot that's
1170             // rolled back, fulfillment or evaluation will notice the cycle.
1171 
1172             if use_cache {
1173                 infcx.inner.borrow_mut().projection_cache().recur(cache_key);
1174             }
1175             return Err(InProgress);
1176         }
1177         Err(ProjectionCacheEntry::Recur) => {
1178             debug!("recur cache");
1179             return Err(InProgress);
1180         }
1181         Err(ProjectionCacheEntry::NormalizedTy { ty, complete: _ }) => {
1182             // This is the hottest path in this function.
1183             //
1184             // If we find the value in the cache, then return it along
1185             // with the obligations that went along with it. Note
1186             // that, when using a fulfillment context, these
1187             // obligations could in principle be ignored: they have
1188             // already been registered when the cache entry was
1189             // created (and hence the new ones will quickly be
1190             // discarded as duplicated). But when doing trait
1191             // evaluation this is not the case, and dropping the trait
1192             // evaluations can causes ICEs (e.g., #43132).
1193             debug!(?ty, "found normalized ty");
1194             obligations.extend(ty.obligations);
1195             return Ok(Some(ty.value));
1196         }
1197         Err(ProjectionCacheEntry::Error) => {
1198             debug!("opt_normalize_projection_type: found error");
1199             let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth);
1200             obligations.extend(result.obligations);
1201             return Ok(Some(result.value.into()));
1202         }
1203     }
1204 
1205     let obligation =
1206         Obligation::with_depth(selcx.tcx(), cause.clone(), depth, param_env, projection_ty);
1207 
1208     match project(selcx, &obligation) {
1209         Ok(Projected::Progress(Progress {
1210             term: projected_term,
1211             obligations: mut projected_obligations,
1212         })) => {
1213             // if projection succeeded, then what we get out of this
1214             // is also non-normalized (consider: it was derived from
1215             // an impl, where-clause etc) and hence we must
1216             // re-normalize it
1217 
1218             let projected_term = selcx.infcx.resolve_vars_if_possible(projected_term);
1219 
1220             let mut result = if projected_term.has_projections() {
1221                 let mut normalizer = AssocTypeNormalizer::new(
1222                     selcx,
1223                     param_env,
1224                     cause,
1225                     depth + 1,
1226                     &mut projected_obligations,
1227                 );
1228                 let normalized_ty = normalizer.fold(projected_term);
1229 
1230                 Normalized { value: normalized_ty, obligations: projected_obligations }
1231             } else {
1232                 Normalized { value: projected_term, obligations: projected_obligations }
1233             };
1234 
1235             let mut deduped: SsoHashSet<_> = Default::default();
1236             result.obligations.retain(|projected_obligation| {
1237                 if !deduped.insert(projected_obligation.clone()) {
1238                     return false;
1239                 }
1240                 true
1241             });
1242 
1243             if use_cache {
1244                 infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone());
1245             }
1246             obligations.extend(result.obligations);
1247             Ok(Some(result.value))
1248         }
1249         Ok(Projected::NoProgress(projected_ty)) => {
1250             let result = Normalized { value: projected_ty, obligations: vec![] };
1251             if use_cache {
1252                 infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone());
1253             }
1254             // No need to extend `obligations`.
1255             Ok(Some(result.value))
1256         }
1257         Err(ProjectionError::TooManyCandidates) => {
1258             debug!("opt_normalize_projection_type: too many candidates");
1259             if use_cache {
1260                 infcx.inner.borrow_mut().projection_cache().ambiguous(cache_key);
1261             }
1262             Ok(None)
1263         }
1264         Err(ProjectionError::TraitSelectionError(_)) => {
1265             debug!("opt_normalize_projection_type: ERROR");
1266             // if we got an error processing the `T as Trait` part,
1267             // just return `ty::err` but add the obligation `T :
1268             // Trait`, which when processed will cause the error to be
1269             // reported later
1270 
1271             if use_cache {
1272                 infcx.inner.borrow_mut().projection_cache().error(cache_key);
1273             }
1274             let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth);
1275             obligations.extend(result.obligations);
1276             Ok(Some(result.value.into()))
1277         }
1278     }
1279 }
1280 
1281 /// If we are projecting `<T as Trait>::Item`, but `T: Trait` does not
1282 /// hold. In various error cases, we cannot generate a valid
1283 /// normalized projection. Therefore, we create an inference variable
1284 /// return an associated obligation that, when fulfilled, will lead to
1285 /// an error.
1286 ///
1287 /// Note that we used to return `Error` here, but that was quite
1288 /// dubious -- the premise was that an error would *eventually* be
1289 /// reported, when the obligation was processed. But in general once
1290 /// you see an `Error` you are supposed to be able to assume that an
1291 /// error *has been* reported, so that you can take whatever heuristic
1292 /// paths you want to take. To make things worse, it was possible for
1293 /// cycles to arise, where you basically had a setup like `<MyType<$0>
1294 /// as Trait>::Foo == $0`. Here, normalizing `<MyType<$0> as
1295 /// Trait>::Foo>` to `[type error]` would lead to an obligation of
1296 /// `<MyType<[type error]> as Trait>::Foo`. We are supposed to report
1297 /// an error for this obligation, but we legitimately should not,
1298 /// because it contains `[type error]`. Yuck! (See issue #29857 for
1299 /// one case where this arose.)
normalize_to_error<'a, 'tcx>( selcx: &mut SelectionContext<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, projection_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, ) -> NormalizedTy<'tcx>1300 fn normalize_to_error<'a, 'tcx>(
1301     selcx: &mut SelectionContext<'a, 'tcx>,
1302     param_env: ty::ParamEnv<'tcx>,
1303     projection_ty: ty::AliasTy<'tcx>,
1304     cause: ObligationCause<'tcx>,
1305     depth: usize,
1306 ) -> NormalizedTy<'tcx> {
1307     let trait_ref = ty::Binder::dummy(projection_ty.trait_ref(selcx.tcx()));
1308     let trait_obligation = Obligation {
1309         cause,
1310         recursion_depth: depth,
1311         param_env,
1312         predicate: trait_ref.without_const().to_predicate(selcx.tcx()),
1313     };
1314     let tcx = selcx.infcx.tcx;
1315     let new_value = selcx.infcx.next_ty_var(TypeVariableOrigin {
1316         kind: TypeVariableOriginKind::NormalizeProjectionType,
1317         span: tcx.def_span(projection_ty.def_id),
1318     });
1319     Normalized { value: new_value, obligations: vec![trait_obligation] }
1320 }
1321 
1322 /// Confirm and normalize the given inherent projection.
1323 #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
normalize_inherent_projection<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, alias_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &mut Vec<PredicateObligation<'tcx>>, ) -> Ty<'tcx>1324 pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
1325     selcx: &'a mut SelectionContext<'b, 'tcx>,
1326     param_env: ty::ParamEnv<'tcx>,
1327     alias_ty: ty::AliasTy<'tcx>,
1328     cause: ObligationCause<'tcx>,
1329     depth: usize,
1330     obligations: &mut Vec<PredicateObligation<'tcx>>,
1331 ) -> Ty<'tcx> {
1332     let tcx = selcx.tcx();
1333 
1334     if !tcx.recursion_limit().value_within_limit(depth) {
1335         // Halt compilation because it is important that overflows never be masked.
1336         tcx.sess.emit_fatal(InherentProjectionNormalizationOverflow {
1337             span: cause.span,
1338             ty: alias_ty.to_string(),
1339         });
1340     }
1341 
1342     let substs = compute_inherent_assoc_ty_substs(
1343         selcx,
1344         param_env,
1345         alias_ty,
1346         cause.clone(),
1347         depth,
1348         obligations,
1349     );
1350 
1351     // Register the obligations arising from the impl and from the associated type itself.
1352     let predicates = tcx.predicates_of(alias_ty.def_id).instantiate(tcx, substs);
1353     for (predicate, span) in predicates {
1354         let predicate = normalize_with_depth_to(
1355             selcx,
1356             param_env,
1357             cause.clone(),
1358             depth + 1,
1359             predicate,
1360             obligations,
1361         );
1362 
1363         let nested_cause = ObligationCause::new(
1364             cause.span,
1365             cause.body_id,
1366             // FIXME(inherent_associated_types): Since we can't pass along the self type to the
1367             // cause code, inherent projections will be printed with identity substitutions in
1368             // diagnostics which is not ideal.
1369             // Consider creating separate cause codes for this specific situation.
1370             if span.is_dummy() {
1371                 super::ItemObligation(alias_ty.def_id)
1372             } else {
1373                 super::BindingObligation(alias_ty.def_id, span)
1374             },
1375         );
1376 
1377         obligations.push(Obligation::with_depth(
1378             tcx,
1379             nested_cause,
1380             depth + 1,
1381             param_env,
1382             predicate,
1383         ));
1384     }
1385 
1386     let ty = tcx.type_of(alias_ty.def_id).subst(tcx, substs);
1387 
1388     let mut ty = selcx.infcx.resolve_vars_if_possible(ty);
1389     if ty.has_projections() {
1390         ty = normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, ty, obligations);
1391     }
1392 
1393     ty
1394 }
1395 
compute_inherent_assoc_ty_substs<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, alias_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &mut Vec<PredicateObligation<'tcx>>, ) -> ty::SubstsRef<'tcx>1396 pub fn compute_inherent_assoc_ty_substs<'a, 'b, 'tcx>(
1397     selcx: &'a mut SelectionContext<'b, 'tcx>,
1398     param_env: ty::ParamEnv<'tcx>,
1399     alias_ty: ty::AliasTy<'tcx>,
1400     cause: ObligationCause<'tcx>,
1401     depth: usize,
1402     obligations: &mut Vec<PredicateObligation<'tcx>>,
1403 ) -> ty::SubstsRef<'tcx> {
1404     let tcx = selcx.tcx();
1405 
1406     let impl_def_id = tcx.parent(alias_ty.def_id);
1407     let impl_substs = selcx.infcx.fresh_substs_for_item(cause.span, impl_def_id);
1408 
1409     let impl_ty = tcx.type_of(impl_def_id).subst(tcx, impl_substs);
1410     let impl_ty =
1411         normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, impl_ty, obligations);
1412 
1413     // Infer the generic parameters of the impl by unifying the
1414     // impl type with the self type of the projection.
1415     let self_ty = alias_ty.self_ty();
1416     match selcx.infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, impl_ty, self_ty) {
1417         Ok(mut ok) => obligations.append(&mut ok.obligations),
1418         Err(_) => {
1419             tcx.sess.delay_span_bug(
1420                 cause.span,
1421                 format!(
1422                     "{self_ty:?} was a subtype of {impl_ty:?} during selection but now it is not"
1423                 ),
1424             );
1425         }
1426     }
1427 
1428     alias_ty.rebase_substs_onto_impl(impl_substs, tcx)
1429 }
1430 
1431 enum Projected<'tcx> {
1432     Progress(Progress<'tcx>),
1433     NoProgress(ty::Term<'tcx>),
1434 }
1435 
1436 struct Progress<'tcx> {
1437     term: ty::Term<'tcx>,
1438     obligations: Vec<PredicateObligation<'tcx>>,
1439 }
1440 
1441 impl<'tcx> Progress<'tcx> {
error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self1442     fn error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
1443         Progress { term: Ty::new_error(tcx, guar).into(), obligations: vec![] }
1444     }
1445 
with_addl_obligations(mut self, mut obligations: Vec<PredicateObligation<'tcx>>) -> Self1446     fn with_addl_obligations(mut self, mut obligations: Vec<PredicateObligation<'tcx>>) -> Self {
1447         self.obligations.append(&mut obligations);
1448         self
1449     }
1450 }
1451 
1452 /// Computes the result of a projection type (if we can).
1453 ///
1454 /// IMPORTANT:
1455 /// - `obligation` must be fully normalized
1456 #[instrument(level = "info", skip(selcx))]
project<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, ) -> Result<Projected<'tcx>, ProjectionError<'tcx>>1457 fn project<'cx, 'tcx>(
1458     selcx: &mut SelectionContext<'cx, 'tcx>,
1459     obligation: &ProjectionTyObligation<'tcx>,
1460 ) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
1461     if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) {
1462         // This should really be an immediate error, but some existing code
1463         // relies on being able to recover from this.
1464         return Err(ProjectionError::TraitSelectionError(SelectionError::Overflow(
1465             OverflowError::Canonical,
1466         )));
1467     }
1468 
1469     if let Err(guar) = obligation.predicate.error_reported() {
1470         return Ok(Projected::Progress(Progress::error(selcx.tcx(), guar)));
1471     }
1472 
1473     let mut candidates = ProjectionCandidateSet::None;
1474 
1475     assemble_candidate_for_impl_trait_in_trait(selcx, obligation, &mut candidates);
1476 
1477     // Make sure that the following procedures are kept in order. ParamEnv
1478     // needs to be first because it has highest priority, and Select checks
1479     // the return value of push_candidate which assumes it's ran at last.
1480     assemble_candidates_from_param_env(selcx, obligation, &mut candidates);
1481 
1482     assemble_candidates_from_trait_def(selcx, obligation, &mut candidates);
1483 
1484     assemble_candidates_from_object_ty(selcx, obligation, &mut candidates);
1485 
1486     if let ProjectionCandidateSet::Single(ProjectionCandidate::Object(_)) = candidates {
1487         // Avoid normalization cycle from selection (see
1488         // `assemble_candidates_from_object_ty`).
1489         // FIXME(lazy_normalization): Lazy normalization should save us from
1490         // having to special case this.
1491     } else {
1492         assemble_candidates_from_impls(selcx, obligation, &mut candidates);
1493     };
1494 
1495     match candidates {
1496         ProjectionCandidateSet::Single(candidate) => {
1497             Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate)))
1498         }
1499         ProjectionCandidateSet::None => {
1500             let tcx = selcx.tcx();
1501             let term = match tcx.def_kind(obligation.predicate.def_id) {
1502                 DefKind::AssocTy | DefKind::ImplTraitPlaceholder => Ty::new_projection(
1503                     tcx,
1504                     obligation.predicate.def_id,
1505                     obligation.predicate.substs,
1506                 )
1507                 .into(),
1508                 DefKind::AssocConst => ty::Const::new_unevaluated(
1509                     tcx,
1510                     ty::UnevaluatedConst::new(
1511                         obligation.predicate.def_id,
1512                         obligation.predicate.substs,
1513                     ),
1514                     tcx.type_of(obligation.predicate.def_id)
1515                         .subst(tcx, obligation.predicate.substs),
1516                 )
1517                 .into(),
1518                 kind => {
1519                     bug!("unknown projection def-id: {}", kind.descr(obligation.predicate.def_id))
1520                 }
1521             };
1522 
1523             Ok(Projected::NoProgress(term))
1524         }
1525         // Error occurred while trying to processing impls.
1526         ProjectionCandidateSet::Error(e) => Err(ProjectionError::TraitSelectionError(e)),
1527         // Inherent ambiguity that prevents us from even enumerating the
1528         // candidates.
1529         ProjectionCandidateSet::Ambiguous => Err(ProjectionError::TooManyCandidates),
1530     }
1531 }
1532 
1533 /// If the predicate's item is an `ImplTraitPlaceholder`, we do a select on the
1534 /// corresponding trait ref. If this yields an `impl`, then we're able to project
1535 /// to a concrete type, since we have an `impl`'s method  to provide the RPITIT.
assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, )1536 fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
1537     selcx: &mut SelectionContext<'cx, 'tcx>,
1538     obligation: &ProjectionTyObligation<'tcx>,
1539     candidate_set: &mut ProjectionCandidateSet<'tcx>,
1540 ) {
1541     let tcx = selcx.tcx();
1542     if tcx.def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
1543         let trait_fn_def_id = tcx.impl_trait_in_trait_parent_fn(obligation.predicate.def_id);
1544 
1545         let trait_def_id = tcx.parent(trait_fn_def_id);
1546         let trait_substs =
1547             obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id));
1548         let trait_predicate = ty::TraitRef::new(tcx, trait_def_id, trait_substs);
1549 
1550         let _ = selcx.infcx.commit_if_ok(|_| {
1551             match selcx.select(&obligation.with(tcx, trait_predicate)) {
1552                 Ok(Some(super::ImplSource::UserDefined(data))) => {
1553                     candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(data));
1554                     Ok(())
1555                 }
1556                 Ok(None) => {
1557                     candidate_set.mark_ambiguous();
1558                     Err(())
1559                 }
1560                 Ok(Some(_)) => {
1561                     // Don't know enough about the impl to provide a useful signature
1562                     Err(())
1563                 }
1564                 Err(e) => {
1565                     debug!(error = ?e, "selection error");
1566                     candidate_set.mark_error(e);
1567                     Err(())
1568                 }
1569             }
1570         });
1571     }
1572 }
1573 
1574 /// The first thing we have to do is scan through the parameter
1575 /// environment to see whether there are any projection predicates
1576 /// there that can answer this question.
assemble_candidates_from_param_env<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, )1577 fn assemble_candidates_from_param_env<'cx, 'tcx>(
1578     selcx: &mut SelectionContext<'cx, 'tcx>,
1579     obligation: &ProjectionTyObligation<'tcx>,
1580     candidate_set: &mut ProjectionCandidateSet<'tcx>,
1581 ) {
1582     assemble_candidates_from_predicates(
1583         selcx,
1584         obligation,
1585         candidate_set,
1586         ProjectionCandidate::ParamEnv,
1587         obligation.param_env.caller_bounds().iter(),
1588         false,
1589     );
1590 }
1591 
1592 /// In the case of a nested projection like `<<A as Foo>::FooT as Bar>::BarT`, we may find
1593 /// that the definition of `Foo` has some clues:
1594 ///
1595 /// ```ignore (illustrative)
1596 /// trait Foo {
1597 ///     type FooT : Bar<BarT=i32>
1598 /// }
1599 /// ```
1600 ///
1601 /// Here, for example, we could conclude that the result is `i32`.
assemble_candidates_from_trait_def<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, )1602 fn assemble_candidates_from_trait_def<'cx, 'tcx>(
1603     selcx: &mut SelectionContext<'cx, 'tcx>,
1604     obligation: &ProjectionTyObligation<'tcx>,
1605     candidate_set: &mut ProjectionCandidateSet<'tcx>,
1606 ) {
1607     debug!("assemble_candidates_from_trait_def(..)");
1608 
1609     let tcx = selcx.tcx();
1610     // Check whether the self-type is itself a projection.
1611     // If so, extract what we know from the trait and try to come up with a good answer.
1612     let bounds = match *obligation.predicate.self_ty().kind() {
1613         // Excluding IATs and type aliases here as they don't have meaningful item bounds.
1614         ty::Alias(ty::Projection | ty::Opaque, ref data) => {
1615             tcx.item_bounds(data.def_id).subst(tcx, data.substs)
1616         }
1617         ty::Infer(ty::TyVar(_)) => {
1618             // If the self-type is an inference variable, then it MAY wind up
1619             // being a projected type, so induce an ambiguity.
1620             candidate_set.mark_ambiguous();
1621             return;
1622         }
1623         _ => return,
1624     };
1625 
1626     assemble_candidates_from_predicates(
1627         selcx,
1628         obligation,
1629         candidate_set,
1630         ProjectionCandidate::TraitDef,
1631         bounds.iter(),
1632         true,
1633     );
1634 }
1635 
1636 /// In the case of a trait object like
1637 /// `<dyn Iterator<Item = ()> as Iterator>::Item` we can use the existential
1638 /// predicate in the trait object.
1639 ///
1640 /// We don't go through the select candidate for these bounds to avoid cycles:
1641 /// In the above case, `dyn Iterator<Item = ()>: Iterator` would create a
1642 /// nested obligation of `<dyn Iterator<Item = ()> as Iterator>::Item: Sized`,
1643 /// this then has to be normalized without having to prove
1644 /// `dyn Iterator<Item = ()>: Iterator` again.
assemble_candidates_from_object_ty<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, )1645 fn assemble_candidates_from_object_ty<'cx, 'tcx>(
1646     selcx: &mut SelectionContext<'cx, 'tcx>,
1647     obligation: &ProjectionTyObligation<'tcx>,
1648     candidate_set: &mut ProjectionCandidateSet<'tcx>,
1649 ) {
1650     debug!("assemble_candidates_from_object_ty(..)");
1651 
1652     let tcx = selcx.tcx();
1653 
1654     if !tcx.trait_def(obligation.predicate.trait_def_id(tcx)).implement_via_object {
1655         return;
1656     }
1657 
1658     let self_ty = obligation.predicate.self_ty();
1659     let object_ty = selcx.infcx.shallow_resolve(self_ty);
1660     let data = match object_ty.kind() {
1661         ty::Dynamic(data, ..) => data,
1662         ty::Infer(ty::TyVar(_)) => {
1663             // If the self-type is an inference variable, then it MAY wind up
1664             // being an object type, so induce an ambiguity.
1665             candidate_set.mark_ambiguous();
1666             return;
1667         }
1668         _ => return,
1669     };
1670     let env_predicates = data
1671         .projection_bounds()
1672         .filter(|bound| bound.item_def_id() == obligation.predicate.def_id)
1673         .map(|p| p.with_self_ty(tcx, object_ty).to_predicate(tcx));
1674 
1675     assemble_candidates_from_predicates(
1676         selcx,
1677         obligation,
1678         candidate_set,
1679         ProjectionCandidate::Object,
1680         env_predicates,
1681         false,
1682     );
1683 }
1684 
1685 #[instrument(
1686     level = "debug",
1687     skip(selcx, candidate_set, ctor, env_predicates, potentially_unnormalized_candidates)
1688 )]
assemble_candidates_from_predicates<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionCandidate<'tcx>, env_predicates: impl Iterator<Item = ty::Clause<'tcx>>, potentially_unnormalized_candidates: bool, )1689 fn assemble_candidates_from_predicates<'cx, 'tcx>(
1690     selcx: &mut SelectionContext<'cx, 'tcx>,
1691     obligation: &ProjectionTyObligation<'tcx>,
1692     candidate_set: &mut ProjectionCandidateSet<'tcx>,
1693     ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionCandidate<'tcx>,
1694     env_predicates: impl Iterator<Item = ty::Clause<'tcx>>,
1695     potentially_unnormalized_candidates: bool,
1696 ) {
1697     let infcx = selcx.infcx;
1698     for predicate in env_predicates {
1699         let bound_predicate = predicate.kind();
1700         if let ty::ClauseKind::Projection(data) = predicate.kind().skip_binder() {
1701             let data = bound_predicate.rebind(data);
1702             if data.projection_def_id() != obligation.predicate.def_id {
1703                 continue;
1704             }
1705 
1706             let is_match = infcx.probe(|_| {
1707                 selcx.match_projection_projections(
1708                     obligation,
1709                     data,
1710                     potentially_unnormalized_candidates,
1711                 )
1712             });
1713 
1714             match is_match {
1715                 ProjectionMatchesProjection::Yes => {
1716                     candidate_set.push_candidate(ctor(data));
1717 
1718                     if potentially_unnormalized_candidates
1719                         && !obligation.predicate.has_non_region_infer()
1720                     {
1721                         // HACK: Pick the first trait def candidate for a fully
1722                         // inferred predicate. This is to allow duplicates that
1723                         // differ only in normalization.
1724                         return;
1725                     }
1726                 }
1727                 ProjectionMatchesProjection::Ambiguous => {
1728                     candidate_set.mark_ambiguous();
1729                 }
1730                 ProjectionMatchesProjection::No => {}
1731             }
1732         }
1733     }
1734 }
1735 
1736 #[instrument(level = "debug", skip(selcx, obligation, candidate_set))]
assemble_candidates_from_impls<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, )1737 fn assemble_candidates_from_impls<'cx, 'tcx>(
1738     selcx: &mut SelectionContext<'cx, 'tcx>,
1739     obligation: &ProjectionTyObligation<'tcx>,
1740     candidate_set: &mut ProjectionCandidateSet<'tcx>,
1741 ) {
1742     // Can't assemble candidate from impl for RPITIT
1743     if selcx.tcx().def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
1744         return;
1745     }
1746 
1747     // If we are resolving `<T as TraitRef<...>>::Item == Type`,
1748     // start out by selecting the predicate `T as TraitRef<...>`:
1749     let trait_ref = obligation.predicate.trait_ref(selcx.tcx());
1750     let trait_obligation = obligation.with(selcx.tcx(), trait_ref);
1751     let _ = selcx.infcx.commit_if_ok(|_| {
1752         let impl_source = match selcx.select(&trait_obligation) {
1753             Ok(Some(impl_source)) => impl_source,
1754             Ok(None) => {
1755                 candidate_set.mark_ambiguous();
1756                 return Err(());
1757             }
1758             Err(e) => {
1759                 debug!(error = ?e, "selection error");
1760                 candidate_set.mark_error(e);
1761                 return Err(());
1762             }
1763         };
1764 
1765         let eligible = match &impl_source {
1766             super::ImplSource::UserDefined(impl_data) => {
1767                 // We have to be careful when projecting out of an
1768                 // impl because of specialization. If we are not in
1769                 // codegen (i.e., projection mode is not "any"), and the
1770                 // impl's type is declared as default, then we disable
1771                 // projection (even if the trait ref is fully
1772                 // monomorphic). In the case where trait ref is not
1773                 // fully monomorphic (i.e., includes type parameters),
1774                 // this is because those type parameters may
1775                 // ultimately be bound to types from other crates that
1776                 // may have specialized impls we can't see. In the
1777                 // case where the trait ref IS fully monomorphic, this
1778                 // is a policy decision that we made in the RFC in
1779                 // order to preserve flexibility for the crate that
1780                 // defined the specializable impl to specialize later
1781                 // for existing types.
1782                 //
1783                 // In either case, we handle this by not adding a
1784                 // candidate for an impl if it contains a `default`
1785                 // type.
1786                 //
1787                 // NOTE: This should be kept in sync with the similar code in
1788                 // `rustc_ty_utils::instance::resolve_associated_item()`.
1789                 let node_item =
1790                     specialization_graph::assoc_def(selcx.tcx(), impl_data.impl_def_id, obligation.predicate.def_id)
1791                         .map_err(|ErrorGuaranteed { .. }| ())?;
1792 
1793                 if node_item.is_final() {
1794                     // Non-specializable items are always projectable.
1795                     true
1796                 } else {
1797                     // Only reveal a specializable default if we're past type-checking
1798                     // and the obligation is monomorphic, otherwise passes such as
1799                     // transmute checking and polymorphic MIR optimizations could
1800                     // get a result which isn't correct for all monomorphizations.
1801                     if obligation.param_env.reveal() == Reveal::All {
1802                         // NOTE(eddyb) inference variables can resolve to parameters, so
1803                         // assume `poly_trait_ref` isn't monomorphic, if it contains any.
1804                         let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref);
1805                         !poly_trait_ref.still_further_specializable()
1806                     } else {
1807                         debug!(
1808                             assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
1809                             ?obligation.predicate,
1810                             "assemble_candidates_from_impls: not eligible due to default",
1811                         );
1812                         false
1813                     }
1814                 }
1815             }
1816             super::ImplSource::Builtin(..) => {
1817                 // While a builtin impl may be known to exist, the associated type may not yet
1818                 // be known. Any type with multiple potential associated types is therefore
1819                 // not eligible.
1820                 let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
1821 
1822                 let lang_items = selcx.tcx().lang_items();
1823                 if [lang_items.gen_trait(), lang_items.future_trait()].contains(&Some(trait_ref.def_id))
1824                     || selcx.tcx().fn_trait_kind_from_def_id(trait_ref.def_id).is_some()
1825                 {
1826                     true
1827                 } else if lang_items.discriminant_kind_trait() == Some(trait_ref.def_id) {
1828                     match self_ty.kind() {
1829                         ty::Bool
1830                         | ty::Char
1831                         | ty::Int(_)
1832                         | ty::Uint(_)
1833                         | ty::Float(_)
1834                         | ty::Adt(..)
1835                         | ty::Foreign(_)
1836                         | ty::Str
1837                         | ty::Array(..)
1838                         | ty::Slice(_)
1839                         | ty::RawPtr(..)
1840                         | ty::Ref(..)
1841                         | ty::FnDef(..)
1842                         | ty::FnPtr(..)
1843                         | ty::Dynamic(..)
1844                         | ty::Closure(..)
1845                         | ty::Generator(..)
1846                         | ty::GeneratorWitness(..)
1847                         | ty::GeneratorWitnessMIR(..)
1848                         | ty::Never
1849                         | ty::Tuple(..)
1850                         // Integers and floats always have `u8` as their discriminant.
1851                         | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
1852 
1853                          // type parameters, opaques, and unnormalized projections have pointer
1854                         // metadata if they're known (e.g. by the param_env) to be sized
1855                         ty::Param(_)
1856                         | ty::Alias(..)
1857                         | ty::Bound(..)
1858                         | ty::Placeholder(..)
1859                         | ty::Infer(..)
1860                         | ty::Error(_) => false,
1861                     }
1862                 } else if lang_items.pointee_trait() == Some(trait_ref.def_id) {
1863                     let tail = selcx.tcx().struct_tail_with_normalize(
1864                         self_ty,
1865                         |ty| {
1866                             // We throw away any obligations we get from this, since we normalize
1867                             // and confirm these obligations once again during confirmation
1868                             normalize_with_depth(
1869                                 selcx,
1870                                 obligation.param_env,
1871                                 obligation.cause.clone(),
1872                                 obligation.recursion_depth + 1,
1873                                 ty,
1874                             )
1875                             .value
1876                         },
1877                         || {},
1878                     );
1879 
1880                     match tail.kind() {
1881                         ty::Bool
1882                         | ty::Char
1883                         | ty::Int(_)
1884                         | ty::Uint(_)
1885                         | ty::Float(_)
1886                         | ty::Str
1887                         | ty::Array(..)
1888                         | ty::Slice(_)
1889                         | ty::RawPtr(..)
1890                         | ty::Ref(..)
1891                         | ty::FnDef(..)
1892                         | ty::FnPtr(..)
1893                         | ty::Dynamic(..)
1894                         | ty::Closure(..)
1895                         | ty::Generator(..)
1896                         | ty::GeneratorWitness(..)
1897                         | ty::GeneratorWitnessMIR(..)
1898                         | ty::Never
1899                         // Extern types have unit metadata, according to RFC 2850
1900                         | ty::Foreign(_)
1901                         // If returned by `struct_tail_without_normalization` this is a unit struct
1902                         // without any fields, or not a struct, and therefore is Sized.
1903                         | ty::Adt(..)
1904                         // If returned by `struct_tail_without_normalization` this is the empty tuple.
1905                         | ty::Tuple(..)
1906                         // Integers and floats are always Sized, and so have unit type metadata.
1907                         | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
1908 
1909                         // type parameters, opaques, and unnormalized projections have pointer
1910                         // metadata if they're known (e.g. by the param_env) to be sized
1911                         ty::Param(_) | ty::Alias(..)
1912                             if selcx.infcx.predicate_must_hold_modulo_regions(
1913                                 &obligation.with(
1914                                     selcx.tcx(),
1915                                     ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty])
1916                                         .without_const(),
1917                                 ),
1918                             ) =>
1919                         {
1920                             true
1921                         }
1922 
1923                         // FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
1924                         ty::Param(_)
1925                         | ty::Alias(..)
1926                         | ty::Bound(..)
1927                         | ty::Placeholder(..)
1928                         | ty::Infer(..)
1929                         | ty::Error(_) => {
1930                             if tail.has_infer_types() {
1931                                 candidate_set.mark_ambiguous();
1932                             }
1933                             false
1934                         }
1935                     }
1936                 } else {
1937                     bug!("unexpected builtin trait with associated type: {trait_ref:?}")
1938                 }
1939             }
1940             super::ImplSource::Param(..) => {
1941                 // This case tell us nothing about the value of an
1942                 // associated type. Consider:
1943                 //
1944                 // ```
1945                 // trait SomeTrait { type Foo; }
1946                 // fn foo<T:SomeTrait>(...) { }
1947                 // ```
1948                 //
1949                 // If the user writes `<T as SomeTrait>::Foo`, then the `T
1950                 // : SomeTrait` binding does not help us decide what the
1951                 // type `Foo` is (at least, not more specifically than
1952                 // what we already knew).
1953                 //
1954                 // But wait, you say! What about an example like this:
1955                 //
1956                 // ```
1957                 // fn bar<T:SomeTrait<Foo=usize>>(...) { ... }
1958                 // ```
1959                 //
1960                 // Doesn't the `T : SomeTrait<Foo=usize>` predicate help
1961                 // resolve `T::Foo`? And of course it does, but in fact
1962                 // that single predicate is desugared into two predicates
1963                 // in the compiler: a trait predicate (`T : SomeTrait`) and a
1964                 // projection. And the projection where clause is handled
1965                 // in `assemble_candidates_from_param_env`.
1966                 false
1967             }
1968             super::ImplSource::Object(_) => {
1969                 // Handled by the `Object` projection candidate. See
1970                 // `assemble_candidates_from_object_ty` for an explanation of
1971                 // why we special case object types.
1972                 false
1973             }
1974             | super::ImplSource::TraitUpcasting(_) => {
1975                 // These traits have no associated types.
1976                 selcx.tcx().sess.delay_span_bug(
1977                     obligation.cause.span,
1978                     format!("Cannot project an associated type from `{:?}`", impl_source),
1979                 );
1980                 return Err(());
1981             }
1982         };
1983 
1984         if eligible {
1985             if candidate_set.push_candidate(ProjectionCandidate::Select(impl_source)) {
1986                 Ok(())
1987             } else {
1988                 Err(())
1989             }
1990         } else {
1991             Err(())
1992         }
1993     });
1994 }
1995 
confirm_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, candidate: ProjectionCandidate<'tcx>, ) -> Progress<'tcx>1996 fn confirm_candidate<'cx, 'tcx>(
1997     selcx: &mut SelectionContext<'cx, 'tcx>,
1998     obligation: &ProjectionTyObligation<'tcx>,
1999     candidate: ProjectionCandidate<'tcx>,
2000 ) -> Progress<'tcx> {
2001     debug!(?obligation, ?candidate, "confirm_candidate");
2002     let mut progress = match candidate {
2003         ProjectionCandidate::ParamEnv(poly_projection)
2004         | ProjectionCandidate::Object(poly_projection) => {
2005             confirm_param_env_candidate(selcx, obligation, poly_projection, false)
2006         }
2007 
2008         ProjectionCandidate::TraitDef(poly_projection) => {
2009             confirm_param_env_candidate(selcx, obligation, poly_projection, true)
2010         }
2011 
2012         ProjectionCandidate::Select(impl_source) => {
2013             confirm_select_candidate(selcx, obligation, impl_source)
2014         }
2015         ProjectionCandidate::ImplTraitInTrait(data) => {
2016             confirm_impl_trait_in_trait_candidate(selcx, obligation, data)
2017         }
2018     };
2019 
2020     // When checking for cycle during evaluation, we compare predicates with
2021     // "syntactic" equality. Since normalization generally introduces a type
2022     // with new region variables, we need to resolve them to existing variables
2023     // when possible for this to work. See `auto-trait-projection-recursion.rs`
2024     // for a case where this matters.
2025     if progress.term.has_infer_regions() {
2026         progress.term = progress.term.fold_with(&mut OpportunisticRegionResolver::new(selcx.infcx));
2027     }
2028     progress
2029 }
2030 
confirm_select_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, impl_source: Selection<'tcx>, ) -> Progress<'tcx>2031 fn confirm_select_candidate<'cx, 'tcx>(
2032     selcx: &mut SelectionContext<'cx, 'tcx>,
2033     obligation: &ProjectionTyObligation<'tcx>,
2034     impl_source: Selection<'tcx>,
2035 ) -> Progress<'tcx> {
2036     match impl_source {
2037         super::ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
2038         super::ImplSource::Builtin(data) => {
2039             let trait_def_id = obligation.predicate.trait_def_id(selcx.tcx());
2040             let lang_items = selcx.tcx().lang_items();
2041             if lang_items.gen_trait() == Some(trait_def_id) {
2042                 confirm_generator_candidate(selcx, obligation, data)
2043             } else if lang_items.future_trait() == Some(trait_def_id) {
2044                 confirm_future_candidate(selcx, obligation, data)
2045             } else if selcx.tcx().fn_trait_kind_from_def_id(trait_def_id).is_some() {
2046                 if obligation.predicate.self_ty().is_closure() {
2047                     confirm_closure_candidate(selcx, obligation, data)
2048                 } else {
2049                     confirm_fn_pointer_candidate(selcx, obligation, data)
2050                 }
2051             } else {
2052                 confirm_builtin_candidate(selcx, obligation, data)
2053             }
2054         }
2055         super::ImplSource::Object(_)
2056         | super::ImplSource::Param(..)
2057         | super::ImplSource::TraitUpcasting(_) => {
2058             // we don't create Select candidates with this kind of resolution
2059             span_bug!(
2060                 obligation.cause.span,
2061                 "Cannot project an associated type from `{:?}`",
2062                 impl_source
2063             )
2064         }
2065     }
2066 }
2067 
confirm_generator_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, nested: Vec<PredicateObligation<'tcx>>, ) -> Progress<'tcx>2068 fn confirm_generator_candidate<'cx, 'tcx>(
2069     selcx: &mut SelectionContext<'cx, 'tcx>,
2070     obligation: &ProjectionTyObligation<'tcx>,
2071     nested: Vec<PredicateObligation<'tcx>>,
2072 ) -> Progress<'tcx> {
2073     let ty::Generator(_, substs, _) =
2074         selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
2075     else {
2076         unreachable!()
2077     };
2078     let gen_sig = substs.as_generator().poly_sig();
2079     let Normalized { value: gen_sig, obligations } = normalize_with_depth(
2080         selcx,
2081         obligation.param_env,
2082         obligation.cause.clone(),
2083         obligation.recursion_depth + 1,
2084         gen_sig,
2085     );
2086 
2087     debug!(?obligation, ?gen_sig, ?obligations, "confirm_generator_candidate");
2088 
2089     let tcx = selcx.tcx();
2090 
2091     let gen_def_id = tcx.require_lang_item(LangItem::Generator, None);
2092 
2093     let predicate = super::util::generator_trait_ref_and_outputs(
2094         tcx,
2095         gen_def_id,
2096         obligation.predicate.self_ty(),
2097         gen_sig,
2098     )
2099     .map_bound(|(trait_ref, yield_ty, return_ty)| {
2100         let name = tcx.associated_item(obligation.predicate.def_id).name;
2101         let ty = if name == sym::Return {
2102             return_ty
2103         } else if name == sym::Yield {
2104             yield_ty
2105         } else {
2106             bug!()
2107         };
2108 
2109         ty::ProjectionPredicate {
2110             projection_ty: tcx.mk_alias_ty(obligation.predicate.def_id, trait_ref.substs),
2111             term: ty.into(),
2112         }
2113     });
2114 
2115     confirm_param_env_candidate(selcx, obligation, predicate, false)
2116         .with_addl_obligations(nested)
2117         .with_addl_obligations(obligations)
2118 }
2119 
confirm_future_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, nested: Vec<PredicateObligation<'tcx>>, ) -> Progress<'tcx>2120 fn confirm_future_candidate<'cx, 'tcx>(
2121     selcx: &mut SelectionContext<'cx, 'tcx>,
2122     obligation: &ProjectionTyObligation<'tcx>,
2123     nested: Vec<PredicateObligation<'tcx>>,
2124 ) -> Progress<'tcx> {
2125     let ty::Generator(_, substs, _) =
2126         selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
2127     else {
2128         unreachable!()
2129     };
2130     let gen_sig = substs.as_generator().poly_sig();
2131     let Normalized { value: gen_sig, obligations } = normalize_with_depth(
2132         selcx,
2133         obligation.param_env,
2134         obligation.cause.clone(),
2135         obligation.recursion_depth + 1,
2136         gen_sig,
2137     );
2138 
2139     debug!(?obligation, ?gen_sig, ?obligations, "confirm_future_candidate");
2140 
2141     let tcx = selcx.tcx();
2142     let fut_def_id = tcx.require_lang_item(LangItem::Future, None);
2143 
2144     let predicate = super::util::future_trait_ref_and_outputs(
2145         tcx,
2146         fut_def_id,
2147         obligation.predicate.self_ty(),
2148         gen_sig,
2149     )
2150     .map_bound(|(trait_ref, return_ty)| {
2151         debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output);
2152 
2153         ty::ProjectionPredicate {
2154             projection_ty: tcx.mk_alias_ty(obligation.predicate.def_id, trait_ref.substs),
2155             term: return_ty.into(),
2156         }
2157     });
2158 
2159     confirm_param_env_candidate(selcx, obligation, predicate, false)
2160         .with_addl_obligations(nested)
2161         .with_addl_obligations(obligations)
2162 }
2163 
confirm_builtin_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, data: Vec<PredicateObligation<'tcx>>, ) -> Progress<'tcx>2164 fn confirm_builtin_candidate<'cx, 'tcx>(
2165     selcx: &mut SelectionContext<'cx, 'tcx>,
2166     obligation: &ProjectionTyObligation<'tcx>,
2167     data: Vec<PredicateObligation<'tcx>>,
2168 ) -> Progress<'tcx> {
2169     let tcx = selcx.tcx();
2170     let self_ty = obligation.predicate.self_ty();
2171     let substs = tcx.mk_substs(&[self_ty.into()]);
2172     let lang_items = tcx.lang_items();
2173     let item_def_id = obligation.predicate.def_id;
2174     let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
2175     let (term, obligations) = if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
2176         let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
2177         assert_eq!(discriminant_def_id, item_def_id);
2178 
2179         (self_ty.discriminant_ty(tcx).into(), Vec::new())
2180     } else if lang_items.pointee_trait() == Some(trait_def_id) {
2181         let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
2182         assert_eq!(metadata_def_id, item_def_id);
2183 
2184         let mut obligations = Vec::new();
2185         let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| {
2186             normalize_with_depth_to(
2187                 selcx,
2188                 obligation.param_env,
2189                 obligation.cause.clone(),
2190                 obligation.recursion_depth + 1,
2191                 ty,
2192                 &mut obligations,
2193             )
2194         });
2195         if check_is_sized {
2196             let sized_predicate = ty::TraitRef::from_lang_item(
2197                 tcx,
2198                 LangItem::Sized,
2199                 obligation.cause.span(),
2200                 [self_ty],
2201             )
2202             .without_const();
2203             obligations.push(obligation.with(tcx, sized_predicate));
2204         }
2205         (metadata_ty.into(), obligations)
2206     } else {
2207         bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
2208     };
2209 
2210     let predicate =
2211         ty::ProjectionPredicate { projection_ty: tcx.mk_alias_ty(item_def_id, substs), term };
2212 
2213     confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
2214         .with_addl_obligations(obligations)
2215         .with_addl_obligations(data)
2216 }
2217 
confirm_fn_pointer_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, nested: Vec<PredicateObligation<'tcx>>, ) -> Progress<'tcx>2218 fn confirm_fn_pointer_candidate<'cx, 'tcx>(
2219     selcx: &mut SelectionContext<'cx, 'tcx>,
2220     obligation: &ProjectionTyObligation<'tcx>,
2221     nested: Vec<PredicateObligation<'tcx>>,
2222 ) -> Progress<'tcx> {
2223     let fn_type = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
2224     let sig = fn_type.fn_sig(selcx.tcx());
2225     let Normalized { value: sig, obligations } = normalize_with_depth(
2226         selcx,
2227         obligation.param_env,
2228         obligation.cause.clone(),
2229         obligation.recursion_depth + 1,
2230         sig,
2231     );
2232 
2233     confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
2234         .with_addl_obligations(nested)
2235         .with_addl_obligations(obligations)
2236 }
2237 
confirm_closure_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, nested: Vec<PredicateObligation<'tcx>>, ) -> Progress<'tcx>2238 fn confirm_closure_candidate<'cx, 'tcx>(
2239     selcx: &mut SelectionContext<'cx, 'tcx>,
2240     obligation: &ProjectionTyObligation<'tcx>,
2241     nested: Vec<PredicateObligation<'tcx>>,
2242 ) -> Progress<'tcx> {
2243     let ty::Closure(_, substs) =
2244         selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
2245     else {
2246         unreachable!()
2247     };
2248     let closure_sig = substs.as_closure().sig();
2249     let Normalized { value: closure_sig, obligations } = normalize_with_depth(
2250         selcx,
2251         obligation.param_env,
2252         obligation.cause.clone(),
2253         obligation.recursion_depth + 1,
2254         closure_sig,
2255     );
2256 
2257     debug!(?obligation, ?closure_sig, ?obligations, "confirm_closure_candidate");
2258 
2259     confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No)
2260         .with_addl_obligations(nested)
2261         .with_addl_obligations(obligations)
2262 }
2263 
confirm_callable_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, fn_sig: ty::PolyFnSig<'tcx>, flag: util::TupleArgumentsFlag, ) -> Progress<'tcx>2264 fn confirm_callable_candidate<'cx, 'tcx>(
2265     selcx: &mut SelectionContext<'cx, 'tcx>,
2266     obligation: &ProjectionTyObligation<'tcx>,
2267     fn_sig: ty::PolyFnSig<'tcx>,
2268     flag: util::TupleArgumentsFlag,
2269 ) -> Progress<'tcx> {
2270     let tcx = selcx.tcx();
2271 
2272     debug!(?obligation, ?fn_sig, "confirm_callable_candidate");
2273 
2274     let fn_once_def_id = tcx.require_lang_item(LangItem::FnOnce, None);
2275     let fn_once_output_def_id = tcx.require_lang_item(LangItem::FnOnceOutput, None);
2276 
2277     let predicate = super::util::closure_trait_ref_and_return_type(
2278         tcx,
2279         fn_once_def_id,
2280         obligation.predicate.self_ty(),
2281         fn_sig,
2282         flag,
2283     )
2284     .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
2285         projection_ty: tcx.mk_alias_ty(fn_once_output_def_id, trait_ref.substs),
2286         term: ret_type.into(),
2287     });
2288 
2289     confirm_param_env_candidate(selcx, obligation, predicate, true)
2290 }
2291 
confirm_param_env_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, poly_cache_entry: ty::PolyProjectionPredicate<'tcx>, potentially_unnormalized_candidate: bool, ) -> Progress<'tcx>2292 fn confirm_param_env_candidate<'cx, 'tcx>(
2293     selcx: &mut SelectionContext<'cx, 'tcx>,
2294     obligation: &ProjectionTyObligation<'tcx>,
2295     poly_cache_entry: ty::PolyProjectionPredicate<'tcx>,
2296     potentially_unnormalized_candidate: bool,
2297 ) -> Progress<'tcx> {
2298     let infcx = selcx.infcx;
2299     let cause = &obligation.cause;
2300     let param_env = obligation.param_env;
2301 
2302     let cache_entry = infcx.instantiate_binder_with_fresh_vars(
2303         cause.span,
2304         LateBoundRegionConversionTime::HigherRankedType,
2305         poly_cache_entry,
2306     );
2307 
2308     let cache_projection = cache_entry.projection_ty;
2309     let mut nested_obligations = Vec::new();
2310     let obligation_projection = obligation.predicate;
2311     let obligation_projection = ensure_sufficient_stack(|| {
2312         normalize_with_depth_to(
2313             selcx,
2314             obligation.param_env,
2315             obligation.cause.clone(),
2316             obligation.recursion_depth + 1,
2317             obligation_projection,
2318             &mut nested_obligations,
2319         )
2320     });
2321     let cache_projection = if potentially_unnormalized_candidate {
2322         ensure_sufficient_stack(|| {
2323             normalize_with_depth_to(
2324                 selcx,
2325                 obligation.param_env,
2326                 obligation.cause.clone(),
2327                 obligation.recursion_depth + 1,
2328                 cache_projection,
2329                 &mut nested_obligations,
2330             )
2331         })
2332     } else {
2333         cache_projection
2334     };
2335 
2336     debug!(?cache_projection, ?obligation_projection);
2337 
2338     match infcx.at(cause, param_env).eq(
2339         DefineOpaqueTypes::No,
2340         cache_projection,
2341         obligation_projection,
2342     ) {
2343         Ok(InferOk { value: _, obligations }) => {
2344             nested_obligations.extend(obligations);
2345             assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations);
2346             // FIXME(associated_const_equality): Handle consts here as well? Maybe this progress type should just take
2347             // a term instead.
2348             Progress { term: cache_entry.term, obligations: nested_obligations }
2349         }
2350         Err(e) => {
2351             let msg = format!(
2352                 "Failed to unify obligation `{:?}` with poly_projection `{:?}`: {:?}",
2353                 obligation, poly_cache_entry, e,
2354             );
2355             debug!("confirm_param_env_candidate: {}", msg);
2356             let err = Ty::new_error_with_message(infcx.tcx, obligation.cause.span, msg);
2357             Progress { term: err.into(), obligations: vec![] }
2358         }
2359     }
2360 }
2361 
confirm_impl_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>, ) -> Progress<'tcx>2362 fn confirm_impl_candidate<'cx, 'tcx>(
2363     selcx: &mut SelectionContext<'cx, 'tcx>,
2364     obligation: &ProjectionTyObligation<'tcx>,
2365     impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
2366 ) -> Progress<'tcx> {
2367     let tcx = selcx.tcx();
2368 
2369     let ImplSourceUserDefinedData { impl_def_id, substs, mut nested } = impl_impl_source;
2370     let assoc_item_id = obligation.predicate.def_id;
2371     let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
2372 
2373     let param_env = obligation.param_env;
2374     let assoc_ty = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) {
2375         Ok(assoc_ty) => assoc_ty,
2376         Err(guar) => return Progress::error(tcx, guar),
2377     };
2378 
2379     if !assoc_ty.item.defaultness(tcx).has_value() {
2380         // This means that the impl is missing a definition for the
2381         // associated type. This error will be reported by the type
2382         // checker method `check_impl_items_against_trait`, so here we
2383         // just return Error.
2384         debug!(
2385             "confirm_impl_candidate: no associated type {:?} for {:?}",
2386             assoc_ty.item.name, obligation.predicate
2387         );
2388         return Progress { term: Ty::new_misc_error(tcx).into(), obligations: nested };
2389     }
2390     // If we're trying to normalize `<Vec<u32> as X>::A<S>` using
2391     //`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then:
2392     //
2393     // * `obligation.predicate.substs` is `[Vec<u32>, S]`
2394     // * `substs` is `[u32]`
2395     // * `substs` ends up as `[u32, S]`
2396     let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs);
2397     let substs =
2398         translate_substs(selcx.infcx, param_env, impl_def_id, substs, assoc_ty.defining_node);
2399     let ty = tcx.type_of(assoc_ty.item.def_id);
2400     let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
2401     let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
2402         let did = assoc_ty.item.def_id;
2403         let identity_substs = crate::traits::InternalSubsts::identity_for_item(tcx, did);
2404         let uv = ty::UnevaluatedConst::new(did, identity_substs);
2405         ty.map_bound(|ty| ty::Const::new_unevaluated(tcx, uv, ty).into())
2406     } else {
2407         ty.map_bound(|ty| ty.into())
2408     };
2409     if !check_substs_compatible(tcx, assoc_ty.item, substs) {
2410         let err = Ty::new_error_with_message(
2411             tcx,
2412             obligation.cause.span,
2413             "impl item and trait item have different parameters",
2414         );
2415         Progress { term: err.into(), obligations: nested }
2416     } else {
2417         assoc_ty_own_obligations(selcx, obligation, &mut nested);
2418         Progress { term: term.subst(tcx, substs), obligations: nested }
2419     }
2420 }
2421 
confirm_impl_trait_in_trait_candidate<'tcx>( selcx: &mut SelectionContext<'_, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, data: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>, ) -> Progress<'tcx>2422 fn confirm_impl_trait_in_trait_candidate<'tcx>(
2423     selcx: &mut SelectionContext<'_, 'tcx>,
2424     obligation: &ProjectionTyObligation<'tcx>,
2425     data: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
2426 ) -> Progress<'tcx> {
2427     let tcx = selcx.tcx();
2428     let mut obligations = data.nested;
2429 
2430     let trait_fn_def_id = tcx.impl_trait_in_trait_parent_fn(obligation.predicate.def_id);
2431     let leaf_def = match specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) {
2432         Ok(assoc_ty) => assoc_ty,
2433         Err(guar) => return Progress::error(tcx, guar),
2434     };
2435     // We don't support specialization for RPITITs anyways... yet.
2436     // Also don't try to project to an RPITIT that has no value
2437     if !leaf_def.is_final() || !leaf_def.item.defaultness(tcx).has_value() {
2438         return Progress { term: Ty::new_misc_error(tcx).into(), obligations };
2439     }
2440 
2441     // Use the default `impl Trait` for the trait, e.g., for a default trait body
2442     if leaf_def.item.container == ty::AssocItemContainer::TraitContainer {
2443         return Progress {
2444             term: Ty::new_opaque(tcx, obligation.predicate.def_id, obligation.predicate.substs)
2445                 .into(),
2446             obligations,
2447         };
2448     }
2449 
2450     // Rebase from {trait}::{fn}::{opaque} to {impl}::{fn}::{opaque},
2451     // since `data.substs` are the impl substs.
2452     let impl_fn_substs =
2453         obligation.predicate.substs.rebase_onto(tcx, tcx.parent(trait_fn_def_id), data.substs);
2454     let impl_fn_substs = translate_substs(
2455         selcx.infcx,
2456         obligation.param_env,
2457         data.impl_def_id,
2458         impl_fn_substs,
2459         leaf_def.defining_node,
2460     );
2461 
2462     if !check_substs_compatible(tcx, leaf_def.item, impl_fn_substs) {
2463         let err = Ty::new_error_with_message(
2464             tcx,
2465             obligation.cause.span,
2466             "impl method and trait method have different parameters",
2467         );
2468         return Progress { term: err.into(), obligations };
2469     }
2470 
2471     let impl_fn_def_id = leaf_def.item.def_id;
2472 
2473     let cause = ObligationCause::new(
2474         obligation.cause.span,
2475         obligation.cause.body_id,
2476         super::ItemObligation(impl_fn_def_id),
2477     );
2478     let predicates = normalize_with_depth_to(
2479         selcx,
2480         obligation.param_env,
2481         cause.clone(),
2482         obligation.recursion_depth + 1,
2483         tcx.predicates_of(impl_fn_def_id).instantiate(tcx, impl_fn_substs),
2484         &mut obligations,
2485     );
2486     obligations.extend(predicates.into_iter().map(|(pred, span)| {
2487         Obligation::with_depth(
2488             tcx,
2489             ObligationCause::new(
2490                 obligation.cause.span,
2491                 obligation.cause.body_id,
2492                 if span.is_dummy() {
2493                     super::ItemObligation(impl_fn_def_id)
2494                 } else {
2495                     super::BindingObligation(impl_fn_def_id, span)
2496                 },
2497             ),
2498             obligation.recursion_depth + 1,
2499             obligation.param_env,
2500             pred,
2501         )
2502     }));
2503 
2504     let ty = normalize_with_depth_to(
2505         selcx,
2506         obligation.param_env,
2507         cause.clone(),
2508         obligation.recursion_depth + 1,
2509         tcx.collect_return_position_impl_trait_in_trait_tys(impl_fn_def_id).map_or_else(
2510             |guar| Ty::new_error(tcx, guar),
2511             |tys| tys[&obligation.predicate.def_id].subst(tcx, impl_fn_substs),
2512         ),
2513         &mut obligations,
2514     );
2515 
2516     Progress { term: ty.into(), obligations }
2517 }
2518 
2519 // Get obligations corresponding to the predicates from the where-clause of the
2520 // associated type itself.
assoc_ty_own_obligations<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, nested: &mut Vec<PredicateObligation<'tcx>>, )2521 fn assoc_ty_own_obligations<'cx, 'tcx>(
2522     selcx: &mut SelectionContext<'cx, 'tcx>,
2523     obligation: &ProjectionTyObligation<'tcx>,
2524     nested: &mut Vec<PredicateObligation<'tcx>>,
2525 ) {
2526     let tcx = selcx.tcx();
2527     let predicates = tcx
2528         .predicates_of(obligation.predicate.def_id)
2529         .instantiate_own(tcx, obligation.predicate.substs);
2530     for (predicate, span) in predicates {
2531         let normalized = normalize_with_depth_to(
2532             selcx,
2533             obligation.param_env,
2534             obligation.cause.clone(),
2535             obligation.recursion_depth + 1,
2536             predicate,
2537             nested,
2538         );
2539 
2540         let nested_cause = if matches!(
2541             obligation.cause.code(),
2542             super::CompareImplItemObligation { .. }
2543                 | super::CheckAssociatedTypeBounds { .. }
2544                 | super::AscribeUserTypeProvePredicate(..)
2545         ) {
2546             obligation.cause.clone()
2547         } else if span.is_dummy() {
2548             ObligationCause::new(
2549                 obligation.cause.span,
2550                 obligation.cause.body_id,
2551                 super::ItemObligation(obligation.predicate.def_id),
2552             )
2553         } else {
2554             ObligationCause::new(
2555                 obligation.cause.span,
2556                 obligation.cause.body_id,
2557                 super::BindingObligation(obligation.predicate.def_id, span),
2558             )
2559         };
2560         nested.push(Obligation::with_depth(
2561             tcx,
2562             nested_cause,
2563             obligation.recursion_depth + 1,
2564             obligation.param_env,
2565             normalized,
2566         ));
2567     }
2568 }
2569 
2570 pub(crate) trait ProjectionCacheKeyExt<'cx, 'tcx>: Sized {
from_poly_projection_predicate( selcx: &mut SelectionContext<'cx, 'tcx>, predicate: ty::PolyProjectionPredicate<'tcx>, ) -> Option<Self>2571     fn from_poly_projection_predicate(
2572         selcx: &mut SelectionContext<'cx, 'tcx>,
2573         predicate: ty::PolyProjectionPredicate<'tcx>,
2574     ) -> Option<Self>;
2575 }
2576 
2577 impl<'cx, 'tcx> ProjectionCacheKeyExt<'cx, 'tcx> for ProjectionCacheKey<'tcx> {
from_poly_projection_predicate( selcx: &mut SelectionContext<'cx, 'tcx>, predicate: ty::PolyProjectionPredicate<'tcx>, ) -> Option<Self>2578     fn from_poly_projection_predicate(
2579         selcx: &mut SelectionContext<'cx, 'tcx>,
2580         predicate: ty::PolyProjectionPredicate<'tcx>,
2581     ) -> Option<Self> {
2582         let infcx = selcx.infcx;
2583         // We don't do cross-snapshot caching of obligations with escaping regions,
2584         // so there's no cache key to use
2585         predicate.no_bound_vars().map(|predicate| {
2586             ProjectionCacheKey::new(
2587                 // We don't attempt to match up with a specific type-variable state
2588                 // from a specific call to `opt_normalize_projection_type` - if
2589                 // there's no precise match, the original cache entry is "stranded"
2590                 // anyway.
2591                 infcx.resolve_vars_if_possible(predicate.projection_ty),
2592             )
2593         })
2594     }
2595 }
2596