diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-06-06 09:47:28 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-06-26 10:31:49 -0400 |
| commit | 214d7650c91e777c445a8ef0733c8553e34b2658 (patch) | |
| tree | 3e838837fd9de8d141be3816ce7dfe9b897f9fa0 /src | |
| parent | 7c62461c39d5cf8899d419be77a0ec48dd9f14bc (diff) | |
| download | rust-214d7650c91e777c445a8ef0733c8553e34b2658.tar.gz rust-214d7650c91e777c445a8ef0733c8553e34b2658.zip | |
introduce `prove_predicates` type op
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/type_check/mod.rs | 34 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/type_check/type_op.rs | 62 |
2 files changed, 65 insertions, 31 deletions
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 7a405f0a709..5e9b3ad5054 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -28,7 +28,7 @@ use rustc::mir::tcx::PlaceTy; use rustc::mir::visit::{PlaceContext, Visitor}; use rustc::mir::*; use rustc::traits::query::NoSolution; -use rustc::traits::{self, ObligationCause, Normalized, TraitEngine}; +use rustc::traits::{ObligationCause, Normalized, TraitEngine}; use rustc::ty::error::TypeError; use rustc::ty::fold::TypeFoldable; use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeVariants}; @@ -833,7 +833,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { self.fully_perform_op( locations, || format!("eq_types({:?} = {:?})", a, b), - type_op::Eq::new(b, a) + type_op::Eq::new(b, a), ) } @@ -1590,27 +1590,17 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { ); } - fn prove_predicates<T>(&mut self, predicates: T, location: Location) - where - T: IntoIterator<Item = ty::Predicate<'tcx>> + Clone, - { - let cause = ObligationCause::dummy(); - let obligations: Vec<_> = predicates - .into_iter() - .map(|p| traits::Obligation::new(cause.clone(), self.param_env, p)) - .collect(); - - // Micro-optimization - if obligations.is_empty() { - return; - } - + fn prove_predicates( + &mut self, + predicates: impl IntoIterator<Item = ty::Predicate<'tcx>> + Clone, + location: Location, + ) { // This intermediate vector is mildly unfortunate, in that we // sometimes create it even when logging is disabled, but only // if debug-info is enabled, and I doubt it is actually // expensive. -nmatsakis let predicates_vec: Vec<_> = if cfg!(debug_assertions) { - obligations.iter().map(|o| o.predicate).collect() + predicates.clone().into_iter().collect() } else { Vec::new() }; @@ -1620,15 +1610,11 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { predicates_vec, location, ); + let param_env = self.param_env; self.fully_perform_op( location.at_self(), || format!("prove_predicates({:?})", predicates_vec), - CustomTypeOp::new(|_this| { - Ok(InferOk { - value: (), - obligations, - }) - }), + type_op::ProvePredicates::new(param_env, predicates), ).unwrap() } diff --git a/src/librustc_mir/borrow_check/nll/type_check/type_op.rs b/src/librustc_mir/borrow_check/nll/type_check/type_op.rs index 97453231273..0b35f3501fc 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/type_op.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/type_op.rs @@ -9,9 +9,9 @@ // except according to those terms. use borrow_check::nll::type_check::TypeChecker; -use rustc::infer::InferResult; -use rustc::traits::ObligationCause; -use rustc::ty::Ty; +use rustc::infer::{InferOk, InferResult}; +use rustc::traits::{Obligation, ObligationCause, PredicateObligation}; +use rustc::ty::{ParamEnv, Predicate, Ty}; pub(super) trait TypeOp<'gcx, 'tcx> { type Output; @@ -75,8 +75,12 @@ impl<'gcx, 'tcx> TypeOp<'gcx, 'tcx> for Subtype<'tcx> { } } - fn perform(self, type_checker: &mut TypeChecker<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> { - type_checker.infcx + fn perform( + self, + type_checker: &mut TypeChecker<'_, 'gcx, 'tcx>, + ) -> InferResult<'tcx, Self::Output> { + type_checker + .infcx .at(&ObligationCause::dummy(), type_checker.param_env) .sup(self.sup, self.sub) } @@ -104,9 +108,53 @@ impl<'gcx, 'tcx> TypeOp<'gcx, 'tcx> for Eq<'tcx> { } } - fn perform(self, type_checker: &mut TypeChecker<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> { - type_checker.infcx + fn perform( + self, + type_checker: &mut TypeChecker<'_, 'gcx, 'tcx>, + ) -> InferResult<'tcx, Self::Output> { + type_checker + .infcx .at(&ObligationCause::dummy(), type_checker.param_env) .eq(self.a, self.b) } } + +pub(super) struct ProvePredicates<'tcx> { + obligations: Vec<PredicateObligation<'tcx>>, +} + +impl<'tcx> ProvePredicates<'tcx> { + pub(super) fn new( + param_env: ParamEnv<'tcx>, + predicates: impl IntoIterator<Item = Predicate<'tcx>>, + ) -> Self { + ProvePredicates { + obligations: predicates + .into_iter() + .map(|p| Obligation::new(ObligationCause::dummy(), param_env, p)) + .collect(), + } + } +} + +impl<'gcx, 'tcx> TypeOp<'gcx, 'tcx> for ProvePredicates<'tcx> { + type Output = (); + + fn trivial_noop(&self) -> Option<Self::Output> { + if self.obligations.is_empty() { + Some(()) + } else { + None + } + } + + fn perform( + self, + _type_checker: &mut TypeChecker<'_, 'gcx, 'tcx>, + ) -> InferResult<'tcx, Self::Output> { + Ok(InferOk { + value: (), + obligations: self.obligations, + }) + } +} |
