Skip to content

Commit 365ccde

Browse files
committed
Hoist the reused Elaborator out so it actually gets reused
1 parent f7f40b9 commit 365ccde

File tree

4 files changed

+40
-32
lines changed

4 files changed

+40
-32
lines changed

src/librustc/infer/outlives/obligations.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
use crate::infer::outlives::env::RegionBoundPairs;
6363
use crate::infer::outlives::verify::VerifyBoundCx;
6464
use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
65+
use crate::traits;
6566
use crate::traits::ObligationCause;
6667
use crate::ty::outlives::Component;
6768
use crate::ty::subst::GenericArgKind;
@@ -154,6 +155,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
154155

155156
let my_region_obligations = self.take_registered_region_obligations();
156157

158+
let mut elaborator = traits::Elaborator::new(self.tcx);
159+
157160
for (body_id, RegionObligation { sup_type, sub_region, origin }) in my_region_obligations {
158161
debug!(
159162
"process_registered_region_obligations: sup_type={:?} sub_region={:?} origin={:?}",
@@ -169,6 +172,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
169172
&region_bound_pairs,
170173
implicit_region_bound,
171174
param_env,
175+
&mut elaborator,
172176
);
173177
outlives.type_must_outlive(origin, sup_type, sub_region);
174178
} else {
@@ -191,15 +195,16 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
191195
ty: Ty<'tcx>,
192196
region: ty::Region<'tcx>,
193197
) {
194-
let outlives = &mut TypeOutlives::new(
198+
let ty = self.resolve_vars_if_possible(&ty);
199+
TypeOutlives::new(
195200
self,
196201
self.tcx,
197202
region_bound_pairs,
198203
implicit_region_bound,
199204
param_env,
200-
);
201-
let ty = self.resolve_vars_if_possible(&ty);
202-
outlives.type_must_outlive(origin, ty, region);
205+
&mut traits::Elaborator::new(self.tcx),
206+
)
207+
.type_must_outlive(origin, ty, region);
203208
}
204209
}
205210

@@ -209,15 +214,15 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
209214
/// via a "delegate" of type `D` -- this is usually the `infcx`, which
210215
/// accrues them into the `region_obligations` code, but for NLL we
211216
/// use something else.
212-
pub struct TypeOutlives<'cx, 'tcx, D>
217+
pub struct TypeOutlives<'cx, 'tcx, 'e, D>
213218
where
214219
D: TypeOutlivesDelegate<'tcx>,
215220
{
216221
// See the comments on `process_registered_region_obligations` for the meaning
217222
// of these fields.
218223
delegate: D,
219224
tcx: TyCtxt<'tcx>,
220-
verify_bound: VerifyBoundCx<'cx, 'tcx>,
225+
verify_bound: VerifyBoundCx<'cx, 'tcx, 'e>,
221226
}
222227

223228
pub trait TypeOutlivesDelegate<'tcx> {
@@ -237,7 +242,7 @@ pub trait TypeOutlivesDelegate<'tcx> {
237242
);
238243
}
239244

