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