]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_trait_selection/src/traits/project.rs
Rollup merge of #87266 - hellow554:issue87076, r=Mark-Simulacrum
[rust.git] / compiler / rustc_trait_selection / src / traits / project.rs
1 //! Code for projecting associated types out of trait references.
2
3 use super::specialization_graph;
4 use super::translate_substs;
5 use super::util;
6 use super::MismatchedProjectionTypes;
7 use super::Obligation;
8 use super::ObligationCause;
9 use super::PredicateObligation;
10 use super::Selection;
11 use super::SelectionContext;
12 use super::SelectionError;
13 use super::{
14     ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
15     ImplSourceGeneratorData, ImplSourcePointeeData, ImplSourceUserDefinedData,
16 };
17 use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
18
19 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
20 use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
21 use crate::traits::error_reporting::InferCtxtExt;
22 use rustc_data_structures::stack::ensure_sufficient_stack;
23 use rustc_errors::ErrorReported;
24 use rustc_hir::def_id::DefId;
25 use rustc_hir::lang_items::LangItem;
26 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
27 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
28 use rustc_middle::ty::subst::Subst;
29 use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
30 use rustc_span::symbol::sym;
31
32 use std::collections::BTreeMap;
33
34 pub use rustc_middle::traits::Reveal;
35
36 pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPredicate<'tcx>>;
37
38 pub type ProjectionObligation<'tcx> = Obligation<'tcx, ty::ProjectionPredicate<'tcx>>;
39
40 pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>>;
41
42 pub(super) struct InProgress;
43
44 /// When attempting to resolve `<T as TraitRef>::Name` ...
45 #[derive(Debug)]
46 pub enum ProjectionTyError<'tcx> {
47     /// ...we found multiple sources of information and couldn't resolve the ambiguity.
48     TooManyCandidates,
49
50     /// ...an error occurred matching `T : TraitRef`
51     TraitSelectionError(SelectionError<'tcx>),
52 }
53
54 #[derive(PartialEq, Eq, Debug)]
55 enum ProjectionTyCandidate<'tcx> {
56     /// From a where-clause in the env or object type
57     ParamEnv(ty::PolyProjectionPredicate<'tcx>),
58
59     /// From the definition of `Trait` when you have something like <<A as Trait>::B as Trait2>::C
60     TraitDef(ty::PolyProjectionPredicate<'tcx>),
61
62     /// Bounds specified on an object type
63     Object(ty::PolyProjectionPredicate<'tcx>),
64
65     /// From a "impl" (or a "pseudo-impl" returned by select)
66     Select(Selection<'tcx>),
67 }
68
69 enum ProjectionTyCandidateSet<'tcx> {
70     None,
71     Single(ProjectionTyCandidate<'tcx>),
72     Ambiguous,
73     Error(SelectionError<'tcx>),
74 }
75
76 impl<'tcx> ProjectionTyCandidateSet<'tcx> {
77     fn mark_ambiguous(&mut self) {
78         *self = ProjectionTyCandidateSet::Ambiguous;
79     }
80
81     fn mark_error(&mut self, err: SelectionError<'tcx>) {
82         *self = ProjectionTyCandidateSet::Error(err);
83     }
84
85     // Returns true if the push was successful, or false if the candidate
86     // was discarded -- this could be because of ambiguity, or because
87     // a higher-priority candidate is already there.
88     fn push_candidate(&mut self, candidate: ProjectionTyCandidate<'tcx>) -> bool {
89         use self::ProjectionTyCandidate::*;
90         use self::ProjectionTyCandidateSet::*;
91
92         // This wacky variable is just used to try and
93         // make code readable and avoid confusing paths.
94         // It is assigned a "value" of `()` only on those
95         // paths in which we wish to convert `*self` to
96         // ambiguous (and return false, because the candidate
97         // was not used). On other paths, it is not assigned,
98         // and hence if those paths *could* reach the code that
99         // comes after the match, this fn would not compile.
100         let convert_to_ambiguous;
101
102         match self {
103             None => {
104                 *self = Single(candidate);
105                 return true;
106             }
107
108             Single(current) => {
109                 // Duplicates can happen inside ParamEnv. In the case, we
110                 // perform a lazy deduplication.
111                 if current == &candidate {
112                     return false;
113                 }
114
115                 // Prefer where-clauses. As in select, if there are multiple
116                 // candidates, we prefer where-clause candidates over impls.  This
117                 // may seem a bit surprising, since impls are the source of
118                 // "truth" in some sense, but in fact some of the impls that SEEM
119                 // applicable are not, because of nested obligations. Where
120                 // clauses are the safer choice. See the comment on
121                 // `select::SelectionCandidate` and #21974 for more details.
122                 match (current, candidate) {
123                     (ParamEnv(..), ParamEnv(..)) => convert_to_ambiguous = (),
124                     (ParamEnv(..), _) => return false,
125                     (_, ParamEnv(..)) => unreachable!(),
126                     (_, _) => convert_to_ambiguous = (),
127                 }
128             }
129
130             Ambiguous | Error(..) => {
131                 return false;
132             }
133         }
134
135         // We only ever get here when we moved from a single candidate
136         // to ambiguous.
137         let () = convert_to_ambiguous;
138         *self = Ambiguous;
139         false
140     }
141 }
142
143 /// Evaluates constraints of the form:
144 ///
145 ///     for<...> <T as Trait>::U == V
146 ///
147 /// If successful, this may result in additional obligations. Also returns
148 /// the projection cache key used to track these additional obligations.
149 ///
150 /// ## Returns
151 ///
152 /// - `Err(_)`: the projection can be normalized, but is not equal to the
153 ///   expected type.
154 /// - `Ok(Err(InProgress))`: this is called recursively while normalizing
155 ///   the same projection.
156 /// - `Ok(Ok(None))`: The projection cannot be normalized due to ambiguity
157 ///   (resolving some inference variables in the projection may fix this).
158 /// - `Ok(Ok(Some(obligations)))`: The projection bound holds subject to
159 ///    the given obligations. If the projection cannot be normalized because
160 ///    the required trait bound doesn't hold this returned with `obligations`
161 ///    being a predicate that cannot be proven.
162 #[instrument(level = "debug", skip(selcx))]
163 pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
164     selcx: &mut SelectionContext<'cx, 'tcx>,
165     obligation: &PolyProjectionObligation<'tcx>,
166 ) -> Result<
167     Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
168     MismatchedProjectionTypes<'tcx>,
169 > {
170     let infcx = selcx.infcx();
171     infcx.commit_if_ok(|_snapshot| {
172         let placeholder_predicate =
173             infcx.replace_bound_vars_with_placeholders(obligation.predicate);
174
175         let placeholder_obligation = obligation.with(placeholder_predicate);
176         let result = project_and_unify_type(selcx, &placeholder_obligation)?;
177         Ok(result)
178     })
179 }
180
181 /// Evaluates constraints of the form:
182 ///
183 ///     <T as Trait>::U == V
184 ///
185 /// If successful, this may result in additional obligations.
186 ///
187 /// See [poly_project_and_unify_type] for an explanation of the return value.
188 fn project_and_unify_type<'cx, 'tcx>(
189     selcx: &mut SelectionContext<'cx, 'tcx>,
190     obligation: &ProjectionObligation<'tcx>,
191 ) -> Result<
192     Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
193     MismatchedProjectionTypes<'tcx>,
194 > {
195     debug!(?obligation, "project_and_unify_type");
196
197     let mut obligations = vec![];
198     let normalized_ty = match opt_normalize_projection_type(
199         selcx,
200         obligation.param_env,
201         obligation.predicate.projection_ty,
202         obligation.cause.clone(),
203         obligation.recursion_depth,
204         &mut obligations,
205     ) {
206         Ok(Some(n)) => n,
207         Ok(None) => return Ok(Ok(None)),
208         Err(InProgress) => return Ok(Err(InProgress)),
209     };
210
211     debug!(?normalized_ty, ?obligations, "project_and_unify_type result");
212
213     let infcx = selcx.infcx();
214     match infcx
215         .at(&obligation.cause, obligation.param_env)
216         .eq(normalized_ty, obligation.predicate.ty)
217     {
218         Ok(InferOk { obligations: inferred_obligations, value: () }) => {
219             obligations.extend(inferred_obligations);
220             Ok(Ok(Some(obligations)))
221         }
222         Err(err) => {
223             debug!("project_and_unify_type: equating types encountered error {:?}", err);
224             Err(MismatchedProjectionTypes { err })
225         }
226     }
227 }
228
229 /// Normalizes any associated type projections in `value`, replacing
230 /// them with a fully resolved type where possible. The return value
231 /// combines the normalized result and any additional obligations that
232 /// were incurred as result.
233 pub fn normalize<'a, 'b, 'tcx, T>(
234     selcx: &'a mut SelectionContext<'b, 'tcx>,
235     param_env: ty::ParamEnv<'tcx>,
236     cause: ObligationCause<'tcx>,
237     value: T,
238 ) -> Normalized<'tcx, T>
239 where
240     T: TypeFoldable<'tcx>,
241 {
242     let mut obligations = Vec::new();
243     let value = normalize_to(selcx, param_env, cause, value, &mut obligations);
244     Normalized { value, obligations }
245 }
246
247 pub fn normalize_to<'a, 'b, 'tcx, T>(
248     selcx: &'a mut SelectionContext<'b, 'tcx>,
249     param_env: ty::ParamEnv<'tcx>,
250     cause: ObligationCause<'tcx>,
251     value: T,
252     obligations: &mut Vec<PredicateObligation<'tcx>>,
253 ) -> T
254 where
255     T: TypeFoldable<'tcx>,
256 {
257     normalize_with_depth_to(selcx, param_env, cause, 0, value, obligations)
258 }
259
260 /// As `normalize`, but with a custom depth.
261 pub fn normalize_with_depth<'a, 'b, 'tcx, T>(
262     selcx: &'a mut SelectionContext<'b, 'tcx>,
263     param_env: ty::ParamEnv<'tcx>,
264     cause: ObligationCause<'tcx>,
265     depth: usize,
266     value: T,
267 ) -> Normalized<'tcx, T>
268 where
269     T: TypeFoldable<'tcx>,
270 {
271     let mut obligations = Vec::new();
272     let value = normalize_with_depth_to(selcx, param_env, cause, depth, value, &mut obligations);
273     Normalized { value, obligations }
274 }
275
276 #[instrument(level = "info", skip(selcx, param_env, cause, obligations))]
277 pub fn normalize_with_depth_to<'a, 'b, 'tcx, T>(
278     selcx: &'a mut SelectionContext<'b, 'tcx>,
279     param_env: ty::ParamEnv<'tcx>,
280     cause: ObligationCause<'tcx>,
281     depth: usize,
282     value: T,
283     obligations: &mut Vec<PredicateObligation<'tcx>>,
284 ) -> T
285 where
286     T: TypeFoldable<'tcx>,
287 {
288     debug!(obligations.len = obligations.len());
289     let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth, obligations);
290     let result = ensure_sufficient_stack(|| normalizer.fold(value));
291     debug!(?result, obligations.len = normalizer.obligations.len());
292     debug!(?normalizer.obligations,);
293     result
294 }
295
296 pub(crate) fn needs_normalization<'tcx, T: TypeFoldable<'tcx>>(value: &T, reveal: Reveal) -> bool {
297     match reveal {
298         Reveal::UserFacing => value
299             .has_type_flags(ty::TypeFlags::HAS_TY_PROJECTION | ty::TypeFlags::HAS_CT_PROJECTION),
300         Reveal::All => value.has_type_flags(
301             ty::TypeFlags::HAS_TY_PROJECTION
302                 | ty::TypeFlags::HAS_TY_OPAQUE
303                 | ty::TypeFlags::HAS_CT_PROJECTION,
304         ),
305     }
306 }
307
308 struct AssocTypeNormalizer<'a, 'b, 'tcx> {
309     selcx: &'a mut SelectionContext<'b, 'tcx>,
310     param_env: ty::ParamEnv<'tcx>,
311     cause: ObligationCause<'tcx>,
312     obligations: &'a mut Vec<PredicateObligation<'tcx>>,
313     depth: usize,
314     universes: Vec<Option<ty::UniverseIndex>>,
315 }
316
317 impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
318     fn new(
319         selcx: &'a mut SelectionContext<'b, 'tcx>,
320         param_env: ty::ParamEnv<'tcx>,
321         cause: ObligationCause<'tcx>,
322         depth: usize,
323         obligations: &'a mut Vec<PredicateObligation<'tcx>>,
324     ) -> AssocTypeNormalizer<'a, 'b, 'tcx> {
325         AssocTypeNormalizer { selcx, param_env, cause, obligations, depth, universes: vec![] }
326     }
327
328     fn fold<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
329         let value = self.selcx.infcx().resolve_vars_if_possible(value);
330         debug!(?value);
331
332         assert!(
333             !value.has_escaping_bound_vars(),
334             "Normalizing {:?} without wrapping in a `Binder`",
335             value
336         );
337
338         if !needs_normalization(&value, self.param_env.reveal()) {
339             value
340         } else {
341             value.fold_with(self)
342         }
343     }
344 }
345
346 impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
347     fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
348         self.selcx.tcx()
349     }
350
351     fn fold_binder<T: TypeFoldable<'tcx>>(
352         &mut self,
353         t: ty::Binder<'tcx, T>,
354     ) -> ty::Binder<'tcx, T> {
355         self.universes.push(None);
356         let t = t.super_fold_with(self);
357         self.universes.pop();
358         t
359     }
360
361     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
362         if !needs_normalization(&ty, self.param_env.reveal()) {
363             return ty;
364         }
365         // We don't want to normalize associated types that occur inside of region
366         // binders, because they may contain bound regions, and we can't cope with that.
367         //
368         // Example:
369         //
370         //     for<'a> fn(<T as Foo<&'a>>::A)
371         //
372         // Instead of normalizing `<T as Foo<&'a>>::A` here, we'll
373         // normalize it when we instantiate those bound regions (which
374         // should occur eventually).
375
376         let ty = ty.super_fold_with(self);
377         match *ty.kind() {
378             ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
379                 // Only normalize `impl Trait` after type-checking, usually in codegen.
380                 match self.param_env.reveal() {
381                     Reveal::UserFacing => ty,
382
383                     Reveal::All => {
384                         let recursion_limit = self.tcx().recursion_limit();
385                         if !recursion_limit.value_within_limit(self.depth) {
386                             let obligation = Obligation::with_depth(
387                                 self.cause.clone(),
388                                 recursion_limit.0,
389                                 self.param_env,
390                                 ty,
391                             );
392                             self.selcx.infcx().report_overflow_error(&obligation, true);
393                         }
394
395                         let generic_ty = self.tcx().type_of(def_id);
396                         let concrete_ty = generic_ty.subst(self.tcx(), substs);
397                         self.depth += 1;
398                         let folded_ty = self.fold_ty(concrete_ty);
399                         self.depth -= 1;
400                         folded_ty
401                     }
402                 }
403             }
404
405             ty::Projection(data) if !data.has_escaping_bound_vars() => {
406                 // This is kind of hacky -- we need to be able to
407                 // handle normalization within binders because
408                 // otherwise we wind up a need to normalize when doing
409                 // trait matching (since you can have a trait
410                 // obligation like `for<'a> T::B: Fn(&'a i32)`), but
411                 // we can't normalize with bound regions in scope. So
412                 // far now we just ignore binders but only normalize
413                 // if all bound regions are gone (and then we still
414                 // have to renormalize whenever we instantiate a
415                 // binder). It would be better to normalize in a
416                 // binding-aware fashion.
417
418                 let normalized_ty = normalize_projection_type(
419                     self.selcx,
420                     self.param_env,
421                     data,
422                     self.cause.clone(),
423                     self.depth,
424                     &mut self.obligations,
425                 );
426                 debug!(
427                     ?self.depth,
428                     ?ty,
429                     ?normalized_ty,
430                     obligations.len = ?self.obligations.len(),
431                     "AssocTypeNormalizer: normalized type"
432                 );
433                 normalized_ty
434             }
435
436             ty::Projection(data) if !data.trait_ref(self.tcx()).has_escaping_bound_vars() => {
437                 // Okay, so you thought the previous branch was hacky. Well, to
438                 // extend upon this, when the *trait ref* doesn't have escaping
439                 // bound vars, but the associated item *does* (can only occur
440                 // with GATs), then we might still be able to project the type.
441                 // For this, we temporarily replace the bound vars with
442                 // placeholders. Note though, that in the case that we still
443                 // can't project for whatever reason (e.g. self type isn't
444                 // known enough), we *can't* register an obligation and return
445                 // an inference variable (since then that obligation would have
446                 // bound vars and that's a can of worms). Instead, we just
447                 // give up and fall back to pretending like we never tried!
448
449                 let infcx = self.selcx.infcx();
450                 let (data, mapped_regions, mapped_types, mapped_consts) =
451                     BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
452                 let normalized_ty = opt_normalize_projection_type(
453                     self.selcx,
454                     self.param_env,
455                     data,
456                     self.cause.clone(),
457                     self.depth,
458                     &mut self.obligations,
459                 )
460                 .ok()
461                 .flatten()
462                 .unwrap_or_else(|| ty);
463
464                 let normalized_ty = PlaceholderReplacer::replace_placeholders(
465                     infcx,
466                     mapped_regions,
467                     mapped_types,
468                     mapped_consts,
469                     &self.universes,
470                     normalized_ty,
471                 );
472                 debug!(
473                     ?self.depth,
474                     ?ty,
475                     ?normalized_ty,
476                     obligations.len = ?self.obligations.len(),
477                     "AssocTypeNormalizer: normalized type"
478                 );
479                 normalized_ty
480             }
481
482             _ => ty,
483         }
484     }
485
486     fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
487         if self.selcx.tcx().lazy_normalization() {
488             constant
489         } else {
490             let constant = constant.super_fold_with(self);
491             constant.eval(self.selcx.tcx(), self.param_env)
492         }
493     }
494 }
495
496 pub struct BoundVarReplacer<'me, 'tcx> {
497     infcx: &'me InferCtxt<'me, 'tcx>,
498     // These three maps track the bound variable that were replaced by placeholders. It might be
499     // nice to remove these since we already have the `kind` in the placeholder; we really just need
500     // the `var` (but we *could* bring that into scope if we were to track them as we pass them).
501     mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
502     mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
503     mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
504     // The current depth relative to *this* folding, *not* the entire normalization. In other words,
505     // the depth of binders we've passed here.
506     current_index: ty::DebruijnIndex,
507     // The `UniverseIndex` of the binding levels above us. These are optional, since we are lazy:
508     // we don't actually create a universe until we see a bound var we have to replace.
509     universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>,
510 }
511
512 impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
513     /// Returns `Some` if we *were* able to replace bound vars. If there are any bound vars that
514     /// use a binding level above `universe_indices.len()`, we fail.
515     pub fn replace_bound_vars<T: TypeFoldable<'tcx>>(
516         infcx: &'me InferCtxt<'me, 'tcx>,
517         universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>,
518         value: T,
519     ) -> (
520         T,
521         BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
522         BTreeMap<ty::PlaceholderType, ty::BoundTy>,
523         BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
524     ) {
525         let mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion> = BTreeMap::new();
526         let mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy> = BTreeMap::new();
527         let mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar> = BTreeMap::new();
528
529         let mut replacer = BoundVarReplacer {
530             infcx,
531             mapped_regions,
532             mapped_types,
533             mapped_consts,
534             current_index: ty::INNERMOST,
535             universe_indices,
536         };
537
538         let value = value.super_fold_with(&mut replacer);
539
540         (value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts)
541     }
542
543     fn universe_for(&mut self, debruijn: ty::DebruijnIndex) -> ty::UniverseIndex {
544         let infcx = self.infcx;
545         let index =
546             self.universe_indices.len() - debruijn.as_usize() + self.current_index.as_usize() - 1;
547         let universe = self.universe_indices[index].unwrap_or_else(|| {
548             for i in self.universe_indices.iter_mut().take(index + 1) {
549                 *i = i.or_else(|| Some(infcx.create_next_universe()))
550             }
551             self.universe_indices[index].unwrap()
552         });
553         universe
554     }
555 }
556
557 impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
558     fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
559         self.infcx.tcx
560     }
561
562     fn fold_binder<T: TypeFoldable<'tcx>>(
563         &mut self,
564         t: ty::Binder<'tcx, T>,
565     ) -> ty::Binder<'tcx, T> {
566         self.current_index.shift_in(1);
567         let t = t.super_fold_with(self);
568         self.current_index.shift_out(1);
569         t
570     }
571
572     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
573         match *r {
574             ty::ReLateBound(debruijn, _)
575                 if debruijn.as_usize() + 1
576                     > self.current_index.as_usize() + self.universe_indices.len() =>
577             {
578                 bug!("Bound vars outside of `self.universe_indices`");
579             }
580             ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => {
581                 let universe = self.universe_for(debruijn);
582                 let p = ty::PlaceholderRegion { universe, name: br.kind };
583                 self.mapped_regions.insert(p.clone(), br);
584                 self.infcx.tcx.mk_region(ty::RePlaceholder(p))
585             }
586             _ => r,
587         }
588     }
589
590     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
591         match *t.kind() {
592             ty::Bound(debruijn, _)
593                 if debruijn.as_usize() + 1
594                     > self.current_index.as_usize() + self.universe_indices.len() =>
595             {
596                 bug!("Bound vars outside of `self.universe_indices`");
597             }
598             ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
599                 let universe = self.universe_for(debruijn);
600                 let p = ty::PlaceholderType { universe, name: bound_ty.var };
601                 self.mapped_types.insert(p.clone(), bound_ty);
602                 self.infcx.tcx.mk_ty(ty::Placeholder(p))
603             }
604             _ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
605             _ => t,
606         }
607     }
608
609     fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
610         match *ct {
611             ty::Const { val: ty::ConstKind::Bound(debruijn, _), ty: _ }
612                 if debruijn.as_usize() + 1
613                     > self.current_index.as_usize() + self.universe_indices.len() =>
614             {
615                 bug!("Bound vars outside of `self.universe_indices`");
616             }
617             ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty }
618                 if debruijn >= self.current_index =>
619             {
620                 let universe = self.universe_for(debruijn);
621                 let p = ty::PlaceholderConst {
622                     universe,
623                     name: ty::BoundConst { var: bound_const, ty },
624                 };
625                 self.mapped_consts.insert(p.clone(), bound_const);
626                 self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty })
627             }
628             _ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self),
629             _ => ct,
630         }
631     }
632 }
633
634 // The inverse of `BoundVarReplacer`: replaces placeholders with the bound vars from which they came.
635 pub struct PlaceholderReplacer<'me, 'tcx> {
636     infcx: &'me InferCtxt<'me, 'tcx>,
637     mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
638     mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
639     mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
640     universe_indices: &'me Vec<Option<ty::UniverseIndex>>,
641     current_index: ty::DebruijnIndex,
642 }
643
644 impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
645     pub fn replace_placeholders<T: TypeFoldable<'tcx>>(
646         infcx: &'me InferCtxt<'me, 'tcx>,
647         mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
648         mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
649         mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
650         universe_indices: &'me Vec<Option<ty::UniverseIndex>>,
651         value: T,
652     ) -> T {
653         let mut replacer = PlaceholderReplacer {
654             infcx,
655             mapped_regions,
656             mapped_types,
657             mapped_consts,
658             universe_indices,
659             current_index: ty::INNERMOST,
660         };
661         value.super_fold_with(&mut replacer)
662     }
663 }
664
665 impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
666     fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
667         self.infcx.tcx
668     }
669
670     fn fold_binder<T: TypeFoldable<'tcx>>(
671         &mut self,
672         t: ty::Binder<'tcx, T>,
673     ) -> ty::Binder<'tcx, T> {
674         if !t.has_placeholders() && !t.has_infer_regions() {
675             return t;
676         }
677         self.current_index.shift_in(1);
678         let t = t.super_fold_with(self);
679         self.current_index.shift_out(1);
680         t
681     }
682
683     fn fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx> {
684         let r1 = match r0 {
685             ty::ReVar(_) => self
686                 .infcx
687                 .inner
688                 .borrow_mut()
689                 .unwrap_region_constraints()
690                 .opportunistic_resolve_region(self.infcx.tcx, r0),
691             _ => r0,
692         };
693
694         let r2 = match *r1 {
695             ty::RePlaceholder(p) => {
696                 let replace_var = self.mapped_regions.get(&p);
697                 match replace_var {
698                     Some(replace_var) => {
699                         let index = self
700                             .universe_indices
701                             .iter()
702                             .position(|u| matches!(u, Some(pu) if *pu == p.universe))
703                             .unwrap_or_else(|| bug!("Unexpected placeholder universe."));
704                         let db = ty::DebruijnIndex::from_usize(
705                             self.universe_indices.len() - index + self.current_index.as_usize() - 1,
706                         );
707                         self.tcx().mk_region(ty::ReLateBound(db, *replace_var))
708                     }
709                     None => r1,
710                 }
711             }
712             _ => r1,
713         };
714
715         debug!(?r0, ?r1, ?r2, "fold_region");
716
717         r2
718     }
719
720     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
721         match *ty.kind() {
722             ty::Placeholder(p) => {
723                 let replace_var = self.mapped_types.get(&p);
724                 match replace_var {
725                     Some(replace_var) => {
726                         let index = self
727                             .universe_indices
728                             .iter()
729                             .position(|u| matches!(u, Some(pu) if *pu == p.universe))
730                             .unwrap_or_else(|| bug!("Unexpected placeholder universe."));
731                         let db = ty::DebruijnIndex::from_usize(
732                             self.universe_indices.len() - index + self.current_index.as_usize() - 1,
733                         );
734                         self.tcx().mk_ty(ty::Bound(db, *replace_var))
735                     }
736                     None => ty,
737                 }
738             }
739
740             _ if ty.has_placeholders() || ty.has_infer_regions() => ty.super_fold_with(self),
741             _ => ty,
742         }
743     }
744
745     fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
746         if let ty::Const { val: ty::ConstKind::Placeholder(p), ty } = *ct {
747             let replace_var = self.mapped_consts.get(&p);
748             match replace_var {
749                 Some(replace_var) => {
750                     let index = self
751                         .universe_indices
752                         .iter()
753                         .position(|u| matches!(u, Some(pu) if *pu == p.universe))
754                         .unwrap_or_else(|| bug!("Unexpected placeholder universe."));
755                     let db = ty::DebruijnIndex::from_usize(
756                         self.universe_indices.len() - index + self.current_index.as_usize() - 1,
757                     );
758                     self.tcx()
759                         .mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty })
760                 }
761                 None => ct,
762             }
763         } else {
764             ct.super_fold_with(self)
765         }
766     }
767 }
768
769 /// The guts of `normalize`: normalize a specific projection like `<T
770 /// as Trait>::Item`. The result is always a type (and possibly
771 /// additional obligations). If ambiguity arises, which implies that
772 /// there are unresolved type variables in the projection, we will
773 /// substitute a fresh type variable `$X` and generate a new
774 /// obligation `<T as Trait>::Item == $X` for later.
775 pub fn normalize_projection_type<'a, 'b, 'tcx>(
776     selcx: &'a mut SelectionContext<'b, 'tcx>,
777     param_env: ty::ParamEnv<'tcx>,
778     projection_ty: ty::ProjectionTy<'tcx>,
779     cause: ObligationCause<'tcx>,
780     depth: usize,
781     obligations: &mut Vec<PredicateObligation<'tcx>>,
782 ) -> Ty<'tcx> {
783     opt_normalize_projection_type(
784         selcx,
785         param_env,
786         projection_ty,
787         cause.clone(),
788         depth,
789         obligations,
790     )
791     .ok()
792     .flatten()
793     .unwrap_or_else(move || {
794         // if we bottom out in ambiguity, create a type variable
795         // and a deferred predicate to resolve this when more type
796         // information is available.
797
798         let tcx = selcx.infcx().tcx;
799         let def_id = projection_ty.item_def_id;
800         let ty_var = selcx.infcx().next_ty_var(TypeVariableOrigin {
801             kind: TypeVariableOriginKind::NormalizeProjectionType,
802             span: tcx.def_span(def_id),
803         });
804         let projection = ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, ty: ty_var });
805         let obligation =
806             Obligation::with_depth(cause, depth + 1, param_env, projection.to_predicate(tcx));
807         obligations.push(obligation);
808         ty_var
809     })
810 }
811
812 /// The guts of `normalize`: normalize a specific projection like `<T
813 /// as Trait>::Item`. The result is always a type (and possibly
814 /// additional obligations). Returns `None` in the case of ambiguity,
815 /// which indicates that there are unbound type variables.
816 ///
817 /// This function used to return `Option<NormalizedTy<'tcx>>`, which contains a
818 /// `Ty<'tcx>` and an obligations vector. But that obligation vector was very
819 /// often immediately appended to another obligations vector. So now this
820 /// function takes an obligations vector and appends to it directly, which is
821 /// slightly uglier but avoids the need for an extra short-lived allocation.
822 #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
823 fn opt_normalize_projection_type<'a, 'b, 'tcx>(
824     selcx: &'a mut SelectionContext<'b, 'tcx>,
825     param_env: ty::ParamEnv<'tcx>,
826     projection_ty: ty::ProjectionTy<'tcx>,
827     cause: ObligationCause<'tcx>,
828     depth: usize,
829     obligations: &mut Vec<PredicateObligation<'tcx>>,
830 ) -> Result<Option<Ty<'tcx>>, InProgress> {
831     let infcx = selcx.infcx();
832
833     let projection_ty = infcx.resolve_vars_if_possible(projection_ty);
834     let cache_key = ProjectionCacheKey::new(projection_ty);
835
836     // FIXME(#20304) For now, I am caching here, which is good, but it
837     // means we don't capture the type variables that are created in
838     // the case of ambiguity. Which means we may create a large stream
839     // of such variables. OTOH, if we move the caching up a level, we
840     // would not benefit from caching when proving `T: Trait<U=Foo>`
841     // bounds. It might be the case that we want two distinct caches,
842     // or else another kind of cache entry.
843
844     let cache_result = infcx.inner.borrow_mut().projection_cache().try_start(cache_key);
845     match cache_result {
846         Ok(()) => debug!("no cache"),
847         Err(ProjectionCacheEntry::Ambiguous) => {
848             // If we found ambiguity the last time, that means we will continue
849             // to do so until some type in the key changes (and we know it
850             // hasn't, because we just fully resolved it).
851             debug!("found cache entry: ambiguous");
852             return Ok(None);
853         }
854         Err(ProjectionCacheEntry::InProgress) => {
855             // Under lazy normalization, this can arise when
856             // bootstrapping.  That is, imagine an environment with a
857             // where-clause like `A::B == u32`. Now, if we are asked
858             // to normalize `A::B`, we will want to check the
859             // where-clauses in scope. So we will try to unify `A::B`
860             // with `A::B`, which can trigger a recursive
861             // normalization.
862
863             debug!("found cache entry: in-progress");
864
865             // Cache that normalizing this projection resulted in a cycle. This
866             // should ensure that, unless this happens within a snapshot that's
867             // rolled back, fulfillment or evaluation will notice the cycle.
868
869             infcx.inner.borrow_mut().projection_cache().recur(cache_key);
870             return Err(InProgress);
871         }
872         Err(ProjectionCacheEntry::Recur) => {
873             debug!("recur cache");
874             return Err(InProgress);
875         }
876         Err(ProjectionCacheEntry::NormalizedTy(ty)) => {
877             // This is the hottest path in this function.
878             //
879             // If we find the value in the cache, then return it along
880             // with the obligations that went along with it. Note
881             // that, when using a fulfillment context, these
882             // obligations could in principle be ignored: they have
883             // already been registered when the cache entry was
884             // created (and hence the new ones will quickly be
885             // discarded as duplicated). But when doing trait
886             // evaluation this is not the case, and dropping the trait
887             // evaluations can causes ICEs (e.g., #43132).
888             debug!(?ty, "found normalized ty");
889             obligations.extend(ty.obligations);
890             return Ok(Some(ty.value));
891         }
892         Err(ProjectionCacheEntry::Error) => {
893             debug!("opt_normalize_projection_type: found error");
894             let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth);
895             obligations.extend(result.obligations);
896             return Ok(Some(result.value));
897         }
898     }
899
900     let obligation = Obligation::with_depth(cause.clone(), depth, param_env, projection_ty);
901     match project_type(selcx, &obligation) {
902         Ok(ProjectedTy::Progress(Progress {
903             ty: projected_ty,
904             obligations: mut projected_obligations,
905         })) => {
906             // if projection succeeded, then what we get out of this
907             // is also non-normalized (consider: it was derived from
908             // an impl, where-clause etc) and hence we must
909             // re-normalize it
910
911             debug!(?projected_ty, ?depth, ?projected_obligations);
912
913             let result = if projected_ty.has_projections() {
914                 let mut normalizer = AssocTypeNormalizer::new(
915                     selcx,
916                     param_env,
917                     cause,
918                     depth + 1,
919                     &mut projected_obligations,
920                 );
921                 let normalized_ty = normalizer.fold(projected_ty);
922
923                 debug!(?normalized_ty, ?depth);
924
925                 Normalized { value: normalized_ty, obligations: projected_obligations }
926             } else {
927                 Normalized { value: projected_ty, obligations: projected_obligations }
928             };
929
930             let cache_value = prune_cache_value_obligations(infcx, &result);
931             infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, cache_value);
932             obligations.extend(result.obligations);
933             Ok(Some(result.value))
934         }
935         Ok(ProjectedTy::NoProgress(projected_ty)) => {
936             debug!(?projected_ty, "opt_normalize_projection_type: no progress");
937             let result = Normalized { value: projected_ty, obligations: vec![] };
938             infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, result.clone());
939             // No need to extend `obligations`.
940             Ok(Some(result.value))
941         }
942         Err(ProjectionTyError::TooManyCandidates) => {
943             debug!("opt_normalize_projection_type: too many candidates");
944             infcx.inner.borrow_mut().projection_cache().ambiguous(cache_key);
945             Ok(None)
946         }
947         Err(ProjectionTyError::TraitSelectionError(_)) => {
948             debug!("opt_normalize_projection_type: ERROR");
949             // if we got an error processing the `T as Trait` part,
950             // just return `ty::err` but add the obligation `T :
951             // Trait`, which when processed will cause the error to be
952             // reported later
953
954             infcx.inner.borrow_mut().projection_cache().error(cache_key);
955             let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth);
956             obligations.extend(result.obligations);
957             Ok(Some(result.value))
958         }
959     }
960 }
961
962 /// If there are unresolved type variables, then we need to include
963 /// any subobligations that bind them, at least until those type
964 /// variables are fully resolved.
965 fn prune_cache_value_obligations<'a, 'tcx>(
966     infcx: &'a InferCtxt<'a, 'tcx>,
967     result: &NormalizedTy<'tcx>,
968 ) -> NormalizedTy<'tcx> {
969     if infcx.unresolved_type_vars(&result.value).is_none() {
970         return NormalizedTy { value: result.value, obligations: vec![] };
971     }
972
973     let mut obligations: Vec<_> = result
974         .obligations
975         .iter()
976         .filter(|obligation| {
977             let bound_predicate = obligation.predicate.kind();
978             match bound_predicate.skip_binder() {
979                 // We found a `T: Foo<X = U>` predicate, let's check
980                 // if `U` references any unresolved type
981                 // variables. In principle, we only care if this
982                 // projection can help resolve any of the type
983                 // variables found in `result.value` -- but we just
984                 // check for any type variables here, for fear of
985                 // indirect obligations (e.g., we project to `?0`,
986                 // but we have `T: Foo<X = ?1>` and `?1: Bar<X =
987                 // ?0>`).
988                 ty::PredicateKind::Projection(data) => {
989                     infcx.unresolved_type_vars(&bound_predicate.rebind(data.ty)).is_some()
990                 }
991
992                 // We are only interested in `T: Foo<X = U>` predicates, whre
993                 // `U` references one of `unresolved_type_vars`. =)
994                 _ => false,
995             }
996         })
997         .cloned()
998         .collect();
999
1000     obligations.shrink_to_fit();
1001
1002     NormalizedTy { value: result.value, obligations }
1003 }
1004
1005 /// If we are projecting `<T as Trait>::Item`, but `T: Trait` does not
1006 /// hold. In various error cases, we cannot generate a valid
1007 /// normalized projection. Therefore, we create an inference variable
1008 /// return an associated obligation that, when fulfilled, will lead to
1009 /// an error.
1010 ///
1011 /// Note that we used to return `Error` here, but that was quite
1012 /// dubious -- the premise was that an error would *eventually* be
1013 /// reported, when the obligation was processed. But in general once
1014 /// you see a `Error` you are supposed to be able to assume that an
1015 /// error *has been* reported, so that you can take whatever heuristic
1016 /// paths you want to take. To make things worse, it was possible for
1017 /// cycles to arise, where you basically had a setup like `<MyType<$0>
1018 /// as Trait>::Foo == $0`. Here, normalizing `<MyType<$0> as
1019 /// Trait>::Foo> to `[type error]` would lead to an obligation of
1020 /// `<MyType<[type error]> as Trait>::Foo`. We are supposed to report
1021 /// an error for this obligation, but we legitimately should not,
1022 /// because it contains `[type error]`. Yuck! (See issue #29857 for
1023 /// one case where this arose.)
1024 fn normalize_to_error<'a, 'tcx>(
1025     selcx: &mut SelectionContext<'a, 'tcx>,
1026     param_env: ty::ParamEnv<'tcx>,
1027     projection_ty: ty::ProjectionTy<'tcx>,
1028     cause: ObligationCause<'tcx>,
1029     depth: usize,
1030 ) -> NormalizedTy<'tcx> {
1031     let trait_ref = projection_ty.trait_ref(selcx.tcx()).to_poly_trait_ref();
1032     let trait_obligation = Obligation {
1033         cause,
1034         recursion_depth: depth,
1035         param_env,
1036         predicate: trait_ref.without_const().to_predicate(selcx.tcx()),
1037     };
1038     let tcx = selcx.infcx().tcx;
1039     let def_id = projection_ty.item_def_id;
1040     let new_value = selcx.infcx().next_ty_var(TypeVariableOrigin {
1041         kind: TypeVariableOriginKind::NormalizeProjectionType,
1042         span: tcx.def_span(def_id),
1043     });
1044     Normalized { value: new_value, obligations: vec![trait_obligation] }
1045 }
1046
1047 enum ProjectedTy<'tcx> {
1048     Progress(Progress<'tcx>),
1049     NoProgress(Ty<'tcx>),
1050 }
1051
1052 struct Progress<'tcx> {
1053     ty: Ty<'tcx>,
1054     obligations: Vec<PredicateObligation<'tcx>>,
1055 }
1056
1057 impl<'tcx> Progress<'tcx> {
1058     fn error(tcx: TyCtxt<'tcx>) -> Self {
1059         Progress { ty: tcx.ty_error(), obligations: vec![] }
1060     }
1061
1062     fn with_addl_obligations(mut self, mut obligations: Vec<PredicateObligation<'tcx>>) -> Self {
1063         debug!(
1064             self.obligations.len = ?self.obligations.len(),
1065             obligations.len = obligations.len(),
1066             "with_addl_obligations"
1067         );
1068
1069         debug!(?self.obligations, ?obligations, "with_addl_obligations");
1070
1071         self.obligations.append(&mut obligations);
1072         self
1073     }
1074 }
1075
1076 /// Computes the result of a projection type (if we can).
1077 ///
1078 /// IMPORTANT:
1079 /// - `obligation` must be fully normalized
1080 #[tracing::instrument(level = "info", skip(selcx))]
1081 fn project_type<'cx, 'tcx>(
1082     selcx: &mut SelectionContext<'cx, 'tcx>,
1083     obligation: &ProjectionTyObligation<'tcx>,
1084 ) -> Result<ProjectedTy<'tcx>, ProjectionTyError<'tcx>> {
1085     if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) {
1086         debug!("project: overflow!");
1087         // This should really be an immediate error, but some existing code
1088         // relies on being able to recover from this.
1089         return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow));
1090     }
1091
1092     if obligation.predicate.references_error() {
1093         return Ok(ProjectedTy::Progress(Progress::error(selcx.tcx())));
1094     }
1095
1096     let mut candidates = ProjectionTyCandidateSet::None;
1097
1098     // Make sure that the following procedures are kept in order. ParamEnv
1099     // needs to be first because it has highest priority, and Select checks
1100     // the return value of push_candidate which assumes it's ran at last.
1101     assemble_candidates_from_param_env(selcx, obligation, &mut candidates);
1102
1103     assemble_candidates_from_trait_def(selcx, obligation, &mut candidates);
1104
1105     assemble_candidates_from_object_ty(selcx, obligation, &mut candidates);
1106
1107     if let ProjectionTyCandidateSet::Single(ProjectionTyCandidate::Object(_)) = candidates {
1108         // Avoid normalization cycle from selection (see
1109         // `assemble_candidates_from_object_ty`).
1110         // FIXME(lazy_normalization): Lazy normalization should save us from
1111         // having to special case this.
1112     } else {
1113         assemble_candidates_from_impls(selcx, obligation, &mut candidates);
1114     };
1115
1116     match candidates {
1117         ProjectionTyCandidateSet::Single(candidate) => {
1118             Ok(ProjectedTy::Progress(confirm_candidate(selcx, obligation, candidate)))
1119         }
1120         ProjectionTyCandidateSet::None => Ok(ProjectedTy::NoProgress(
1121             selcx
1122                 .tcx()
1123                 .mk_projection(obligation.predicate.item_def_id, obligation.predicate.substs),
1124         )),
1125         // Error occurred while trying to processing impls.
1126         ProjectionTyCandidateSet::Error(e) => Err(ProjectionTyError::TraitSelectionError(e)),
1127         // Inherent ambiguity that prevents us from even enumerating the
1128         // candidates.
1129         ProjectionTyCandidateSet::Ambiguous => Err(ProjectionTyError::TooManyCandidates),
1130     }
1131 }
1132
1133 /// The first thing we have to do is scan through the parameter
1134 /// environment to see whether there are any projection predicates
1135 /// there that can answer this question.
1136 fn assemble_candidates_from_param_env<'cx, 'tcx>(
1137     selcx: &mut SelectionContext<'cx, 'tcx>,
1138     obligation: &ProjectionTyObligation<'tcx>,
1139     candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
1140 ) {
1141     debug!("assemble_candidates_from_param_env(..)");
1142     assemble_candidates_from_predicates(
1143         selcx,
1144         obligation,
1145         candidate_set,
1146         ProjectionTyCandidate::ParamEnv,
1147         obligation.param_env.caller_bounds().iter(),
1148         false,
1149     );
1150 }
1151
1152 /// In the case of a nested projection like <<A as Foo>::FooT as Bar>::BarT, we may find
1153 /// that the definition of `Foo` has some clues:
1154 ///
1155 /// ```
1156 /// trait Foo {
1157 ///     type FooT : Bar<BarT=i32>
1158 /// }
1159 /// ```
1160 ///
1161 /// Here, for example, we could conclude that the result is `i32`.
1162 fn assemble_candidates_from_trait_def<'cx, 'tcx>(
1163     selcx: &mut SelectionContext<'cx, 'tcx>,
1164     obligation: &ProjectionTyObligation<'tcx>,
1165     candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
1166 ) {
1167     debug!("assemble_candidates_from_trait_def(..)");
1168
1169     let tcx = selcx.tcx();
1170     // Check whether the self-type is itself a projection.
1171     // If so, extract what we know from the trait and try to come up with a good answer.
1172     let bounds = match *obligation.predicate.self_ty().kind() {
1173         ty::Projection(ref data) => tcx.item_bounds(data.item_def_id).subst(tcx, data.substs),
1174         ty::Opaque(def_id, substs) => tcx.item_bounds(def_id).subst(tcx, substs),
1175         ty::Infer(ty::TyVar(_)) => {
1176             // If the self-type is an inference variable, then it MAY wind up
1177             // being a projected type, so induce an ambiguity.
1178             candidate_set.mark_ambiguous();
1179             return;
1180         }
1181         _ => return,
1182     };
1183
1184     assemble_candidates_from_predicates(
1185         selcx,
1186         obligation,
1187         candidate_set,
1188         ProjectionTyCandidate::TraitDef,
1189         bounds.iter(),
1190         true,
1191     )
1192 }
1193
1194 /// In the case of a trait object like
1195 /// `<dyn Iterator<Item = ()> as Iterator>::Item` we can use the existential
1196 /// predicate in the trait object.
1197 ///
1198 /// We don't go through the select candidate for these bounds to avoid cycles:
1199 /// In the above case, `dyn Iterator<Item = ()>: Iterator` would create a
1200 /// nested obligation of `<dyn Iterator<Item = ()> as Iterator>::Item: Sized`,
1201 /// this then has to be normalized without having to prove
1202 /// `dyn Iterator<Item = ()>: Iterator` again.
1203 fn assemble_candidates_from_object_ty<'cx, 'tcx>(
1204     selcx: &mut SelectionContext<'cx, 'tcx>,
1205     obligation: &ProjectionTyObligation<'tcx>,
1206     candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
1207 ) {
1208     debug!("assemble_candidates_from_object_ty(..)");
1209
1210     let tcx = selcx.tcx();
1211
1212     let self_ty = obligation.predicate.self_ty();
1213     let object_ty = selcx.infcx().shallow_resolve(self_ty);
1214     let data = match object_ty.kind() {
1215         ty::Dynamic(data, ..) => data,
1216         ty::Infer(ty::TyVar(_)) => {
1217             // If the self-type is an inference variable, then it MAY wind up
1218             // being an object type, so induce an ambiguity.
1219             candidate_set.mark_ambiguous();
1220             return;
1221         }
1222         _ => return,
1223     };
1224     let env_predicates = data
1225         .projection_bounds()
1226         .filter(|bound| bound.item_def_id() == obligation.predicate.item_def_id)
1227         .map(|p| p.with_self_ty(tcx, object_ty).to_predicate(tcx));
1228
1229     assemble_candidates_from_predicates(
1230         selcx,
1231         obligation,
1232         candidate_set,
1233         ProjectionTyCandidate::Object,
1234         env_predicates,
1235         false,
1236     );
1237 }
1238
1239 fn assemble_candidates_from_predicates<'cx, 'tcx>(
1240     selcx: &mut SelectionContext<'cx, 'tcx>,
1241     obligation: &ProjectionTyObligation<'tcx>,
1242     candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
1243     ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionTyCandidate<'tcx>,
1244     env_predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
1245     potentially_unnormalized_candidates: bool,
1246 ) {
1247     debug!(?obligation, "assemble_candidates_from_predicates");
1248
1249     let infcx = selcx.infcx();
1250     for predicate in env_predicates {
1251         debug!(?predicate);
1252         let bound_predicate = predicate.kind();
1253         if let ty::PredicateKind::Projection(data) = predicate.kind().skip_binder() {
1254             let data = bound_predicate.rebind(data);
1255             let same_def_id = data.projection_def_id() == obligation.predicate.item_def_id;
1256
1257             let is_match = same_def_id
1258                 && infcx.probe(|_| {
1259                     selcx.match_projection_projections(
1260                         obligation,
1261                         data,
1262                         potentially_unnormalized_candidates,
1263                     )
1264                 });
1265
1266             debug!(?data, ?is_match, ?same_def_id);
1267
1268             if is_match {
1269                 candidate_set.push_candidate(ctor(data));
1270
1271                 if potentially_unnormalized_candidates
1272                     && !obligation.predicate.has_infer_types_or_consts()
1273                 {
1274                     // HACK: Pick the first trait def candidate for a fully
1275                     // inferred predicate. This is to allow duplicates that
1276                     // differ only in normalization.
1277                     return;
1278                 }
1279             }
1280         }
1281     }
1282 }
1283
1284 fn assemble_candidates_from_impls<'cx, 'tcx>(
1285     selcx: &mut SelectionContext<'cx, 'tcx>,
1286     obligation: &ProjectionTyObligation<'tcx>,
1287     candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
1288 ) {
1289     debug!("assemble_candidates_from_impls");
1290
1291     // If we are resolving `<T as TraitRef<...>>::Item == Type`,
1292     // start out by selecting the predicate `T as TraitRef<...>`:
1293     let poly_trait_ref = obligation.predicate.trait_ref(selcx.tcx()).to_poly_trait_ref();
1294     let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate());
1295     let _ = selcx.infcx().commit_if_ok(|_| {
1296         let impl_source = match selcx.select(&trait_obligation) {
1297             Ok(Some(impl_source)) => impl_source,
1298             Ok(None) => {
1299                 candidate_set.mark_ambiguous();
1300                 return Err(());
1301             }
1302             Err(e) => {
1303                 debug!(error = ?e, "selection error");
1304                 candidate_set.mark_error(e);
1305                 return Err(());
1306             }
1307         };
1308
1309         let eligible = match &impl_source {
1310             super::ImplSource::Closure(_)
1311             | super::ImplSource::Generator(_)
1312             | super::ImplSource::FnPointer(_)
1313             | super::ImplSource::TraitAlias(_) => {
1314                 debug!(?impl_source);
1315                 true
1316             }
1317             super::ImplSource::UserDefined(impl_data) => {
1318                 // We have to be careful when projecting out of an
1319                 // impl because of specialization. If we are not in
1320                 // codegen (i.e., projection mode is not "any"), and the
1321                 // impl's type is declared as default, then we disable
1322                 // projection (even if the trait ref is fully
1323                 // monomorphic). In the case where trait ref is not
1324                 // fully monomorphic (i.e., includes type parameters),
1325                 // this is because those type parameters may
1326                 // ultimately be bound to types from other crates that
1327                 // may have specialized impls we can't see. In the
1328                 // case where the trait ref IS fully monomorphic, this
1329                 // is a policy decision that we made in the RFC in
1330                 // order to preserve flexibility for the crate that
1331                 // defined the specializable impl to specialize later
1332                 // for existing types.
1333                 //
1334                 // In either case, we handle this by not adding a
1335                 // candidate for an impl if it contains a `default`
1336                 // type.
1337                 //
1338                 // NOTE: This should be kept in sync with the similar code in
1339                 // `rustc_ty_utils::instance::resolve_associated_item()`.
1340                 let node_item =
1341                     assoc_ty_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id)
1342                         .map_err(|ErrorReported| ())?;
1343
1344                 if node_item.is_final() {
1345                     // Non-specializable items are always projectable.
1346                     true
1347                 } else {
1348                     // Only reveal a specializable default if we're past type-checking
1349                     // and the obligation is monomorphic, otherwise passes such as
1350                     // transmute checking and polymorphic MIR optimizations could
1351                     // get a result which isn't correct for all monomorphizations.
1352                     if obligation.param_env.reveal() == Reveal::All {
1353                         // NOTE(eddyb) inference variables can resolve to parameters, so
1354                         // assume `poly_trait_ref` isn't monomorphic, if it contains any.
1355                         let poly_trait_ref = selcx.infcx().resolve_vars_if_possible(poly_trait_ref);
1356                         !poly_trait_ref.still_further_specializable()
1357                     } else {
1358                         debug!(
1359                             assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
1360                             ?obligation.predicate,
1361                             "assemble_candidates_from_impls: not eligible due to default",
1362                         );
1363                         false
1364                     }
1365                 }
1366             }
1367             super::ImplSource::DiscriminantKind(..) => {
1368                 // While `DiscriminantKind` is automatically implemented for every type,
1369                 // the concrete discriminant may not be known yet.
1370                 //
1371                 // Any type with multiple potential discriminant types is therefore not eligible.
1372                 let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
1373
1374                 match self_ty.kind() {
1375                     ty::Bool
1376                     | ty::Char
1377                     | ty::Int(_)
1378                     | ty::Uint(_)
1379                     | ty::Float(_)
1380                     | ty::Adt(..)
1381                     | ty::Foreign(_)
1382                     | ty::Str
1383                     | ty::Array(..)
1384                     | ty::Slice(_)
1385                     | ty::RawPtr(..)
1386                     | ty::Ref(..)
1387                     | ty::FnDef(..)
1388                     | ty::FnPtr(..)
1389                     | ty::Dynamic(..)
1390                     | ty::Closure(..)
1391                     | ty::Generator(..)
1392                     | ty::GeneratorWitness(..)
1393                     | ty::Never
1394                     | ty::Tuple(..)
1395                     // Integers and floats always have `u8` as their discriminant.
1396                     | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
1397
1398                     ty::Projection(..)
1399                     | ty::Opaque(..)
1400                     | ty::Param(..)
1401                     | ty::Bound(..)
1402                     | ty::Placeholder(..)
1403                     | ty::Infer(..)
1404                     | ty::Error(_) => false,
1405                 }
1406             }
1407             super::ImplSource::Pointee(..) => {
1408                 // While `Pointee` is automatically implemented for every type,
1409                 // the concrete metadata type may not be known yet.
1410                 //
1411                 // Any type with multiple potential metadata types is therefore not eligible.
1412                 let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
1413
1414                 // FIXME: should this normalize?
1415                 let tail = selcx.tcx().struct_tail_without_normalization(self_ty);
1416                 match tail.kind() {
1417                     ty::Bool
1418                     | ty::Char
1419                     | ty::Int(_)
1420                     | ty::Uint(_)
1421                     | ty::Float(_)
1422                     | ty::Foreign(_)
1423                     | ty::Str
1424                     | ty::Array(..)
1425                     | ty::Slice(_)
1426                     | ty::RawPtr(..)
1427                     | ty::Ref(..)
1428                     | ty::FnDef(..)
1429                     | ty::FnPtr(..)
1430                     | ty::Dynamic(..)
1431                     | ty::Closure(..)
1432                     | ty::Generator(..)
1433                     | ty::GeneratorWitness(..)
1434                     | ty::Never
1435                     // If returned by `struct_tail_without_normalization` this is a unit struct
1436                     // without any fields, or not a struct, and therefore is Sized.
1437                     | ty::Adt(..)
1438                     // If returned by `struct_tail_without_normalization` this is the empty tuple.
1439                     | ty::Tuple(..)
1440                     // Integers and floats are always Sized, and so have unit type metadata.
1441                     | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
1442
1443                     ty::Projection(..)
1444                     | ty::Opaque(..)
1445                     | ty::Param(..)
1446                     | ty::Bound(..)
1447                     | ty::Placeholder(..)
1448                     | ty::Infer(..)
1449                     | ty::Error(_) => false,
1450                 }
1451             }
1452             super::ImplSource::Param(..) => {
1453                 // This case tell us nothing about the value of an
1454                 // associated type. Consider:
1455                 //
1456                 // ```
1457                 // trait SomeTrait { type Foo; }
1458                 // fn foo<T:SomeTrait>(...) { }
1459                 // ```
1460                 //
1461                 // If the user writes `<T as SomeTrait>::Foo`, then the `T
1462                 // : SomeTrait` binding does not help us decide what the
1463                 // type `Foo` is (at least, not more specifically than
1464                 // what we already knew).
1465                 //
1466                 // But wait, you say! What about an example like this:
1467                 //
1468                 // ```
1469                 // fn bar<T:SomeTrait<Foo=usize>>(...) { ... }
1470                 // ```
1471                 //
1472                 // Doesn't the `T : Sometrait<Foo=usize>` predicate help
1473                 // resolve `T::Foo`? And of course it does, but in fact
1474                 // that single predicate is desugared into two predicates
1475                 // in the compiler: a trait predicate (`T : SomeTrait`) and a
1476                 // projection. And the projection where clause is handled
1477                 // in `assemble_candidates_from_param_env`.
1478                 false
1479             }
1480             super::ImplSource::Object(_) => {
1481                 // Handled by the `Object` projection candidate. See
1482                 // `assemble_candidates_from_object_ty` for an explanation of
1483                 // why we special case object types.
1484                 false
1485             }
1486             super::ImplSource::AutoImpl(..) | super::ImplSource::Builtin(..) => {
1487                 // These traits have no associated types.
1488                 selcx.tcx().sess.delay_span_bug(
1489                     obligation.cause.span,
1490                     &format!("Cannot project an associated type from `{:?}`", impl_source),
1491                 );
1492                 return Err(());
1493             }
1494         };
1495
1496         if eligible {
1497             if candidate_set.push_candidate(ProjectionTyCandidate::Select(impl_source)) {
1498                 Ok(())
1499             } else {
1500                 Err(())
1501             }
1502         } else {
1503             Err(())
1504         }
1505     });
1506 }
1507
1508 fn confirm_candidate<'cx, 'tcx>(
1509     selcx: &mut SelectionContext<'cx, 'tcx>,
1510     obligation: &ProjectionTyObligation<'tcx>,
1511     candidate: ProjectionTyCandidate<'tcx>,
1512 ) -> Progress<'tcx> {
1513     debug!(?obligation, ?candidate, "confirm_candidate");
1514     let mut progress = match candidate {
1515         ProjectionTyCandidate::ParamEnv(poly_projection)
1516         | ProjectionTyCandidate::Object(poly_projection) => {
1517             confirm_param_env_candidate(selcx, obligation, poly_projection, false)
1518         }
1519
1520         ProjectionTyCandidate::TraitDef(poly_projection) => {
1521             confirm_param_env_candidate(selcx, obligation, poly_projection, true)
1522         }
1523
1524         ProjectionTyCandidate::Select(impl_source) => {
1525             confirm_select_candidate(selcx, obligation, impl_source)
1526         }
1527     };
1528     // When checking for cycle during evaluation, we compare predicates with
1529     // "syntactic" equality. Since normalization generally introduces a type
1530     // with new region variables, we need to resolve them to existing variables
1531     // when possible for this to work. See `auto-trait-projection-recursion.rs`
1532     // for a case where this matters.
1533     if progress.ty.has_infer_regions() {
1534         progress.ty = OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty);
1535     }
1536     progress
1537 }
1538
1539 fn confirm_select_candidate<'cx, 'tcx>(
1540     selcx: &mut SelectionContext<'cx, 'tcx>,
1541     obligation: &ProjectionTyObligation<'tcx>,
1542     impl_source: Selection<'tcx>,
1543 ) -> Progress<'tcx> {
1544     match impl_source {
1545         super::ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
1546         super::ImplSource::Generator(data) => confirm_generator_candidate(selcx, obligation, data),
1547         super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data),
1548         super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
1549         super::ImplSource::DiscriminantKind(data) => {
1550             confirm_discriminant_kind_candidate(selcx, obligation, data)
1551         }
1552         super::ImplSource::Pointee(data) => confirm_pointee_candidate(selcx, obligation, data),
1553         super::ImplSource::Object(_)
1554         | super::ImplSource::AutoImpl(..)
1555         | super::ImplSource::Param(..)
1556         | super::ImplSource::Builtin(..)
1557         | super::ImplSource::TraitAlias(..) => {
1558             // we don't create Select candidates with this kind of resolution
1559             span_bug!(
1560                 obligation.cause.span,
1561                 "Cannot project an associated type from `{:?}`",
1562                 impl_source
1563             )
1564         }
1565     }
1566 }
1567
1568 fn confirm_generator_candidate<'cx, 'tcx>(
1569     selcx: &mut SelectionContext<'cx, 'tcx>,
1570     obligation: &ProjectionTyObligation<'tcx>,
1571     impl_source: ImplSourceGeneratorData<'tcx, PredicateObligation<'tcx>>,
1572 ) -> Progress<'tcx> {
1573     let gen_sig = impl_source.substs.as_generator().poly_sig();
1574     let Normalized { value: gen_sig, obligations } = normalize_with_depth(
1575         selcx,
1576         obligation.param_env,
1577         obligation.cause.clone(),
1578         obligation.recursion_depth + 1,
1579         gen_sig,
1580     );
1581
1582     debug!(?obligation, ?gen_sig, ?obligations, "confirm_generator_candidate");
1583
1584     let tcx = selcx.tcx();
1585
1586     let gen_def_id = tcx.require_lang_item(LangItem::Generator, None);
1587
1588     let predicate = super::util::generator_trait_ref_and_outputs(
1589         tcx,
1590         gen_def_id,
1591         obligation.predicate.self_ty(),
1592         gen_sig,
1593     )
1594     .map_bound(|(trait_ref, yield_ty, return_ty)| {
1595         let name = tcx.associated_item(obligation.predicate.item_def_id).ident.name;
1596         let ty = if name == sym::Return {
1597             return_ty
1598         } else if name == sym::Yield {
1599             yield_ty
1600         } else {
1601             bug!()
1602         };
1603
1604         ty::ProjectionPredicate {
1605             projection_ty: ty::ProjectionTy {
1606                 substs: trait_ref.substs,
1607                 item_def_id: obligation.predicate.item_def_id,
1608             },
1609             ty,
1610         }
1611     });
1612
1613     confirm_param_env_candidate(selcx, obligation, predicate, false)
1614         .with_addl_obligations(impl_source.nested)
1615         .with_addl_obligations(obligations)
1616 }
1617
1618 fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
1619     selcx: &mut SelectionContext<'cx, 'tcx>,
1620     obligation: &ProjectionTyObligation<'tcx>,
1621     _: ImplSourceDiscriminantKindData,
1622 ) -> Progress<'tcx> {
1623     let tcx = selcx.tcx();
1624
1625     let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
1626     // We get here from `poly_project_and_unify_type` which replaces bound vars
1627     // with placeholders
1628     debug_assert!(!self_ty.has_escaping_bound_vars());
1629     let substs = tcx.mk_substs([self_ty.into()].iter());
1630
1631     let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
1632
1633     let predicate = ty::ProjectionPredicate {
1634         projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id },
1635         ty: self_ty.discriminant_ty(tcx),
1636     };
1637
1638     // We get here from `poly_project_and_unify_type` which replaces bound vars
1639     // with placeholders, so dummy is okay here.
1640     confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
1641 }
1642
1643 fn confirm_pointee_candidate<'cx, 'tcx>(
1644     selcx: &mut SelectionContext<'cx, 'tcx>,
1645     obligation: &ProjectionTyObligation<'tcx>,
1646     _: ImplSourcePointeeData,
1647 ) -> Progress<'tcx> {
1648     let tcx = selcx.tcx();
1649
1650     let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
1651     let substs = tcx.mk_substs([self_ty.into()].iter());
1652
1653     let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
1654
1655     let predicate = ty::ProjectionPredicate {
1656         projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id },
1657         ty: self_ty.ptr_metadata_ty(tcx),
1658     };
1659
1660     confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
1661 }
1662
1663 fn confirm_fn_pointer_candidate<'cx, 'tcx>(
1664     selcx: &mut SelectionContext<'cx, 'tcx>,
1665     obligation: &ProjectionTyObligation<'tcx>,
1666     fn_pointer_impl_source: ImplSourceFnPointerData<'tcx, PredicateObligation<'tcx>>,
1667 ) -> Progress<'tcx> {
1668     let fn_type = selcx.infcx().shallow_resolve(fn_pointer_impl_source.fn_ty);
1669     let sig = fn_type.fn_sig(selcx.tcx());
1670     let Normalized { value: sig, obligations } = normalize_with_depth(
1671         selcx,
1672         obligation.param_env,
1673         obligation.cause.clone(),
1674         obligation.recursion_depth + 1,
1675         sig,
1676     );
1677
1678     confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
1679         .with_addl_obligations(fn_pointer_impl_source.nested)
1680         .with_addl_obligations(obligations)
1681 }
1682
1683 fn confirm_closure_candidate<'cx, 'tcx>(
1684     selcx: &mut SelectionContext<'cx, 'tcx>,
1685     obligation: &ProjectionTyObligation<'tcx>,
1686     impl_source: ImplSourceClosureData<'tcx, PredicateObligation<'tcx>>,
1687 ) -> Progress<'tcx> {
1688     let closure_sig = impl_source.substs.as_closure().sig();
1689     let Normalized { value: closure_sig, obligations } = normalize_with_depth(
1690         selcx,
1691         obligation.param_env,
1692         obligation.cause.clone(),
1693         obligation.recursion_depth + 1,
1694         closure_sig,
1695     );
1696
1697     debug!(?obligation, ?closure_sig, ?obligations, "confirm_closure_candidate");
1698
1699     confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No)
1700         .with_addl_obligations(impl_source.nested)
1701         .with_addl_obligations(obligations)
1702 }
1703
1704 fn confirm_callable_candidate<'cx, 'tcx>(
1705     selcx: &mut SelectionContext<'cx, 'tcx>,
1706     obligation: &ProjectionTyObligation<'tcx>,
1707     fn_sig: ty::PolyFnSig<'tcx>,
1708     flag: util::TupleArgumentsFlag,
1709 ) -> Progress<'tcx> {
1710     let tcx = selcx.tcx();
1711
1712     debug!(?obligation, ?fn_sig, "confirm_callable_candidate");
1713
1714     let fn_once_def_id = tcx.require_lang_item(LangItem::FnOnce, None);
1715     let fn_once_output_def_id = tcx.require_lang_item(LangItem::FnOnceOutput, None);
1716
1717     let predicate = super::util::closure_trait_ref_and_return_type(
1718         tcx,
1719         fn_once_def_id,
1720         obligation.predicate.self_ty(),
1721         fn_sig,
1722         flag,
1723     )
1724     .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
1725         projection_ty: ty::ProjectionTy {
1726             substs: trait_ref.substs,
1727             item_def_id: fn_once_output_def_id,
1728         },
1729         ty: ret_type,
1730     });
1731
1732     confirm_param_env_candidate(selcx, obligation, predicate, false)
1733 }
1734
1735 fn confirm_param_env_candidate<'cx, 'tcx>(
1736     selcx: &mut SelectionContext<'cx, 'tcx>,
1737     obligation: &ProjectionTyObligation<'tcx>,
1738     poly_cache_entry: ty::PolyProjectionPredicate<'tcx>,
1739     potentially_unnormalized_candidate: bool,
1740 ) -> Progress<'tcx> {
1741     let infcx = selcx.infcx();
1742     let cause = &obligation.cause;
1743     let param_env = obligation.param_env;
1744
1745     let (cache_entry, _) = infcx.replace_bound_vars_with_fresh_vars(
1746         cause.span,
1747         LateBoundRegionConversionTime::HigherRankedType,
1748         poly_cache_entry,
1749     );
1750
1751     let cache_projection = cache_entry.projection_ty;
1752     let obligation_projection = obligation.predicate;
1753     let mut nested_obligations = Vec::new();
1754     let cache_projection = if potentially_unnormalized_candidate {
1755         ensure_sufficient_stack(|| {
1756             normalize_with_depth_to(
1757                 selcx,
1758                 obligation.param_env,
1759                 obligation.cause.clone(),
1760                 obligation.recursion_depth + 1,
1761                 cache_projection,
1762                 &mut nested_obligations,
1763             )
1764         })
1765     } else {
1766         cache_projection
1767     };
1768
1769     match infcx.at(cause, param_env).eq(cache_projection, obligation_projection) {
1770         Ok(InferOk { value: _, obligations }) => {
1771             nested_obligations.extend(obligations);
1772             assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations);
1773             Progress { ty: cache_entry.ty, obligations: nested_obligations }
1774         }
1775         Err(e) => {
1776             let msg = format!(
1777                 "Failed to unify obligation `{:?}` with poly_projection `{:?}`: {:?}",
1778                 obligation, poly_cache_entry, e,
1779             );
1780             debug!("confirm_param_env_candidate: {}", msg);
1781             let err = infcx.tcx.ty_error_with_message(obligation.cause.span, &msg);
1782             Progress { ty: err, obligations: vec![] }
1783         }
1784     }
1785 }
1786
1787 fn confirm_impl_candidate<'cx, 'tcx>(
1788     selcx: &mut SelectionContext<'cx, 'tcx>,
1789     obligation: &ProjectionTyObligation<'tcx>,
1790     impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
1791 ) -> Progress<'tcx> {
1792     let tcx = selcx.tcx();
1793
1794     let ImplSourceUserDefinedData { impl_def_id, substs, mut nested } = impl_impl_source;
1795     let assoc_item_id = obligation.predicate.item_def_id;
1796     let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
1797
1798     let param_env = obligation.param_env;
1799     let assoc_ty = match assoc_ty_def(selcx, impl_def_id, assoc_item_id) {
1800         Ok(assoc_ty) => assoc_ty,
1801         Err(ErrorReported) => return Progress { ty: tcx.ty_error(), obligations: nested },
1802     };
1803
1804     if !assoc_ty.item.defaultness.has_value() {
1805         // This means that the impl is missing a definition for the
1806         // associated type. This error will be reported by the type
1807         // checker method `check_impl_items_against_trait`, so here we
1808         // just return Error.
1809         debug!(
1810             "confirm_impl_candidate: no associated type {:?} for {:?}",
1811             assoc_ty.item.ident, obligation.predicate
1812         );
1813         return Progress { ty: tcx.ty_error(), obligations: nested };
1814     }
1815     // If we're trying to normalize `<Vec<u32> as X>::A<S>` using
1816     //`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then:
1817     //
1818     // * `obligation.predicate.substs` is `[Vec<u32>, S]`
1819     // * `substs` is `[u32]`
1820     // * `substs` ends up as `[u32, S]`
1821     let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs);
1822     let substs =
1823         translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node);
1824     let ty = tcx.type_of(assoc_ty.item.def_id);
1825     if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() {
1826         let err = tcx.ty_error_with_message(
1827             obligation.cause.span,
1828             "impl item and trait item have different parameter counts",
1829         );
1830         Progress { ty: err, obligations: nested }
1831     } else {
1832         assoc_ty_own_obligations(selcx, obligation, &mut nested);
1833         Progress { ty: ty.subst(tcx, substs), obligations: nested }
1834     }
1835 }
1836
1837 // Get obligations corresponding to the predicates from the where-clause of the
1838 // associated type itself.
1839 // Note: `feature(generic_associated_types)` is required to write such
1840 // predicates, even for non-generic associcated types.
1841 fn assoc_ty_own_obligations<'cx, 'tcx>(
1842     selcx: &mut SelectionContext<'cx, 'tcx>,
1843     obligation: &ProjectionTyObligation<'tcx>,
1844     nested: &mut Vec<PredicateObligation<'tcx>>,
1845 ) {
1846     let tcx = selcx.tcx();
1847     for predicate in tcx
1848         .predicates_of(obligation.predicate.item_def_id)
1849         .instantiate_own(tcx, obligation.predicate.substs)
1850         .predicates
1851     {
1852         let normalized = normalize_with_depth_to(
1853             selcx,
1854             obligation.param_env,
1855             obligation.cause.clone(),
1856             obligation.recursion_depth + 1,
1857             predicate,
1858             nested,
1859         );
1860         nested.push(Obligation::with_depth(
1861             obligation.cause.clone(),
1862             obligation.recursion_depth + 1,
1863             obligation.param_env,
1864             normalized,
1865         ));
1866     }
1867 }
1868
1869 /// Locate the definition of an associated type in the specialization hierarchy,
1870 /// starting from the given impl.
1871 ///
1872 /// Based on the "projection mode", this lookup may in fact only examine the
1873 /// topmost impl. See the comments for `Reveal` for more details.
1874 fn assoc_ty_def(
1875     selcx: &SelectionContext<'_, '_>,
1876     impl_def_id: DefId,
1877     assoc_ty_def_id: DefId,
1878 ) -> Result<specialization_graph::LeafDef, ErrorReported> {
1879     let tcx = selcx.tcx();
1880     let assoc_ty_name = tcx.associated_item(assoc_ty_def_id).ident;
1881     let trait_def_id = tcx.impl_trait_ref(impl_def_id).unwrap().def_id;
1882     let trait_def = tcx.trait_def(trait_def_id);
1883
1884     // This function may be called while we are still building the
1885     // specialization graph that is queried below (via TraitDef::ancestors()),
1886     // so, in order to avoid unnecessary infinite recursion, we manually look
1887     // for the associated item at the given impl.
1888     // If there is no such item in that impl, this function will fail with a
1889     // cycle error if the specialization graph is currently being built.
1890     let impl_node = specialization_graph::Node::Impl(impl_def_id);
1891     for item in impl_node.items(tcx) {
1892         if matches!(item.kind, ty::AssocKind::Type)
1893             && tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id)
1894         {
1895             return Ok(specialization_graph::LeafDef {
1896                 item: *item,
1897                 defining_node: impl_node,
1898                 finalizing_node: if item.defaultness.is_default() { None } else { Some(impl_node) },
1899             });
1900         }
1901     }
1902
1903     let ancestors = trait_def.ancestors(tcx, impl_def_id)?;
1904     if let Some(assoc_item) = ancestors.leaf_def(tcx, assoc_ty_name, ty::AssocKind::Type) {
1905         Ok(assoc_item)
1906     } else {
1907         // This is saying that neither the trait nor
1908         // the impl contain a definition for this
1909         // associated type.  Normally this situation
1910         // could only arise through a compiler bug --
1911         // if the user wrote a bad item name, it
1912         // should have failed in astconv.
1913         bug!("No associated type `{}` for {}", assoc_ty_name, tcx.def_path_str(impl_def_id))
1914     }
1915 }
1916
1917 crate trait ProjectionCacheKeyExt<'tcx>: Sized {
1918     fn from_poly_projection_predicate(
1919         selcx: &mut SelectionContext<'cx, 'tcx>,
1920         predicate: ty::PolyProjectionPredicate<'tcx>,
1921     ) -> Option<Self>;
1922 }
1923
1924 impl<'tcx> ProjectionCacheKeyExt<'tcx> for ProjectionCacheKey<'tcx> {
1925     fn from_poly_projection_predicate(
1926         selcx: &mut SelectionContext<'cx, 'tcx>,
1927         predicate: ty::PolyProjectionPredicate<'tcx>,
1928     ) -> Option<Self> {
1929         let infcx = selcx.infcx();
1930         // We don't do cross-snapshot caching of obligations with escaping regions,
1931         // so there's no cache key to use
1932         predicate.no_bound_vars().map(|predicate| {
1933             ProjectionCacheKey::new(
1934                 // We don't attempt to match up with a specific type-variable state
1935                 // from a specific call to `opt_normalize_projection_type` - if
1936                 // there's no precise match, the original cache entry is "stranded"
1937                 // anyway.
1938                 infcx.resolve_vars_if_possible(predicate.projection_ty),
1939             )
1940         })
1941     }
1942 }