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