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