]>
Commit | Line | Data |
---|---|---|
74b04a01 XL |
1 | use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate}; |
2 | use rustc_infer::infer::{InferCtxt, NLLRegionVariableOrigin}; | |
ba9703b0 XL |
3 | use rustc_middle::mir::ConstraintCategory; |
4 | use rustc_middle::ty::relate::TypeRelation; | |
f9f354fc | 5 | use rustc_middle::ty::{self, Const, Ty}; |
ba9703b0 | 6 | use rustc_trait_selection::traits::query::Fallible; |
8faf50e0 | 7 | |
60c5eb7d XL |
8 | use crate::borrow_check::constraints::OutlivesConstraint; |
9 | use crate::borrow_check::type_check::{BorrowCheckContext, Locations}; | |
10 | ||
0bf4aa26 XL |
11 | /// Adds sufficient constraints to ensure that `a R b` where `R` depends on `v`: |
12 | /// | |
13 | /// - "Covariant" `a <: b` | |
14 | /// - "Invariant" `a == b` | |
15 | /// - "Contravariant" `a :> b` | |
16 | /// | |
9fa01778 | 17 | /// N.B., the type `a` is permitted to have unresolved inference |
0bf4aa26 XL |
18 | /// variables, but not the type `b`. |
19 | pub(super) fn relate_types<'tcx>( | |
dc9dc135 | 20 | infcx: &InferCtxt<'_, 'tcx>, |
8faf50e0 | 21 | a: Ty<'tcx>, |
0bf4aa26 | 22 | v: ty::Variance, |
8faf50e0 XL |
23 | b: Ty<'tcx>, |
24 | locations: Locations, | |
0bf4aa26 | 25 | category: ConstraintCategory, |
8faf50e0 XL |
26 | borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>, |
27 | ) -> Fallible<()> { | |
28 | debug!("eq_types(a={:?}, b={:?}, locations={:?})", a, b, locations); | |
29 | TypeRelating::new( | |
30 | infcx, | |
0bf4aa26 | 31 | NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category), |
dfeec247 XL |
32 | v, |
33 | ) | |
34 | .relate(&a, &b)?; | |
8faf50e0 XL |
35 | Ok(()) |
36 | } | |
37 | ||
dc9dc135 XL |
38 | struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> { |
39 | infcx: &'me InferCtxt<'me, 'tcx>, | |
0bf4aa26 | 40 | borrowck_context: Option<&'me mut BorrowCheckContext<'bccx, 'tcx>>, |
8faf50e0 XL |
41 | |
42 | /// Where (and why) is this relation taking place? | |
43 | locations: Locations, | |
44 | ||
0bf4aa26 XL |
45 | /// What category do we assign the resulting `'a: 'b` relationships? |
46 | category: ConstraintCategory, | |
8faf50e0 XL |
47 | } |
48 | ||
dc9dc135 | 49 | impl NllTypeRelatingDelegate<'me, 'bccx, 'tcx> { |
8faf50e0 | 50 | fn new( |
dc9dc135 | 51 | infcx: &'me InferCtxt<'me, 'tcx>, |
0bf4aa26 | 52 | borrowck_context: Option<&'me mut BorrowCheckContext<'bccx, 'tcx>>, |
8faf50e0 | 53 | locations: Locations, |
0bf4aa26 | 54 | category: ConstraintCategory, |
8faf50e0 | 55 | ) -> Self { |
dfeec247 | 56 | Self { infcx, borrowck_context, locations, category } |
8faf50e0 | 57 | } |
0bf4aa26 | 58 | } |
8faf50e0 | 59 | |
dc9dc135 | 60 | impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> { |
0bf4aa26 XL |
61 | fn create_next_universe(&mut self) -> ty::UniverseIndex { |
62 | self.infcx.create_next_universe() | |
8faf50e0 XL |
63 | } |
64 | ||
e74abb32 | 65 | fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> { |
74b04a01 | 66 | if self.borrowck_context.is_some() { |
e74abb32 | 67 | let origin = NLLRegionVariableOrigin::Existential { from_forall }; |
a1dfa0c6 XL |
68 | self.infcx.next_nll_region_var(origin) |
69 | } else { | |
48663c56 | 70 | self.infcx.tcx.lifetimes.re_erased |
a1dfa0c6 | 71 | } |
b7449926 XL |
72 | } |
73 | ||
dfeec247 | 74 | fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> { |
0bf4aa26 | 75 | if let Some(borrowck_context) = &mut self.borrowck_context { |
a1dfa0c6 XL |
76 | borrowck_context.constraints.placeholder_region(self.infcx, placeholder) |
77 | } else { | |
48663c56 | 78 | self.infcx.tcx.lifetimes.re_erased |
8faf50e0 XL |
79 | } |
80 | } | |
81 | ||
0bf4aa26 | 82 | fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> { |
dfeec247 XL |
83 | self.infcx.next_nll_region_var_in_universe( |
84 | NLLRegionVariableOrigin::Existential { from_forall: false }, | |
85 | universe, | |
86 | ) | |
0bf4aa26 | 87 | } |
8faf50e0 | 88 | |
0bf4aa26 | 89 | fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) { |
8faf50e0 | 90 | if let Some(borrowck_context) = &mut self.borrowck_context { |
0bf4aa26 XL |
91 | let sub = borrowck_context.universal_regions.to_region_vid(sub); |
92 | let sup = borrowck_context.universal_regions.to_region_vid(sup); | |
dfeec247 XL |
93 | borrowck_context.constraints.outlives_constraints.push(OutlivesConstraint { |
94 | sup, | |
95 | sub, | |
96 | locations: self.locations, | |
97 | category: self.category, | |
98 | }); | |
8faf50e0 XL |
99 | } |
100 | } | |
a1dfa0c6 | 101 | |
f9f354fc XL |
102 | // We don't have to worry about the equality of consts during borrow checking |
103 | // as consts always have a static lifetime. | |
104 | fn const_equate(&mut self, _a: &'tcx Const<'tcx>, _b: &'tcx Const<'tcx>) {} | |
a1dfa0c6 XL |
105 | |
106 | fn normalization() -> NormalizationStrategy { | |
107 | NormalizationStrategy::Eager | |
108 | } | |
109 | ||
110 | fn forbid_inference_vars() -> bool { | |
111 | true | |
112 | } | |
b7449926 | 113 | } |