Skip to content

Commit

Permalink
Revert the non-view changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Jan 10, 2020
1 parent 0ca62cc commit fba7f77
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 126 deletions.
39 changes: 16 additions & 23 deletions src/librustc/infer/outlives/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {

// Start with anything like `T: 'a` we can scrape from the
// environment
let param_bounds = self
.declared_generic_bounds_from_env(GenericKind::Param(param_ty))
.into_iter()
.map(|outlives| outlives.1);
let param_bounds =
self.declared_generic_bounds_from_env(param_ty).into_iter().map(|outlives| outlives.1);

// Add in the default bound of fn body that applies to all in
// scope type parameters:
Expand Down Expand Up @@ -110,24 +108,21 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {

let projection_ty_as_ty = projection_ty.as_ty();

let mut bounds = Vec::new();

// Search the env for where clauses like `P: 'a`.
bounds.extend(
self.projection_approx_declared_bounds_from_env(projection_ty).into_iter().map(
|ty::OutlivesPredicate(ty, r)| {
let vb = VerifyBound::OutlivedBy(r);
if ty == projection_ty_as_ty {
// Micro-optimize if this is an exact match (this
// occurs often when there are no region variables
// involved).
vb
} else {
VerifyBound::IfEq(ty, Box::new(vb))
}
},
),
);
let env_bounds = self
.projection_approx_declared_bounds_from_env(projection_ty)
.into_iter()
.map(|ty::OutlivesPredicate(ty, r)| {
let vb = VerifyBound::OutlivedBy(r);
if ty == projection_ty_as_ty {
// Micro-optimize if this is an exact match (this
// occurs often when there are no region variables
// involved).
vb
} else {
VerifyBound::IfEq(ty, Box::new(vb))
}
});

// Extend with bounds that we can find from the trait.
let trait_bounds = self
Expand Down Expand Up @@ -176,8 +171,6 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
&self,
compare_ty: impl Fn(Ty<'tcx>) -> bool,
) -> Vec<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> {
let tcx = self.tcx;

// To start, collect bounds from user environment. Note that
// parameter environments are already elaborated, so we don't
// have to worry about that. Comparing using `==` is a bit
Expand Down
15 changes: 5 additions & 10 deletions src/librustc/infer/region_constraints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -904,18 +904,13 @@ impl<'tcx> VerifyBound<'tcx> {
}
}

pub fn or(self, vb: impl FnOnce() -> VerifyBound<'tcx>) -> VerifyBound<'tcx> {
if self.must_hold() {
pub fn or(self, vb: VerifyBound<'tcx>) -> VerifyBound<'tcx> {
if self.must_hold() || vb.cannot_hold() {
self
} else if self.cannot_hold() || vb.must_hold() {
vb
} else {
let vb = vb();
if vb.cannot_hold() {
self
} else if self.cannot_hold() || vb.must_hold() {
vb
} else {
VerifyBound::AnyBound(vec![self, vb])
}
VerifyBound::AnyBound(vec![self, vb])
}
}

Expand Down
176 changes: 88 additions & 88 deletions src/librustc/ty/outlives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,106 +60,106 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
// with `collect()` because of the need to sometimes skip subtrees
// in the `subtys` iterator (e.g., when encountering a
// projection).
match ty.kind {
ty::view::Closure(def_id, ref substs) => {
for upvar_ty in substs.as_closure().upvar_tys(def_id, tcx) {
compute_components(tcx, upvar_ty, out);
}
match ty.into() {
ty::view::Closure(def_id, ref substs) => {
for upvar_ty in substs.as_closure().upvar_tys(def_id, tcx) {
compute_components(tcx, upvar_ty, out);
}
}

ty::view::Generator(def_id, ref substs, _) => {
// Same as the closure case
for upvar_ty in substs.as_generator().upvar_tys(def_id, tcx) {
compute_components(tcx, upvar_ty, out);
}

// We ignore regions in the generator interior as we don't
// want these to affect region inference
ty::view::Generator(def_id, ref substs, _) => {
// Same as the closure case
for upvar_ty in substs.as_generator().upvar_tys(def_id, tcx) {
compute_components(tcx, upvar_ty, out);
}

// All regions are bound inside a witness
ty::view::GeneratorWitness(..) => (),
// We ignore regions in the generator interior as we don't
// want these to affect region inference
}

// OutlivesTypeParameterEnv -- the actual checking that `X:'a`
// is implied by the environment is done in regionck.
ty::view::Param(p) => {
out.push(Component::Param(p));
}
// All regions are bound inside a witness
ty::view::GeneratorWitness(..) => (),

// OutlivesTypeParameterEnv -- the actual checking that `X:'a`
// is implied by the environment is done in regionck.
ty::view::Param(p) => {
out.push(Component::Param(p));
}

// For projections, we prefer to generate an obligation like
// `<P0 as Trait<P1...Pn>>::Foo: 'a`, because this gives the
// regionck more ways to prove that it holds. However,
// regionck is not (at least currently) prepared to deal with
// higher-ranked regions that may appear in the
// trait-ref. Therefore, if we see any higher-ranke regions,
// we simply fallback to the most restrictive rule, which
// requires that `Pi: 'a` for all `i`.
ty::view::Projection(data) => {
if !data.has_escaping_bound_vars() {
// best case: no escaping regions, so push the
// projection and skip the subtree (thus generating no
// constraints for Pi). This defers the choice between
// the rules OutlivesProjectionEnv,
// OutlivesProjectionTraitDef, and
// OutlivesProjectionComponents to regionck.
out.push(Component::Projection(data));
} else {
// fallback case: hard code
// OutlivesProjectionComponents. Continue walking
// through and constrain Pi.
let subcomponents = capture_components(tcx, ty);
out.push(Component::EscapingProjection(subcomponents));
}
// For projections, we prefer to generate an obligation like
// `<P0 as Trait<P1...Pn>>::Foo: 'a`, because this gives the
// regionck more ways to prove that it holds. However,
// regionck is not (at least currently) prepared to deal with
// higher-ranked regions that may appear in the
// trait-ref. Therefore, if we see any higher-ranke regions,
// we simply fallback to the most restrictive rule, which
// requires that `Pi: 'a` for all `i`.
ty::view::Projection(data) => {
if !data.has_escaping_bound_vars() {
// best case: no escaping regions, so push the
// projection and skip the subtree (thus generating no
// constraints for Pi). This defers the choice between
// the rules OutlivesProjectionEnv,
// OutlivesProjectionTraitDef, and
// OutlivesProjectionComponents to regionck.
out.push(Component::Projection(data));
} else {
// fallback case: hard code
// OutlivesProjectionComponents. Continue walking
// through and constrain Pi.
let subcomponents = capture_components(tcx, ty);
out.push(Component::EscapingProjection(subcomponents));
}
}

ty::view::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
ty::view::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),

// We assume that inference variables are fully resolved.
// So, if we encounter an inference variable, just record
// the unresolved variable as a component.
ty::view::Infer(infer_ty) => {
out.push(Component::UnresolvedInferenceVariable(infer_ty));
}
// We assume that inference variables are fully resolved.
// So, if we encounter an inference variable, just record
// the unresolved variable as a component.
ty::view::Infer(infer_ty) => {
out.push(Component::UnresolvedInferenceVariable(infer_ty));
}

// Most types do not introduce any region binders, nor
// involve any other subtle cases, and so the WF relation
// simply constraints any regions referenced directly by
// the type and then visits the types that are lexically
// contained within. (The comments refer to relevant rules
// from RFC1214.)
ty::view::Bool | // OutlivesScalar
ty::view::Char | // OutlivesScalar
ty::view::Int(..) | // OutlivesScalar
ty::view::Uint(..) | // OutlivesScalar
ty::view::Float(..) | // OutlivesScalar
ty::view::Never | // ...
ty::view::Adt(..) | // OutlivesNominalType
ty::view::Opaque(..) | // OutlivesNominalType (ish)
ty::view::Foreign(..) | // OutlivesNominalType
ty::view::Str | // OutlivesScalar (ish)
ty::view::Array(..) | // ...
ty::view::Slice(..) | // ...
ty::view::RawPtr(..) | // ...
ty::view::Ref(..) | // OutlivesReference
ty::view::Tuple(..) | // ...
ty::view::FnDef(..) | // OutlivesFunction (*)
ty::view::FnPtr(_) | // OutlivesFunction (*)
ty::view::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
ty::view::Placeholder(..) |
ty::view::Bound(..) |
ty::view::Error => {
// (*) Bare functions and traits are both binders. In the
// RFC, this means we would add the bound regions to the
// "bound regions list". In our representation, no such
// list is maintained explicitly, because bound regions
// themselves can be readily identified.

push_region_constraints(ty, out);
for subty in ty.walk_shallow() {
compute_components(tcx, subty, out);
}
// Most types do not introduce any region binders, nor
// involve any other subtle cases, and so the WF relation
// simply constraints any regions referenced directly by
// the type and then visits the types that are lexically
// contained within. (The comments refer to relevant rules
// from RFC1214.)
ty::view::Bool | // OutlivesScalar
ty::view::Char | // OutlivesScalar
ty::view::Int(..) | // OutlivesScalar
ty::view::Uint(..) | // OutlivesScalar
ty::view::Float(..) | // OutlivesScalar
ty::view::Never | // ...
ty::view::Adt(..) | // OutlivesNominalType
ty::view::Opaque(..) | // OutlivesNominalType (ish)
ty::view::Foreign(..) | // OutlivesNominalType
ty::view::Str | // OutlivesScalar (ish)
ty::view::Array(..) | // ...
ty::view::Slice(..) | // ...
ty::view::RawPtr(..) | // ...
ty::view::Ref(..) | // OutlivesReference
ty::view::Tuple(..) | // ...
ty::view::FnDef(..) | // OutlivesFunction (*)
ty::view::FnPtr(_) | // OutlivesFunction (*)
ty::view::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
ty::view::Placeholder(..) |
ty::view::Bound(..) |
ty::view::Error => {
// (*) Bare functions and traits are both binders. In the
// RFC, this means we would add the bound regions to the
// "bound regions list". In our representation, no such
// list is maintained explicitly, because bound regions
// themselves can be readily identified.

push_region_constraints(ty, out);
for subty in ty.walk_shallow() {
compute_components(tcx, subty, out);
}
}
}
}

fn capture_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Vec<Component<'tcx>> {
Expand Down
5 changes: 0 additions & 5 deletions src/librustc_data_structures/captures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,3 @@
pub trait Captures<'a> {}

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

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

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

0 comments on commit fba7f77

Please sign in to comment.