]> git.lizzy.rs Git - rust.git/blob - src/librustc/infer/nll_relate/mod.rs
4649f3f9567e78fb4e3eddcf48eadd3a33c2706f
[rust.git] / src / librustc / infer / nll_relate / mod.rs
1 //! This code is kind of an alternate way of doing subtyping,
2 //! supertyping, and type equating, distinct from the `combine.rs`
3 //! code but very similar in its effect and design. Eventually the two
4 //! ought to be merged. This code is intended for use in NLL and chalk.
5 //!
6 //! Here are the key differences:
7 //!
8 //! - This code may choose to bypass some checks (e.g., the occurs check)
9 //!   in the case where we know that there are no unbound type inference
10 //!   variables. This is the case for NLL, because at NLL time types are fully
11 //!   inferred up-to regions.
12 //! - This code uses "universes" to handle higher-ranked regions and
13 //!   not the leak-check. This is "more correct" than what rustc does
14 //!   and we are generally migrating in this direction, but NLL had to
15 //!   get there first.
16 //!
17 //! Also, this code assumes that there are no bound types at all, not even
18 //! free ones. This is ok because:
19 //! - we are not relating anything quantified over some type variable
20 //! - we will have instantiated all the bound type vars already (the one
21 //!   thing we relate in chalk are basically domain goals and their
22 //!   constituents)
23
24 use crate::infer::InferCtxt;
25 use crate::traits::DomainGoal;
26 use crate::ty::error::TypeError;
27 use crate::ty::fold::{TypeFoldable, TypeVisitor};
28 use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
29 use crate::ty::subst::GenericArg;
30 use crate::ty::{self, Ty, TyCtxt, InferConst};
31 use crate::mir::interpret::ConstValue;
32 use rustc_data_structures::fx::FxHashMap;
33 use std::fmt::Debug;
34
35 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
36 pub enum NormalizationStrategy {
37     Lazy,
38     Eager,
39 }
40
41 pub struct TypeRelating<'me, 'tcx, D>
42 where
43     D: TypeRelatingDelegate<'tcx>,
44 {
45     infcx: &'me InferCtxt<'me, 'tcx>,
46
47     /// Callback to use when we deduce an outlives relationship
48     delegate: D,
49
50     /// How are we relating `a` and `b`?
51     ///
52     /// - Covariant means `a <: b`.
53     /// - Contravariant means `b <: a`.
54     /// - Invariant means `a == b.
55     /// - Bivariant means that it doesn't matter.
56     ambient_variance: ty::Variance,
57
58     /// When we pass through a set of binders (e.g., when looking into
59     /// a `fn` type), we push a new bound region scope onto here. This
60     /// will contain the instantiated region for each region in those
61     /// binders. When we then encounter a `ReLateBound(d, br)`, we can
62     /// use the De Bruijn index `d` to find the right scope, and then
63     /// bound region name `br` to find the specific instantiation from
64     /// within that scope. See `replace_bound_region`.
65     ///
66     /// This field stores the instantiations for late-bound regions in
67     /// the `a` type.
68     a_scopes: Vec<BoundRegionScope<'tcx>>,
69
70     /// Same as `a_scopes`, but for the `b` type.
71     b_scopes: Vec<BoundRegionScope<'tcx>>,
72 }
73
74 pub trait TypeRelatingDelegate<'tcx> {
75     /// Push a constraint `sup: sub` -- this constraint must be
76     /// satisfied for the two types to be related. `sub` and `sup` may
77     /// be regions from the type or new variables created through the
78     /// delegate.
79     fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>);
80
81     /// Push a domain goal that will need to be proved for the two types to
82     /// be related. Used for lazy normalization.
83     fn push_domain_goal(&mut self, domain_goal: DomainGoal<'tcx>);
84
85     /// Creates a new universe index. Used when instantiating placeholders.
86     fn create_next_universe(&mut self) -> ty::UniverseIndex;
87
88     /// Creates a new region variable representing a higher-ranked
89     /// region that is instantiated existentially. This creates an
90     /// inference variable, typically.
91     ///
92     /// So e.g., if you have `for<'a> fn(..) <: for<'b> fn(..)`, then
93     /// we will invoke this method to instantiate `'a` with an
94     /// inference variable (though `'b` would be instantiated first,
95     /// as a placeholder).
96     fn next_existential_region_var(&mut self, was_placeholder: bool) -> ty::Region<'tcx>;
97
98     /// Creates a new region variable representing a
99     /// higher-ranked region that is instantiated universally.
100     /// This creates a new region placeholder, typically.
101     ///
102     /// So e.g., if you have `for<'a> fn(..) <: for<'b> fn(..)`, then
103     /// we will invoke this method to instantiate `'b` with a
104     /// placeholder region.
105     fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx>;
106
107     /// Creates a new existential region in the given universe. This
108     /// is used when handling subtyping and type variables -- if we
109     /// have that `?X <: Foo<'a>`, for example, we would instantiate
110     /// `?X` with a type like `Foo<'?0>` where `'?0` is a fresh
111     /// existential variable created by this function. We would then
112     /// relate `Foo<'?0>` with `Foo<'a>` (and probably add an outlives
113     /// relation stating that `'?0: 'a`).
114     fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>;
115
116     /// Define the normalization strategy to use, eager or lazy.
117     fn normalization() -> NormalizationStrategy;
118
119     /// Enables some optimizations if we do not expect inference variables
120     /// in the RHS of the relation.
121     fn forbid_inference_vars() -> bool;
122 }
123
124 #[derive(Clone, Debug)]
125 struct ScopesAndKind<'tcx> {
126     scopes: Vec<BoundRegionScope<'tcx>>,
127     kind: GenericArg<'tcx>,
128 }
129
130 #[derive(Clone, Debug, Default)]
131 struct BoundRegionScope<'tcx> {
132     map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
133 }
134
135 #[derive(Copy, Clone)]
136 struct UniversallyQuantified(bool);
137
138 impl<'me, 'tcx, D> TypeRelating<'me, 'tcx, D>
139 where
140     D: TypeRelatingDelegate<'tcx>,
141 {
142     pub fn new(
143         infcx: &'me InferCtxt<'me, 'tcx>,
144         delegate: D,
145         ambient_variance: ty::Variance,
146     ) -> Self {
147         Self {
148             infcx,
149             delegate,
150             ambient_variance,
151             a_scopes: vec![],
152             b_scopes: vec![],
153         }
154     }
155
156     fn ambient_covariance(&self) -> bool {
157         match self.ambient_variance {
158             ty::Variance::Covariant | ty::Variance::Invariant => true,
159             ty::Variance::Contravariant | ty::Variance::Bivariant => false,
160         }
161     }
162
163     fn ambient_contravariance(&self) -> bool {
164         match self.ambient_variance {
165             ty::Variance::Contravariant | ty::Variance::Invariant => true,
166             ty::Variance::Covariant | ty::Variance::Bivariant => false,
167         }
168     }
169
170     fn create_scope(
171         &mut self,
172         value: &ty::Binder<impl TypeFoldable<'tcx>>,
173         universally_quantified: UniversallyQuantified,
174     ) -> BoundRegionScope<'tcx> {
175         let mut scope = BoundRegionScope::default();
176
177         // Create a callback that creates (via the delegate) either an
178         // existential or placeholder region as needed.
179         let mut next_region = {
180             let delegate = &mut self.delegate;
181             let mut lazy_universe = None;
182             move |br: ty::BoundRegion| {
183                 if universally_quantified.0 {
184                     // The first time this closure is called, create a
185                     // new universe for the placeholders we will make
186                     // from here out.
187                     let universe = lazy_universe.unwrap_or_else(|| {
188                         let universe = delegate.create_next_universe();
189                         lazy_universe = Some(universe);
190                         universe
191                     });
192
193                     let placeholder = ty::PlaceholderRegion { universe, name: br };
194                     delegate.next_placeholder_region(placeholder)
195                 } else {
196                     delegate.next_existential_region_var(true)
197                 }
198             }
199         };
200
201         value.skip_binder().visit_with(&mut ScopeInstantiator {
202             next_region: &mut next_region,
203             target_index: ty::INNERMOST,
204             bound_region_scope: &mut scope,
205         });
206
207         scope
208     }
209
210     /// When we encounter binders during the type traversal, we record
211     /// the value to substitute for each of the things contained in
212     /// that binder. (This will be either a universal placeholder or
213     /// an existential inference variable.) Given the De Bruijn index
214     /// `debruijn` (and name `br`) of some binder we have now
215     /// encountered, this routine finds the value that we instantiated
216     /// the region with; to do so, it indexes backwards into the list
217     /// of ambient scopes `scopes`.
218     fn lookup_bound_region(
219         debruijn: ty::DebruijnIndex,
220         br: &ty::BoundRegion,
221         first_free_index: ty::DebruijnIndex,
222         scopes: &[BoundRegionScope<'tcx>],
223     ) -> ty::Region<'tcx> {
224         // The debruijn index is a "reverse index" into the
225         // scopes listing. So when we have INNERMOST (0), we
226         // want the *last* scope pushed, and so forth.
227         let debruijn_index = debruijn.index() - first_free_index.index();
228         let scope = &scopes[scopes.len() - debruijn_index - 1];
229
230         // Find this bound region in that scope to map to a
231         // particular region.
232         scope.map[br]
233     }
234
235     /// If `r` is a bound region, find the scope in which it is bound
236     /// (from `scopes`) and return the value that we instantiated it
237     /// with. Otherwise just return `r`.
238     fn replace_bound_region(
239         &self,
240         r: ty::Region<'tcx>,
241         first_free_index: ty::DebruijnIndex,
242         scopes: &[BoundRegionScope<'tcx>],
243     ) -> ty::Region<'tcx> {
244         debug!("replace_bound_regions(scopes={:?})", scopes);
245         if let ty::ReLateBound(debruijn, br) = r {
246             Self::lookup_bound_region(*debruijn, br, first_free_index, scopes)
247         } else {
248             r
249         }
250     }
251
252     /// Push a new outlives requirement into our output set of
253     /// constraints.
254     fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
255         debug!("push_outlives({:?}: {:?})", sup, sub);
256
257         self.delegate.push_outlives(sup, sub);
258     }
259
260     /// Relate a projection type and some value type lazily. This will always
261     /// succeed, but we push an additional `ProjectionEq` goal depending
262     /// on the value type:
263     /// - if the value type is any type `T` which is not a projection, we push
264     ///   `ProjectionEq(projection = T)`.
265     /// - if the value type is another projection `other_projection`, we create
266     ///   a new inference variable `?U` and push the two goals
267     ///   `ProjectionEq(projection = ?U)`, `ProjectionEq(other_projection = ?U)`.
268     fn relate_projection_ty(
269         &mut self,
270         projection_ty: ty::ProjectionTy<'tcx>,
271         value_ty: Ty<'tcx>,
272     ) -> Ty<'tcx> {
273         use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
274         use crate::traits::WhereClause;
275         use syntax_pos::DUMMY_SP;
276
277         match value_ty.kind {
278             ty::Projection(other_projection_ty) => {
279                 let var = self.infcx.next_ty_var(TypeVariableOrigin {
280                     kind: TypeVariableOriginKind::MiscVariable,
281                     span: DUMMY_SP,
282                 });
283                 self.relate_projection_ty(projection_ty, var);
284                 self.relate_projection_ty(other_projection_ty, var);
285                 var
286             }
287
288             _ => {
289                 let projection = ty::ProjectionPredicate {
290                     projection_ty,
291                     ty: value_ty,
292                 };
293                 self.delegate
294                     .push_domain_goal(DomainGoal::Holds(WhereClause::ProjectionEq(projection)));
295                 value_ty
296             }
297         }
298     }
299
300     /// Relate a type inference variable with a value type. This works
301     /// by creating a "generalization" G of the value where all the
302     /// lifetimes are replaced with fresh inference values. This
303     /// genearlization G becomes the value of the inference variable,
304     /// and is then related in turn to the value. So e.g. if you had
305     /// `vid = ?0` and `value = &'a u32`, we might first instantiate
306     /// `?0` to a type like `&'0 u32` where `'0` is a fresh variable,
307     /// and then relate `&'0 u32` with `&'a u32` (resulting in
308     /// relations between `'0` and `'a`).
309     ///
310     /// The variable `pair` can be either a `(vid, ty)` or `(ty, vid)`
311     /// -- in other words, it is always a (unresolved) inference
312     /// variable `vid` and a type `ty` that are being related, but the
313     /// vid may appear either as the "a" type or the "b" type,
314     /// depending on where it appears in the tuple. The trait
315     /// `VidValuePair` lets us work with the vid/type while preserving
316     /// the "sidedness" when necessary -- the sidedness is relevant in
317     /// particular for the variance and set of in-scope things.
318     fn relate_ty_var<PAIR: VidValuePair<'tcx>>(
319         &mut self,
320         pair: PAIR,
321     ) -> RelateResult<'tcx, Ty<'tcx>> {
322         debug!("relate_ty_var({:?})", pair);
323
324         let vid = pair.vid();
325         let value_ty = pair.value_ty();
326
327         // FIXME -- this logic assumes invariance, but that is wrong.
328         // This only presently applies to chalk integration, as NLL
329         // doesn't permit type variables to appear on both sides (and
330         // doesn't use lazy norm).
331         match value_ty.kind {
332             ty::Infer(ty::TyVar(value_vid)) => {
333                 // Two type variables: just equate them.
334                 self.infcx
335                     .type_variables
336                     .borrow_mut()
337                     .equate(vid, value_vid);
338                 return Ok(value_ty);
339             }
340
341             ty::Projection(projection_ty) if D::normalization() == NormalizationStrategy::Lazy => {
342                 return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_ty_var(vid)));
343             }
344
345             _ => (),
346         }
347
348         let generalized_ty = self.generalize_value(value_ty, vid)?;
349         debug!("relate_ty_var: generalized_ty = {:?}", generalized_ty);
350
351         if D::forbid_inference_vars() {
352             // In NLL, we don't have type inference variables
353             // floating around, so we can do this rather imprecise
354             // variant of the occurs-check.
355             assert!(!generalized_ty.has_infer_types());
356         }
357
358         self.infcx
359             .type_variables
360             .borrow_mut()
361             .instantiate(vid, generalized_ty);
362
363         // The generalized values we extract from `canonical_var_values` have
364         // been fully instantiated and hence the set of scopes we have
365         // doesn't matter -- just to be sure, put an empty vector
366         // in there.
367         let old_a_scopes = ::std::mem::take(pair.vid_scopes(self));
368
369         // Relate the generalized kind to the original one.
370         let result = pair.relate_generalized_ty(self, generalized_ty);
371
372         // Restore the old scopes now.
373         *pair.vid_scopes(self) = old_a_scopes;
374
375         debug!("relate_ty_var: complete, result = {:?}", result);
376         result
377     }
378
379     fn generalize_value<T: Relate<'tcx>>(
380         &mut self,
381         value: T,
382         for_vid: ty::TyVid,
383     ) -> RelateResult<'tcx, T> {
384         let universe = self.infcx.probe_ty_var(for_vid).unwrap_err();
385
386         let mut generalizer = TypeGeneralizer {
387             infcx: self.infcx,
388             delegate: &mut self.delegate,
389             first_free_index: ty::INNERMOST,
390             ambient_variance: self.ambient_variance,
391             for_vid_sub_root: self.infcx.type_variables.borrow_mut().sub_root_var(for_vid),
392             universe,
393         };
394
395         generalizer.relate(&value, &value)
396     }
397 }
398
399 /// When we instantiate a inference variable with a value in
400 /// `relate_ty_var`, we always have the pair of a `TyVid` and a `Ty`,
401 /// but the ordering may vary (depending on whether the inference
402 /// variable was found on the `a` or `b` sides). Therefore, this trait
403 /// allows us to factor out common code, while preserving the order
404 /// when needed.
405 trait VidValuePair<'tcx>: Debug {
406     /// Extract the inference variable (which could be either the
407     /// first or second part of the tuple).
408     fn vid(&self) -> ty::TyVid;
409
410     /// Extract the value it is being related to (which will be the
411     /// opposite part of the tuple from the vid).
412     fn value_ty(&self) -> Ty<'tcx>;
413
414     /// Extract the scopes that apply to whichever side of the tuple
415     /// the vid was found on.  See the comment where this is called
416     /// for more details on why we want them.
417     fn vid_scopes<D: TypeRelatingDelegate<'tcx>>(
418         &self,
419         relate: &'r mut TypeRelating<'_, 'tcx, D>,
420     ) -> &'r mut Vec<BoundRegionScope<'tcx>>;
421
422     /// Given a generalized type G that should replace the vid, relate
423     /// G to the value, putting G on whichever side the vid would have
424     /// appeared.
425     fn relate_generalized_ty<D>(
426         &self,
427         relate: &mut TypeRelating<'_, 'tcx, D>,
428         generalized_ty: Ty<'tcx>,
429     ) -> RelateResult<'tcx, Ty<'tcx>>
430     where
431         D: TypeRelatingDelegate<'tcx>;
432 }
433
434 impl VidValuePair<'tcx> for (ty::TyVid, Ty<'tcx>) {
435     fn vid(&self) -> ty::TyVid {
436         self.0
437     }
438
439     fn value_ty(&self) -> Ty<'tcx> {
440         self.1
441     }
442
443     fn vid_scopes<D>(
444         &self,
445         relate: &'r mut TypeRelating<'_, 'tcx, D>,
446     ) -> &'r mut Vec<BoundRegionScope<'tcx>>
447     where
448         D: TypeRelatingDelegate<'tcx>,
449     {
450         &mut relate.a_scopes
451     }
452
453     fn relate_generalized_ty<D>(
454         &self,
455         relate: &mut TypeRelating<'_, 'tcx, D>,
456         generalized_ty: Ty<'tcx>,
457     ) -> RelateResult<'tcx, Ty<'tcx>>
458     where
459         D: TypeRelatingDelegate<'tcx>,
460     {
461         relate.relate(&generalized_ty, &self.value_ty())
462     }
463 }
464
465 // In this case, the "vid" is the "b" type.
466 impl VidValuePair<'tcx> for (Ty<'tcx>, ty::TyVid) {
467     fn vid(&self) -> ty::TyVid {
468         self.1
469     }
470
471     fn value_ty(&self) -> Ty<'tcx> {
472         self.0
473     }
474
475     fn vid_scopes<D>(
476         &self,
477         relate: &'r mut TypeRelating<'_, 'tcx, D>,
478     ) -> &'r mut Vec<BoundRegionScope<'tcx>>
479     where
480         D: TypeRelatingDelegate<'tcx>,
481     {
482         &mut relate.b_scopes
483     }
484
485     fn relate_generalized_ty<D>(
486         &self,
487         relate: &mut TypeRelating<'_, 'tcx, D>,
488         generalized_ty: Ty<'tcx>,
489     ) -> RelateResult<'tcx, Ty<'tcx>>
490     where
491         D: TypeRelatingDelegate<'tcx>,
492     {
493         relate.relate(&self.value_ty(), &generalized_ty)
494     }
495 }
496
497 impl<D> TypeRelation<'tcx> for TypeRelating<'me, 'tcx, D>
498 where
499     D: TypeRelatingDelegate<'tcx>,
500 {
501     fn tcx(&self) -> TyCtxt<'tcx> {
502         self.infcx.tcx
503     }
504
505     // FIXME(oli-obk): not sure how to get the correct ParamEnv
506     fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() }
507
508     fn tag(&self) -> &'static str {
509         "nll::subtype"
510     }
511
512     fn a_is_expected(&self) -> bool {
513         true
514     }
515
516     fn relate_with_variance<T: Relate<'tcx>>(
517         &mut self,
518         variance: ty::Variance,
519         a: &T,
520         b: &T,
521     ) -> RelateResult<'tcx, T> {
522         debug!(
523             "relate_with_variance(variance={:?}, a={:?}, b={:?})",
524             variance, a, b
525         );
526
527         let old_ambient_variance = self.ambient_variance;
528         self.ambient_variance = self.ambient_variance.xform(variance);
529
530         debug!(
531             "relate_with_variance: ambient_variance = {:?}",
532             self.ambient_variance
533         );
534
535         let r = self.relate(a, b)?;
536
537         self.ambient_variance = old_ambient_variance;
538
539         debug!("relate_with_variance: r={:?}", r);
540
541         Ok(r)
542     }
543
544     fn tys(&mut self, a: Ty<'tcx>, mut b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
545         let a = self.infcx.shallow_resolve(a);
546
547         if !D::forbid_inference_vars() {
548             b = self.infcx.shallow_resolve(b);
549         }
550
551         match (&a.kind, &b.kind) {
552             (_, &ty::Infer(ty::TyVar(vid))) => {
553                 if D::forbid_inference_vars() {
554                     // Forbid inference variables in the RHS.
555                     bug!("unexpected inference var {:?}", b)
556                 } else {
557                     self.relate_ty_var((a, vid))
558                 }
559             }
560
561             (&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)),
562
563             (&ty::Projection(projection_ty), _)
564                 if D::normalization() == NormalizationStrategy::Lazy =>
565             {
566                 Ok(self.relate_projection_ty(projection_ty, b))
567             }
568
569             (_, &ty::Projection(projection_ty))
570                 if D::normalization() == NormalizationStrategy::Lazy =>
571             {
572                 Ok(self.relate_projection_ty(projection_ty, a))
573             }
574
575             _ => {
576                 debug!(
577                     "tys(a={:?}, b={:?}, variance={:?})",
578                     a, b, self.ambient_variance
579                 );
580
581                 // Will also handle unification of `IntVar` and `FloatVar`.
582                 self.infcx.super_combine_tys(self, a, b)
583             }
584         }
585     }
586
587     fn regions(
588         &mut self,
589         a: ty::Region<'tcx>,
590         b: ty::Region<'tcx>,
591     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
592         debug!(
593             "regions(a={:?}, b={:?}, variance={:?})",
594             a, b, self.ambient_variance
595         );
596
597         let v_a = self.replace_bound_region(a, ty::INNERMOST, &self.a_scopes);
598         let v_b = self.replace_bound_region(b, ty::INNERMOST, &self.b_scopes);
599
600         debug!("regions: v_a = {:?}", v_a);
601         debug!("regions: v_b = {:?}", v_b);
602
603         if self.ambient_covariance() {
604             // Covariance: a <= b. Hence, `b: a`.
605             self.push_outlives(v_b, v_a);
606         }
607
608         if self.ambient_contravariance() {
609             // Contravariant: b <= a. Hence, `a: b`.
610             self.push_outlives(v_a, v_b);
611         }
612
613         Ok(a)
614     }
615
616     fn consts(
617         &mut self,
618         a: &'tcx ty::Const<'tcx>,
619         b: &'tcx ty::Const<'tcx>,
620     ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
621         if let ty::Const { val: ConstValue::Infer(InferConst::Canonical(_, _)), .. } = a {
622             // FIXME(const_generics): I'm unsure how this branch should actually be handled,
623             // so this is probably not correct.
624             self.infcx.super_combine_consts(self, a, b)
625         } else {
626             debug!("consts(a={:?}, b={:?}, variance={:?})", a, b, self.ambient_variance);
627             relate::super_relate_consts(self, a, b)
628         }
629     }
630
631     fn binders<T>(
632         &mut self,
633         a: &ty::Binder<T>,
634         b: &ty::Binder<T>,
635     ) -> RelateResult<'tcx, ty::Binder<T>>
636     where
637         T: Relate<'tcx>,
638     {
639         // We want that
640         //
641         // ```
642         // for<'a> fn(&'a u32) -> &'a u32 <:
643         //   fn(&'b u32) -> &'b u32
644         // ```
645         //
646         // but not
647         //
648         // ```
649         // fn(&'a u32) -> &'a u32 <:
650         //   for<'b> fn(&'b u32) -> &'b u32
651         // ```
652         //
653         // We therefore proceed as follows:
654         //
655         // - Instantiate binders on `b` universally, yielding a universe U1.
656         // - Instantiate binders on `a` existentially in U1.
657
658         debug!(
659             "binders({:?}: {:?}, ambient_variance={:?})",
660             a, b, self.ambient_variance
661         );
662
663         if self.ambient_covariance() {
664             // Covariance, so we want `for<..> A <: for<..> B` --
665             // therefore we compare any instantiation of A (i.e., A
666             // instantiated with existentials) against every
667             // instantiation of B (i.e., B instantiated with
668             // universals).
669
670             let b_scope = self.create_scope(b, UniversallyQuantified(true));
671             let a_scope = self.create_scope(a, UniversallyQuantified(false));
672
673             debug!("binders: a_scope = {:?} (existential)", a_scope);
674             debug!("binders: b_scope = {:?} (universal)", b_scope);
675
676             self.b_scopes.push(b_scope);
677             self.a_scopes.push(a_scope);
678
679             // Reset the ambient variance to covariant. This is needed
680             // to correctly handle cases like
681             //
682             //     for<'a> fn(&'a u32, &'a u3) == for<'b, 'c> fn(&'b u32, &'c u32)
683             //
684             // Somewhat surprisingly, these two types are actually
685             // **equal**, even though the one on the right looks more
686             // polymorphic. The reason is due to subtyping. To see it,
687             // consider that each function can call the other:
688             //
689             // - The left function can call the right with `'b` and
690             //   `'c` both equal to `'a`
691             //
692             // - The right function can call the left with `'a` set to
693             //   `{P}`, where P is the point in the CFG where the call
694             //   itself occurs. Note that `'b` and `'c` must both
695             //   include P. At the point, the call works because of
696             //   subtyping (i.e., `&'b u32 <: &{P} u32`).
697             let variance = ::std::mem::replace(&mut self.ambient_variance, ty::Variance::Covariant);
698
699             self.relate(a.skip_binder(), b.skip_binder())?;
700
701             self.ambient_variance = variance;
702
703             self.b_scopes.pop().unwrap();
704             self.a_scopes.pop().unwrap();
705         }
706
707         if self.ambient_contravariance() {
708             // Contravariance, so we want `for<..> A :> for<..> B`
709             // -- therefore we compare every instantiation of A (i.e.,
710             // A instantiated with universals) against any
711             // instantiation of B (i.e., B instantiated with
712             // existentials). Opposite of above.
713
714             let a_scope = self.create_scope(a, UniversallyQuantified(true));
715             let b_scope = self.create_scope(b, UniversallyQuantified(false));
716
717             debug!("binders: a_scope = {:?} (universal)", a_scope);
718             debug!("binders: b_scope = {:?} (existential)", b_scope);
719
720             self.a_scopes.push(a_scope);
721             self.b_scopes.push(b_scope);
722
723             // Reset ambient variance to contravariance. See the
724             // covariant case above for an explanation.
725             let variance =
726                 ::std::mem::replace(&mut self.ambient_variance, ty::Variance::Contravariant);
727
728             self.relate(a.skip_binder(), b.skip_binder())?;
729
730             self.ambient_variance = variance;
731
732             self.b_scopes.pop().unwrap();
733             self.a_scopes.pop().unwrap();
734         }
735
736         Ok(a.clone())
737     }
738 }
739
740 /// When we encounter a binder like `for<..> fn(..)`, we actually have
741 /// to walk the `fn` value to find all the values bound by the `for`
742 /// (these are not explicitly present in the ty representation right
743 /// now). This visitor handles that: it descends the type, tracking
744 /// binder depth, and finds late-bound regions targeting the
745 /// `for<..`>.  For each of those, it creates an entry in
746 /// `bound_region_scope`.
747 struct ScopeInstantiator<'me, 'tcx> {
748     next_region: &'me mut dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
749     // The debruijn index of the scope we are instantiating.
750     target_index: ty::DebruijnIndex,
751     bound_region_scope: &'me mut BoundRegionScope<'tcx>,
752 }
753
754 impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
755     fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
756         self.target_index.shift_in(1);
757         t.super_visit_with(self);
758         self.target_index.shift_out(1);
759
760         false
761     }
762
763     fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
764         let ScopeInstantiator {
765             bound_region_scope,
766             next_region,
767             ..
768         } = self;
769
770         match r {
771             ty::ReLateBound(debruijn, br) if *debruijn == self.target_index => {
772                 bound_region_scope
773                     .map
774                     .entry(*br)
775                     .or_insert_with(|| next_region(*br));
776             }
777
778             _ => {}
779         }
780
781         false
782     }
783 }
784
785 /// The "type generalize" is used when handling inference variables.
786 ///
787 /// The basic strategy for handling a constraint like `?A <: B` is to
788 /// apply a "generalization strategy" to the type `B` -- this replaces
789 /// all the lifetimes in the type `B` with fresh inference
790 /// variables. (You can read more about the strategy in this [blog
791 /// post].)
792 ///
793 /// As an example, if we had `?A <: &'x u32`, we would generalize `&'x
794 /// u32` to `&'0 u32` where `'0` is a fresh variable. This becomes the
795 /// value of `A`. Finally, we relate `&'0 u32 <: &'x u32`, which
796 /// establishes `'0: 'x` as a constraint.
797 ///
798 /// As a side-effect of this generalization procedure, we also replace
799 /// all the bound regions that we have traversed with concrete values,
800 /// so that the resulting generalized type is independent from the
801 /// scopes.
802 ///
803 /// [blog post]: https://is.gd/0hKvIr
804 struct TypeGeneralizer<'me, 'tcx, D>
805 where
806     D: TypeRelatingDelegate<'tcx>,
807 {
808     infcx: &'me InferCtxt<'me, 'tcx>,
809
810     delegate: &'me mut D,
811
812     /// After we generalize this type, we are going to relative it to
813     /// some other type. What will be the variance at this point?
814     ambient_variance: ty::Variance,
815
816     first_free_index: ty::DebruijnIndex,
817
818     /// The vid of the type variable that is in the process of being
819     /// instantiated. If we find this within the value we are folding,
820     /// that means we would have created a cyclic value.
821     for_vid_sub_root: ty::TyVid,
822
823     /// The universe of the type variable that is in the process of being
824     /// instantiated. If we find anything that this universe cannot name,
825     /// we reject the relation.
826     universe: ty::UniverseIndex,
827 }
828
829 impl<D> TypeRelation<'tcx> for TypeGeneralizer<'me, 'tcx, D>
830 where
831     D: TypeRelatingDelegate<'tcx>,
832 {
833     fn tcx(&self) -> TyCtxt<'tcx> {
834         self.infcx.tcx
835     }
836
837     // FIXME(oli-obk): not sure how to get the correct ParamEnv
838     fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() }
839
840     fn tag(&self) -> &'static str {
841         "nll::generalizer"
842     }
843
844     fn a_is_expected(&self) -> bool {
845         true
846     }
847
848     fn relate_with_variance<T: Relate<'tcx>>(
849         &mut self,
850         variance: ty::Variance,
851         a: &T,
852         b: &T,
853     ) -> RelateResult<'tcx, T> {
854         debug!(
855             "TypeGeneralizer::relate_with_variance(variance={:?}, a={:?}, b={:?})",
856             variance, a, b
857         );
858
859         let old_ambient_variance = self.ambient_variance;
860         self.ambient_variance = self.ambient_variance.xform(variance);
861
862         debug!(
863             "TypeGeneralizer::relate_with_variance: ambient_variance = {:?}",
864             self.ambient_variance
865         );
866
867         let r = self.relate(a, b)?;
868
869         self.ambient_variance = old_ambient_variance;
870
871         debug!("TypeGeneralizer::relate_with_variance: r={:?}", r);
872
873         Ok(r)
874     }
875
876     fn tys(&mut self, a: Ty<'tcx>, _: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
877         use crate::infer::type_variable::TypeVariableValue;
878
879         debug!("TypeGeneralizer::tys(a={:?})", a);
880
881         match a.kind {
882             ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_))
883                 if D::forbid_inference_vars() =>
884             {
885                 bug!(
886                     "unexpected inference variable encountered in NLL generalization: {:?}",
887                     a
888                 );
889             }
890
891             ty::Infer(ty::TyVar(vid)) => {
892                 let mut variables = self.infcx.type_variables.borrow_mut();
893                 let vid = variables.root_var(vid);
894                 let sub_vid = variables.sub_root_var(vid);
895                 if sub_vid == self.for_vid_sub_root {
896                     // If sub-roots are equal, then `for_vid` and
897                     // `vid` are related via subtyping.
898                     debug!("TypeGeneralizer::tys: occurs check failed");
899                     return Err(TypeError::Mismatch);
900                 } else {
901                     match variables.probe(vid) {
902                         TypeVariableValue::Known { value: u } => {
903                             drop(variables);
904                             self.relate(&u, &u)
905                         }
906                         TypeVariableValue::Unknown {
907                             universe: _universe,
908                         } => {
909                             if self.ambient_variance == ty::Bivariant {
910                                 // FIXME: we may need a WF predicate (related to #54105).
911                             }
912
913                             let origin = *variables.var_origin(vid);
914
915                             // Replacing with a new variable in the universe `self.universe`,
916                             // it will be unified later with the original type variable in
917                             // the universe `_universe`.
918                             let new_var_id = variables.new_var(self.universe, false, origin);
919
920                             let u = self.tcx().mk_ty_var(new_var_id);
921                             debug!(
922                                 "generalize: replacing original vid={:?} with new={:?}",
923                                 vid, u
924                             );
925                             return Ok(u);
926                         }
927                     }
928                 }
929             }
930
931             ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) => {
932                 // No matter what mode we are in,
933                 // integer/floating-point types must be equal to be
934                 // relatable.
935                 Ok(a)
936             }
937
938             ty::Placeholder(placeholder) => {
939                 if self.universe.cannot_name(placeholder.universe) {
940                     debug!(
941                         "TypeGeneralizer::tys: root universe {:?} cannot name\
942                          placeholder in universe {:?}",
943                         self.universe, placeholder.universe
944                     );
945                     Err(TypeError::Mismatch)
946                 } else {
947                     Ok(a)
948                 }
949             }
950
951             _ => relate::super_relate_tys(self, a, a),
952         }
953     }
954
955     fn regions(
956         &mut self,
957         a: ty::Region<'tcx>,
958         _: ty::Region<'tcx>,
959     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
960         debug!("TypeGeneralizer::regions(a={:?})", a);
961
962         if let ty::ReLateBound(debruijn, _) = a {
963             if *debruijn < self.first_free_index {
964                 return Ok(a);
965             }
966         }
967
968         // For now, we just always create a fresh region variable to
969         // replace all the regions in the source type. In the main
970         // type checker, we special case the case where the ambient
971         // variance is `Invariant` and try to avoid creating a fresh
972         // region variable, but since this comes up so much less in
973         // NLL (only when users use `_` etc) it is much less
974         // important.
975         //
976         // As an aside, since these new variables are created in
977         // `self.universe` universe, this also serves to enforce the
978         // universe scoping rules.
979         //
980         // FIXME(#54105) -- if the ambient variance is bivariant,
981         // though, we may however need to check well-formedness or
982         // risk a problem like #41677 again.
983
984         let replacement_region_vid = self.delegate.generalize_existential(self.universe);
985
986         Ok(replacement_region_vid)
987     }
988
989     fn consts(
990         &mut self,
991         a: &'tcx ty::Const<'tcx>,
992         _: &'tcx ty::Const<'tcx>,
993     ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
994         debug!("TypeGeneralizer::consts(a={:?})", a);
995
996         if let ty::Const { val: ConstValue::Infer(InferConst::Canonical(_, _)), .. } = a {
997             bug!(
998                 "unexpected inference variable encountered in NLL generalization: {:?}",
999                 a
1000             );
1001         } else {
1002             relate::super_relate_consts(self, a, a)
1003         }
1004     }
1005
1006     fn binders<T>(
1007         &mut self,
1008         a: &ty::Binder<T>,
1009         _: &ty::Binder<T>,
1010     ) -> RelateResult<'tcx, ty::Binder<T>>
1011     where
1012         T: Relate<'tcx>,
1013     {
1014         debug!("TypeGeneralizer::binders(a={:?})", a);
1015
1016         self.first_free_index.shift_in(1);
1017         let result = self.relate(a.skip_binder(), a.skip_binder())?;
1018         self.first_free_index.shift_out(1);
1019         Ok(ty::Binder::bind(result))
1020     }
1021 }