diff options
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/type_check/mod.rs | 25 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/type_check/type_op.rs | 29 |
2 files changed, 28 insertions, 26 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 d9e3ecb8f85..e6211c4ed7f 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -736,20 +736,21 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { describe_op: impl Fn() -> String, op: impl TypeOp<'gcx, 'tcx, Output = R>, ) -> Result<R, TypeError<'tcx>> { - if let Some(r) = op.trivial_noop() { - return Ok(r); - } - - let (r, opt_data) = self.fully_perform_op_and_get_region_constraint_data( - || format!("{} at {:?}", describe_op(), locations), - op, - )?; + match op.trivial_noop() { + Ok(r) => Ok(r), + Err(op) => { + let (r, opt_data) = self.fully_perform_op_and_get_region_constraint_data( + || format!("{} at {:?}", describe_op(), locations), + op, + )?; + + if let Some(data) = opt_data { + self.push_region_constraints(locations, data); + } - if let Some(data) = opt_data { - self.push_region_constraints(locations, data); + Ok(r) + } } - - Ok(r) } fn push_region_constraints( 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 602abbdd4e7..d85a83ac3fc 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 @@ -13,11 +13,12 @@ use rustc::infer::{InferOk, InferResult}; use rustc::traits::{Obligation, ObligationCause, PredicateObligation}; use rustc::ty::{ParamEnv, Predicate, Ty}; -pub(super) trait TypeOp<'gcx, 'tcx> { +pub(super) trait TypeOp<'gcx, 'tcx>: Sized { type Output; - /// Micro-optimization point: true if this is trivially true. - fn trivial_noop(&self) -> Option<Self::Output>; + /// Micro-optimization: returns `Ok(x)` if we can trivially + /// produce the output, else returns `Err(self)` back. + fn trivial_noop(self) -> Result<Self::Output, Self>; /// Produce a description of the operation for the debug logs. fn perform( @@ -45,8 +46,8 @@ where { type Output = R; - fn trivial_noop(&self) -> Option<Self::Output> { - None + fn trivial_noop(self) -> Result<Self::Output, Self> { + Err(self) } fn perform(self, type_checker: &mut TypeChecker<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R> { @@ -68,11 +69,11 @@ impl<'tcx> Subtype<'tcx> { impl<'gcx, 'tcx> TypeOp<'gcx, 'tcx> for Subtype<'tcx> { type Output = (); - fn trivial_noop(&self) -> Option<Self::Output> { + fn trivial_noop(self) -> Result<Self::Output, Self> { if self.sub == self.sup { - Some(()) + Ok(()) } else { - None + Err(self) } } @@ -101,11 +102,11 @@ impl<'tcx> Eq<'tcx> { impl<'gcx, 'tcx> TypeOp<'gcx, 'tcx> for Eq<'tcx> { type Output = (); - fn trivial_noop(&self) -> Option<Self::Output> { + fn trivial_noop(self) -> Result<Self::Output, Self> { if self.a == self.b { - Some(()) + Ok(()) } else { - None + Err(self) } } @@ -141,11 +142,11 @@ impl<'tcx> ProvePredicates<'tcx> { impl<'gcx, 'tcx> TypeOp<'gcx, 'tcx> for ProvePredicates<'tcx> { type Output = (); - fn trivial_noop(&self) -> Option<Self::Output> { + fn trivial_noop(self) -> Result<Self::Output, Self> { if self.obligations.is_empty() { - Some(()) + Ok(()) } else { - None + Err(self) } } |
