diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index 752c2cc410f81..daa48b96ae856 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -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: @@ -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 @@ -176,8 +171,6 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { &self, compare_ty: impl Fn(Ty<'tcx>) -> bool, ) -> Vec, 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 diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 32bc3844d0d2a..8fc24bbcd95ef 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -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]) } } diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index 862f49d18c65a..51679ff1b19d1 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -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 - // `>::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 + // `>::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> { diff --git a/src/librustc_data_structures/captures.rs b/src/librustc_data_structures/captures.rs index ea2452187ee97..1e90aa6945b2d 100644 --- a/src/librustc_data_structures/captures.rs +++ b/src/librustc_data_structures/captures.rs @@ -8,8 +8,3 @@ pub trait Captures<'a> {} impl Captures<'_> for T {} - -#[allow(unused_lifetimes)] -pub trait Captures2<'a, 'b> {} - -impl Captures2<'_, '_> for T {}