240-
impl<'cx, 'tcx, D> TypeOutlives<'cx, 'tcx, D>
245+
impl<'cx, 'tcx, 'e, D> TypeOutlives<'cx, 'tcx, 'e, D>
241246
where
242247
D: TypeOutlivesDelegate<'tcx>,
243248
{
@@ -247,6 +252,7 @@ where
247252
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
248253
implicit_region_bound: Option<ty::Region<'tcx>>,
249254
param_env: ty::ParamEnv<'tcx>,
255+
elaborator: &'e mut traits::Elaborator<'tcx>,
250256
) -> Self {
251257
Self {
252258
delegate,
@@ -256,6 +262,7 @@ where
256262
region_bound_pairs,
257263
implicit_region_bound,
258264
param_env,
265+
elaborator,
259266
),
260267
}
261268
}
@@ -273,7 +280,9 @@ where
273280
origin: infer::SubregionOrigin<'tcx>,
274281
ty: Ty<'tcx>,
275282
region: ty::Region<'tcx>,
276-
) {
283+
) where
284+
'tcx: 'e,
285+
{
277286
debug!("type_must_outlive(ty={:?}, region={:?}, origin={:?})", ty, region, origin);
278287

279288
assert!(!ty.has_escaping_bound_vars());
@@ -288,7 +297,9 @@ where
288297
origin: infer::SubregionOrigin<'tcx>,
289298
components: &[Component<'tcx>],
290299
region: ty::Region<'tcx>,
291-
) {
300+
) where
301+
'tcx: 'e,
302+
{
292303
for component in components {
293304
let origin = origin.clone();
294305
match component {
@@ -338,7 +349,9 @@ where
338349
origin: infer::SubregionOrigin<'tcx>,
339350
region: ty::Region<'tcx>,
340351
projection_ty: ty::ProjectionTy<'tcx>,
341-
) {
352+
) where
353+
'tcx: 'e,
354+
{
342355
debug!(
343356
"projection_must_outlive(region={:?}, projection_ty={:?}, origin={:?})",
344357
region, projection_ty, origin

src/librustc/infer/outlives/verify.rs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
use std::cell::RefCell;
2-
31
use crate::infer::outlives::env::RegionBoundPairs;
42
use crate::infer::{GenericKind, VerifyBound};
53
use crate::traits;
64
use crate::ty::subst::{InternalSubsts, Subst};
75
use crate::ty::{self, Ty, TyCtxt};
8-
use crate::util::captures::{Captures, Captures2};
6+
use crate::util::captures::{Captures, Captures2, Captures3};
97
use rustc_hir::def_id::DefId;
108

119
/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`
@@ -14,28 +12,23 @@ use rustc_hir::def_id::DefId;
1412
/// via a "delegate" of type `D` -- this is usually the `infcx`, which
1513
/// accrues them into the `region_obligations` code, but for NLL we
1614
/// use something else.
17-
pub struct VerifyBoundCx<'cx, 'tcx> {
15+
pub struct VerifyBoundCx<'cx, 'tcx, 'e> {
1816
tcx: TyCtxt<'tcx>,
1917
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
2018
implicit_region_bound: Option<ty::Region<'tcx>>,
2119
param_env: ty::ParamEnv<'tcx>,
22-
elaborator: traits::Elaborator<'tcx>,
20+
elaborator: &'e mut traits::Elaborator<'tcx>,
2321
}
2422

25-
impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
23+
impl<'cx, 'tcx, 'e> VerifyBoundCx<'cx, 'tcx, 'e> {
2624
pub fn new(
2725
tcx: TyCtxt<'tcx>,
2826
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
2927
implicit_region_bound: Option<ty::Region<'tcx>>,
3028
param_env: ty::ParamEnv<'tcx>,
29+
elaborator: &'e mut traits::Elaborator<'tcx>,
3130
) -> Self {
32-
Self {
33-
tcx,
34-
region_bound_pairs,
35-
implicit_region_bound,
36-
param_env,
37-
elaborator: traits::Elaborator::new(tcx),
38-
}
31+
Self { tcx, region_bound_pairs, implicit_region_bound, param_env, elaborator }
3932
}
4033

4134
/// Returns a "verify bound" that encodes what we know about
@@ -108,7 +101,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
108101
pub fn projection_declared_bounds_from_trait<'a>(
109102
&'a mut self,
110103
projection_ty: ty::ProjectionTy<'tcx>,
111-
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures2<'cx, 'tcx> {
104+
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures3<'cx, 'tcx, 'e> {
112105
self.declared_projection_bounds_from_trait(projection_ty)
113106
}
114107

@@ -162,11 +155,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
162155
.filter(|b| !b.must_hold())
163156
.collect::<Vec<_>>();
164157

165-
if bounds.len() == 1 {
166-
bounds.pop().unwrap()
167-
} else {
168-
VerifyBound::AllBounds(bounds)
169-
}
158+
if bounds.len() == 1 { bounds.pop().unwrap() } else { VerifyBound::AllBounds(bounds) }
170159
}
171160

172161
/// Searches the environment for where-clauses like `G: 'a` where
@@ -243,7 +232,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
243232
fn declared_projection_bounds_from_trait<'a>(
244233
&'a mut self,
245234
projection_ty: ty::ProjectionTy<'tcx>,
246-
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures2<'cx, 'tcx> {
235+
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures3<'cx, 'tcx, 'e> {
247236
debug!("projection_bounds(projection_ty={:?})", projection_ty);
248237
let tcx = self.tcx;
249238
self.region_bounds_declared_on_associated_item(projection_ty.item_def_id)
@@ -283,7 +272,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
283272
fn region_bounds_declared_on_associated_item<'a>(
284273
&'a mut self,
285274
assoc_item_def_id: DefId,
286-
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures2<'cx, 'tcx> {
275+
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures3<'cx, 'tcx, 'e> {
287276
let tcx = self.tcx;
288277
let assoc_item = tcx.associated_item(assoc_item_def_id);
289278
let trait_def_id = assoc_item.container.assert_trait();

src/librustc/util/captures.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@ pub trait Captures<'a> {}
99

1010
impl<'a, T: ?Sized> Captures<'a> for T {}
1111

12-
// FIXME(eddyb) false positive, the lifetime parameter is "phantom" but needed.
1312
#[allow(unused_lifetimes)]
1413
pub trait Captures2<'a, 'b> {}
1514

1615
impl<'a, 'b, T: ?Sized> Captures2<'a, 'b> for T {}
16+
17+
#[allow(unused_lifetimes)]
18+
pub trait Captures3<'a, 'b, 'c> {}
19+
20+
impl<'a, 'b, 'c, T: ?Sized> Captures3<'a, 'b, 'c> for T {}

src/librustc_mir/borrow_check/type_check/constraint_conversion.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
55
use rustc::infer::region_constraints::{GenericKind, VerifyBound};
66
use rustc::infer::{self, InferCtxt, SubregionOrigin};
77
use rustc::mir::ConstraintCategory;
8+
use rustc::traits;
89
use rustc::ty::subst::GenericArgKind;
910
use rustc::ty::{self, TyCtxt};
1011
use rustc_span::DUMMY_SP;
@@ -108,6 +109,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
108109
region_bound_pairs,
109110
implicit_region_bound,
110111
param_env,
112+
&mut traits::Elaborator::new(tcx),
111113
)
112114
.type_must_outlive(origin, t1, r2);
113115
}

0 commit comments

Comments
 (0)