Skip to content

Commit

Permalink
Hoist the reused Elaborator out so it actually gets reused
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Jan 6, 2020
1 parent f7f40b9 commit 365ccde
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 32 deletions.
33 changes: 23 additions & 10 deletions src/librustc/infer/outlives/obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
use crate::infer::outlives::env::RegionBoundPairs;
use crate::infer::outlives::verify::VerifyBoundCx;
use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
use crate::traits;
use crate::traits::ObligationCause;
use crate::ty::outlives::Component;
use crate::ty::subst::GenericArgKind;
Expand Down Expand Up @@ -154,6 +155,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {

let my_region_obligations = self.take_registered_region_obligations();

let mut elaborator = traits::Elaborator::new(self.tcx);

for (body_id, RegionObligation { sup_type, sub_region, origin }) in my_region_obligations {
debug!(
"process_registered_region_obligations: sup_type={:?} sub_region={:?} origin={:?}",
Expand All @@ -169,6 +172,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
&region_bound_pairs,
implicit_region_bound,
param_env,
&mut elaborator,
);
outlives.type_must_outlive(origin, sup_type, sub_region);
} else {
Expand All @@ -191,15 +195,16 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
ty: Ty<'tcx>,
region: ty::Region<'tcx>,
) {
let outlives = &mut TypeOutlives::new(
let ty = self.resolve_vars_if_possible(&ty);
TypeOutlives::new(
self,
self.tcx,
region_bound_pairs,
implicit_region_bound,
param_env,
);
let ty = self.resolve_vars_if_possible(&ty);
outlives.type_must_outlive(origin, ty, region);
&mut traits::Elaborator::new(self.tcx),
)
.type_must_outlive(origin, ty, region);
}
}

Expand All @@ -209,15 +214,15 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
/// via a "delegate" of type `D` -- this is usually the `infcx`, which
/// accrues them into the `region_obligations` code, but for NLL we
/// use something else.
pub struct TypeOutlives<'cx, 'tcx, D>
pub struct TypeOutlives<'cx, 'tcx, 'e, D>
where
D: TypeOutlivesDelegate<'tcx>,
{
// See the comments on `process_registered_region_obligations` for the meaning
// of these fields.
delegate: D,
tcx: TyCtxt<'tcx>,
verify_bound: VerifyBoundCx<'cx, 'tcx>,
verify_bound: VerifyBoundCx<'cx, 'tcx, 'e>,
}

pub trait TypeOutlivesDelegate<'tcx> {
Expand All @@ -237,7 +242,7 @@ pub trait TypeOutlivesDelegate<'tcx> {
);
}

