Skip to content

Commit 77ddc35

Browse files
committed
Hoist the reused Elaborator out so it actually gets reused
1 parent 6fb0711 commit 77ddc35

File tree

4 files changed

+39
-25
lines changed

4 files changed

+39
-25
lines changed

src/librustc/infer/outlives/obligations.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ use crate::hir;
6363
use crate::infer::outlives::env::RegionBoundPairs;
6464
use crate::infer::outlives::verify::VerifyBoundCx;
6565
use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
66+
use crate::traits;
6667
use crate::traits::ObligationCause;
6768
use crate::ty::outlives::Component;
6869
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: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,31 @@ use crate::infer::{GenericKind, VerifyBound};
44
use crate::traits;
55
use crate::ty::subst::{InternalSubsts, Subst};
66
use crate::ty::{self, Ty, TyCtxt};
7-
use crate::util::captures::{Captures, Captures2};
7+
use crate::util::captures::{Captures, Captures2, Captures3};
88

99
/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`
1010
/// obligation into a series of `'a: 'b` constraints and "verifys", as
1111
/// described on the module comment. The final constraints are emitted
1212
/// via a "delegate" of type `D` -- this is usually the `infcx`, which
1313
/// accrues them into the `region_obligations` code, but for NLL we
1414
/// use something else.
15-
pub struct VerifyBoundCx<'cx, 'tcx> {
15+
pub struct VerifyBoundCx<'cx, 'tcx, 'e> {
1616
tcx: TyCtxt<'tcx>,
1717
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
1818
implicit_region_bound: Option<ty::Region<'tcx>>,
1919
param_env: ty::ParamEnv<'tcx>,
20-
elaborator: traits::Elaborator<'tcx>,
20+
elaborator: &'e mut traits::Elaborator<'tcx>,
2121
}
2222

23-
impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
23+
impl<'cx, 'tcx, 'e> VerifyBoundCx<'cx, 'tcx, 'e> {
2424
pub fn new(
2525
tcx: TyCtxt<'tcx>,
2626
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
2727
implicit_region_bound: Option<ty::Region<'tcx>>,
2828
param_env: ty::ParamEnv<'tcx>,
29+
elaborator: &'e mut traits::Elaborator<'tcx>,
2930
) -> Self {
30-
Self {
31-
tcx,
32-
region_bound_pairs,
33-
implicit_region_bound,
34-
param_env,
35-
elaborator: traits::Elaborator::new(tcx),
36-
}
31+
Self { tcx, region_bound_pairs, implicit_region_bound, param_env, elaborator }
3732
}
3833

3934
/// Returns a "verify bound" that encodes what we know about
@@ -106,7 +101,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
106101
pub fn projection_declared_bounds_from_trait<'a>(
107102
&'a mut self,
108103
projection_ty: ty::ProjectionTy<'tcx>,
109-
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures2<'cx, 'tcx> {
104+
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures3<'cx, 'tcx, 'e> {
110105
self.declared_projection_bounds_from_trait(projection_ty)
111106
}
112107

@@ -237,7 +232,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
237232
fn declared_projection_bounds_from_trait<'a>(
238233
&'a mut self,
239234
projection_ty: ty::ProjectionTy<'tcx>,
240-
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures2<'cx, 'tcx> {
235+
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures3<'cx, 'tcx, 'e> {
241236
debug!("projection_bounds(projection_ty={:?})", projection_ty);
242237
let tcx = self.tcx;
243238
self.region_bounds_declared_on_associated_item(projection_ty.item_def_id)
@@ -277,7 +272,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
277272
fn region_bounds_declared_on_associated_item<'a>(
278273
&'a mut self,
279274
assoc_item_def_id: DefId,
280-
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures2<'cx, 'tcx> {
275+
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures3<'cx, 'tcx, 'e> {
281276
let tcx = self.tcx;
282277
let assoc_item = tcx.associated_item(assoc_item_def_id);
283278
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)