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