impl<'cx, 'tcx, D> TypeOutlives<'cx, 'tcx, D>
impl<'cx, 'tcx, 'e, D> TypeOutlives<'cx, 'tcx, 'e, D>
where
D: TypeOutlivesDelegate<'tcx>,
{
Expand All @@ -247,6 +252,7 @@ where
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
implicit_region_bound: Option<ty::Region<'tcx>>,
param_env: ty::ParamEnv<'tcx>,
elaborator: &'e mut traits::Elaborator<'tcx>,
) -> Self {
Self {
delegate,
Expand All @@ -256,6 +262,7 @@ where
region_bound_pairs,
implicit_region_bound,
param_env,
elaborator,
),
}
}
Expand All @@ -273,7 +280,9 @@ where
origin: infer::SubregionOrigin<'tcx>,
ty: Ty<'tcx>,
region: ty::Region<'tcx>,
) {
) where
'tcx: 'e,
{
debug!("type_must_outlive(ty={:?}, region={:?}, origin={:?})", ty, region, origin);

assert!(!ty.has_escaping_bound_vars());
Expand All @@ -288,7 +297,9 @@ where
origin: infer::SubregionOrigin<'tcx>,
components: &[Component<'tcx>],
region: ty::Region<'tcx>,
) {
) where
'tcx: 'e,
{
for component in components {
let origin = origin.clone();
match component {
Expand Down Expand Up @@ -338,7 +349,9 @@ where
origin: infer::SubregionOrigin<'tcx>,
region: ty::Region<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
) {
) where
'tcx: 'e,
{
debug!(
"projection_must_outlive(region={:?}, projection_ty={:?}, origin={:?})",
region, projection_ty, origin
Expand Down
31 changes: 10 additions & 21 deletions src/librustc/infer/outlives/verify.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use std::cell::RefCell;

use crate::infer::outlives::env::RegionBoundPairs;
use crate::infer::{GenericKind, VerifyBound};
use crate::traits;
use crate::ty::subst::{InternalSubsts, Subst};
use crate::ty::{self, Ty, TyCtxt};
use crate::util::captures::{Captures, Captures2};
use crate::util::captures::{Captures, Captures2, Captures3};
use rustc_hir::def_id::DefId;

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

impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
impl<'cx, 'tcx, 'e> VerifyBoundCx<'cx, 'tcx, 'e> {
pub fn new(
tcx: TyCtxt<'tcx>,
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
implicit_region_bound: Option<ty::Region<'tcx>>,
param_env: ty::ParamEnv<'tcx>,
elaborator: &'e mut traits::Elaborator<'tcx>,
) -> Self {
Self {
tcx,
region_bound_pairs,
implicit_region_bound,
param_env,
elaborator: traits::Elaborator::new(tcx),
}
Self { tcx, region_bound_pairs, implicit_region_bound, param_env, elaborator }
}

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

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

if bounds.len() == 1 {
bounds.pop().unwrap()
} else {
VerifyBound::AllBounds(bounds)
}
if bounds.len() == 1 { bounds.pop().unwrap() } else { VerifyBound::AllBounds(bounds) }
}

/// Searches the environment for where-clauses like `G: 'a` where
Expand Down Expand Up @@ -243,7 +232,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
fn declared_projection_bounds_from_trait<'a>(
&'a mut self,
projection_ty: ty::ProjectionTy<'tcx>,
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures2<'cx, 'tcx> {
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures3<'cx, 'tcx, 'e> {
debug!("projection_bounds(projection_ty={:?})", projection_ty);
let tcx = self.tcx;
self.region_bounds_declared_on_associated_item(projection_ty.item_def_id)
Expand Down Expand Up @@ -283,7 +272,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
fn region_bounds_declared_on_associated_item<'a>(
&'a mut self,
assoc_item_def_id: DefId,
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures2<'cx, 'tcx> {
) -> impl Iterator<Item = ty::Region<'tcx>> + 'a + Captures3<'cx, 'tcx, 'e> {
let tcx = self.tcx;
let assoc_item = tcx.associated_item(assoc_item_def_id);
let trait_def_id = assoc_item.container.assert_trait();
Expand Down
6 changes: 5 additions & 1 deletion src/librustc/util/captures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ pub trait Captures<'a> {}

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

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

impl<'a, 'b, T: ?Sized> Captures2<'a, 'b> for T {}

#[allow(unused_lifetimes)]
pub trait Captures3<'a, 'b, 'c> {}

impl<'a, 'b, 'c, T: ?Sized> Captures3<'a, 'b, 'c> for T {}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
use rustc::infer::region_constraints::{GenericKind, VerifyBound};
use rustc::infer::{self, InferCtxt, SubregionOrigin};
use rustc::mir::ConstraintCategory;
use rustc::traits;
use rustc::ty::subst::GenericArgKind;
use rustc::ty::{self, TyCtxt};
use rustc_span::DUMMY_SP;
Expand Down Expand Up @@ -108,6 +109,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
region_bound_pairs,
implicit_region_bound,
param_env,
&mut traits::Elaborator::new(tcx),
)
.type_must_outlive(origin, t1, r2);
}
Expand Down

0 comments on commit 365ccde

Please sign in to comment.