]> git.proxmox.com Git - rustc.git/blob - src/librustc/infer/nll_relate/mod.rs
New upstream version 1.41.1+dfsg1
[rustc.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::infer::{ConstVariableValue, ConstVarValue};
32 use rustc_data_structures::fx::FxHashMap;
33 use std::fmt::Debug;
34
35 #[derive(PartialEq)]
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(invariance) -- 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 mut b: &'tcx ty::Const<'tcx>,
620 ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
621 let a = self.infcx.shallow_resolve(a);
622
623 if !D::forbid_inference_vars() {
624 b = self.infcx.shallow_resolve(b);
625 }
626
627 match b.val {
628 ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
629 // Forbid inference variables in the RHS.
630 bug!("unexpected inference var {:?}", b)
631 }
632 // FIXME(invariance): see the related FIXME above.
633 _ => self.infcx.super_combine_consts(self, a, b)
634 }
635 }
636
637 fn binders<T>(
638 &mut self,
639 a: &ty::Binder<T>,
640 b: &ty::Binder<T>,
641 ) -> RelateResult<'tcx, ty::Binder<T>>
642 where
643 T: Relate<'tcx>,
644 {
645 // We want that
646 //
647 // ```
648 // for<'a> fn(&'a u32) -> &'a u32 <:
649 // fn(&'b u32) -> &'b u32
650 // ```
651 //
652 // but not
653 //
654 // ```
655 // fn(&'a u32) -> &'a u32 <:
656 // for<'b> fn(&'b u32) -> &'b u32
657 // ```
658 //
659 // We therefore proceed as follows:
660 //
661 // - Instantiate binders on `b` universally, yielding a universe U1.
662 // - Instantiate binders on `a` existentially in U1.
663
664 debug!(
665 "binders({:?}: {:?}, ambient_variance={:?})",
666 a, b, self.ambient_variance
667 );
668
669 if self.ambient_covariance() {
670 // Covariance, so we want `for<..> A <: for<..> B` --
671 // therefore we compare any instantiation of A (i.e., A
672 // instantiated with existentials) against every
673 // instantiation of B (i.e., B instantiated with
674 // universals).
675
676 let b_scope = self.create_scope(b, UniversallyQuantified(true));
677 let a_scope = self.create_scope(a, UniversallyQuantified(false));
678
679 debug!("binders: a_scope = {:?} (existential)", a_scope);
680 debug!("binders: b_scope = {:?} (universal)", b_scope);
681
682 self.b_scopes.push(b_scope);
683 self.a_scopes.push(a_scope);
684
685 // Reset the ambient variance to covariant. This is needed
686 // to correctly handle cases like
687 //
688 // for<'a> fn(&'a u32, &'a u3) == for<'b, 'c> fn(&'b u32, &'c u32)
689 //
690 // Somewhat surprisingly, these two types are actually
691 // **equal**, even though the one on the right looks more
692 // polymorphic. The reason is due to subtyping. To see it,
693 // consider that each function can call the other:
694 //
695 // - The left function can call the right with `'b` and
696 // `'c` both equal to `'a`
697 //
698 // - The right function can call the left with `'a` set to
699 // `{P}`, where P is the point in the CFG where the call
700 // itself occurs. Note that `'b` and `'c` must both
701 // include P. At the point, the call works because of
702 // subtyping (i.e., `&'b u32 <: &{P} u32`).
703 let variance = ::std::mem::replace(&mut self.ambient_variance, ty::Variance::Covariant);
704
705 self.relate(a.skip_binder(), b.skip_binder())?;
706
707 self.ambient_variance = variance;
708
709 self.b_scopes.pop().unwrap();
710 self.a_scopes.pop().unwrap();
711 }
712
713 if self.ambient_contravariance() {
714 // Contravariance, so we want `for<..> A :> for<..> B`
715 // -- therefore we compare every instantiation of A (i.e.,
716 // A instantiated with universals) against any
717 // instantiation of B (i.e., B instantiated with
718 // existentials). Opposite of above.
719
720 let a_scope = self.create_scope(a, UniversallyQuantified(true));
721 let b_scope = self.create_scope(b, UniversallyQuantified(false));
722
723 debug!("binders: a_scope = {:?} (universal)", a_scope);
724 debug!("binders: b_scope = {:?} (existential)", b_scope);
725
726 self.a_scopes.push(a_scope);
727 self.b_scopes.push(b_scope);
728
729 // Reset ambient variance to contravariance. See the
730 // covariant case above for an explanation.
731 let variance =
732 ::std::mem::replace(&mut self.ambient_variance, ty::Variance::Contravariant);
733
734 self.relate(a.skip_binder(), b.skip_binder())?;
735
736 self.ambient_variance = variance;
737
738 self.b_scopes.pop().unwrap();
739 self.a_scopes.pop().unwrap();
740 }
741
742 Ok(a.clone())
743 }
744 }
745
746 /// When we encounter a binder like `for<..> fn(..)`, we actually have
747 /// to walk the `fn` value to find all the values bound by the `for`
748 /// (these are not explicitly present in the ty representation right
749 /// now). This visitor handles that: it descends the type, tracking
750 /// binder depth, and finds late-bound regions targeting the
751 /// `for<..`>. For each of those, it creates an entry in
752 /// `bound_region_scope`.
753 struct ScopeInstantiator<'me, 'tcx> {
754 next_region: &'me mut dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
755 // The debruijn index of the scope we are instantiating.
756 target_index: ty::DebruijnIndex,
757 bound_region_scope: &'me mut BoundRegionScope<'tcx>,
758 }
759
760 impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
761 fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
762 self.target_index.shift_in(1);
763 t.super_visit_with(self);
764 self.target_index.shift_out(1);
765
766 false
767 }
768
769 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
770 let ScopeInstantiator {
771 bound_region_scope,
772 next_region,
773 ..
774 } = self;
775
776 match r {
777 ty::ReLateBound(debruijn, br) if *debruijn == self.target_index => {
778 bound_region_scope
779 .map
780 .entry(*br)
781 .or_insert_with(|| next_region(*br));
782 }
783
784 _ => {}
785 }
786
787 false
788 }
789 }
790
791 /// The "type generalize" is used when handling inference variables.
792 ///
793 /// The basic strategy for handling a constraint like `?A <: B` is to
794 /// apply a "generalization strategy" to the type `B` -- this replaces
795 /// all the lifetimes in the type `B` with fresh inference
796 /// variables. (You can read more about the strategy in this [blog
797 /// post].)
798 ///
799 /// As an example, if we had `?A <: &'x u32`, we would generalize `&'x
800 /// u32` to `&'0 u32` where `'0` is a fresh variable. This becomes the
801 /// value of `A`. Finally, we relate `&'0 u32 <: &'x u32`, which
802 /// establishes `'0: 'x` as a constraint.
803 ///
804 /// As a side-effect of this generalization procedure, we also replace
805 /// all the bound regions that we have traversed with concrete values,
806 /// so that the resulting generalized type is independent from the
807 /// scopes.
808 ///
809 /// [blog post]: https://is.gd/0hKvIr
810 struct TypeGeneralizer<'me, 'tcx, D>
811 where
812 D: TypeRelatingDelegate<'tcx>,
813 {
814 infcx: &'me InferCtxt<'me, 'tcx>,
815
816 delegate: &'me mut D,
817
818 /// After we generalize this type, we are going to relative it to
819 /// some other type. What will be the variance at this point?
820 ambient_variance: ty::Variance,
821
822 first_free_index: ty::DebruijnIndex,
823
824 /// The vid of the type variable that is in the process of being
825 /// instantiated. If we find this within the value we are folding,
826 /// that means we would have created a cyclic value.
827 for_vid_sub_root: ty::TyVid,
828
829 /// The universe of the type variable that is in the process of being
830 /// instantiated. If we find anything that this universe cannot name,
831 /// we reject the relation.
832 universe: ty::UniverseIndex,
833 }
834
835 impl<D> TypeRelation<'tcx> for TypeGeneralizer<'me, 'tcx, D>
836 where
837 D: TypeRelatingDelegate<'tcx>,
838 {
839 fn tcx(&self) -> TyCtxt<'tcx> {
840 self.infcx.tcx
841 }
842
843 // FIXME(oli-obk): not sure how to get the correct ParamEnv
844 fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() }
845
846 fn tag(&self) -> &'static str {
847 "nll::generalizer"
848 }
849
850 fn a_is_expected(&self) -> bool {
851 true
852 }
853
854 fn relate_with_variance<T: Relate<'tcx>>(
855 &mut self,
856 variance: ty::Variance,
857 a: &T,
858 b: &T,
859 ) -> RelateResult<'tcx, T> {
860 debug!(
861 "TypeGeneralizer::relate_with_variance(variance={:?}, a={:?}, b={:?})",
862 variance, a, b
863 );
864
865 let old_ambient_variance = self.ambient_variance;
866 self.ambient_variance = self.ambient_variance.xform(variance);
867
868 debug!(
869 "TypeGeneralizer::relate_with_variance: ambient_variance = {:?}",
870 self.ambient_variance
871 );
872
873 let r = self.relate(a, b)?;
874
875 self.ambient_variance = old_ambient_variance;
876
877 debug!("TypeGeneralizer::relate_with_variance: r={:?}", r);
878
879 Ok(r)
880 }
881
882 fn tys(&mut self, a: Ty<'tcx>, _: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
883 use crate::infer::type_variable::TypeVariableValue;
884
885 debug!("TypeGeneralizer::tys(a={:?})", a);
886
887 match a.kind {
888 ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_))
889 if D::forbid_inference_vars() =>
890 {
891 bug!(
892 "unexpected inference variable encountered in NLL generalization: {:?}",
893 a
894 );
895 }
896
897 ty::Infer(ty::TyVar(vid)) => {
898 let mut variables = self.infcx.type_variables.borrow_mut();
899 let vid = variables.root_var(vid);
900 let sub_vid = variables.sub_root_var(vid);
901 if sub_vid == self.for_vid_sub_root {
902 // If sub-roots are equal, then `for_vid` and
903 // `vid` are related via subtyping.
904 debug!("TypeGeneralizer::tys: occurs check failed");
905 return Err(TypeError::Mismatch);
906 } else {
907 match variables.probe(vid) {
908 TypeVariableValue::Known { value: u } => {
909 drop(variables);
910 self.relate(&u, &u)
911 }
912 TypeVariableValue::Unknown {
913 universe: _universe,
914 } => {
915 if self.ambient_variance == ty::Bivariant {
916 // FIXME: we may need a WF predicate (related to #54105).
917 }
918
919 let origin = *variables.var_origin(vid);
920
921 // Replacing with a new variable in the universe `self.universe`,
922 // it will be unified later with the original type variable in
923 // the universe `_universe`.
924 let new_var_id = variables.new_var(self.universe, false, origin);
925
926 let u = self.tcx().mk_ty_var(new_var_id);
927 debug!(
928 "generalize: replacing original vid={:?} with new={:?}",
929 vid, u
930 );
931 return Ok(u);
932 }
933 }
934 }
935 }
936
937 ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) => {
938 // No matter what mode we are in,
939 // integer/floating-point types must be equal to be
940 // relatable.
941 Ok(a)
942 }
943
944 ty::Placeholder(placeholder) => {
945 if self.universe.cannot_name(placeholder.universe) {
946 debug!(
947 "TypeGeneralizer::tys: root universe {:?} cannot name\
948 placeholder in universe {:?}",
949 self.universe, placeholder.universe
950 );
951 Err(TypeError::Mismatch)
952 } else {
953 Ok(a)
954 }
955 }
956
957 _ => relate::super_relate_tys(self, a, a),
958 }
959 }
960
961 fn regions(
962 &mut self,
963 a: ty::Region<'tcx>,
964 _: ty::Region<'tcx>,
965 ) -> RelateResult<'tcx, ty::Region<'tcx>> {
966 debug!("TypeGeneralizer::regions(a={:?})", a);
967
968 if let ty::ReLateBound(debruijn, _) = a {
969 if *debruijn < self.first_free_index {
970 return Ok(a);
971 }
972 }
973
974 // For now, we just always create a fresh region variable to
975 // replace all the regions in the source type. In the main
976 // type checker, we special case the case where the ambient
977 // variance is `Invariant` and try to avoid creating a fresh
978 // region variable, but since this comes up so much less in
979 // NLL (only when users use `_` etc) it is much less
980 // important.
981 //
982 // As an aside, since these new variables are created in
983 // `self.universe` universe, this also serves to enforce the
984 // universe scoping rules.
985 //
986 // FIXME(#54105) -- if the ambient variance is bivariant,
987 // though, we may however need to check well-formedness or
988 // risk a problem like #41677 again.
989
990 let replacement_region_vid = self.delegate.generalize_existential(self.universe);
991
992 Ok(replacement_region_vid)
993 }
994
995 fn consts(
996 &mut self,
997 a: &'tcx ty::Const<'tcx>,
998 _: &'tcx ty::Const<'tcx>,
999 ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
1000 match a.val {
1001 ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
1002 bug!(
1003 "unexpected inference variable encountered in NLL generalization: {:?}",
1004 a
1005 );
1006 }
1007 ty::ConstKind::Infer(InferConst::Var(vid)) => {
1008 let mut variable_table = self.infcx.const_unification_table.borrow_mut();
1009 let var_value = variable_table.probe_value(vid);
1010 match var_value.val.known() {
1011 Some(u) => self.relate(&u, &u),
1012 None => {
1013 let new_var_id = variable_table.new_key(ConstVarValue {
1014 origin: var_value.origin,
1015 val: ConstVariableValue::Unknown { universe: self.universe },
1016 });
1017 Ok(self.tcx().mk_const_var(new_var_id, a.ty))
1018 }
1019 }
1020 }
1021 _ => relate::super_relate_consts(self, a, a),
1022 }
1023 }
1024
1025 fn binders<T>(
1026 &mut self,
1027 a: &ty::Binder<T>,
1028 _: &ty::Binder<T>,
1029 ) -> RelateResult<'tcx, ty::Binder<T>>
1030 where
1031 T: Relate<'tcx>,
1032 {
1033 debug!("TypeGeneralizer::binders(a={:?})", a);
1034
1035 self.first_free_index.shift_in(1);
1036 let result = self.relate(a.skip_binder(), a.skip_binder())?;
1037 self.first_free_index.shift_out(1);
1038 Ok(ty::Binder::bind(result))
1039 }
1040 }