about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs25
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/type_op.rs29
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)
         }
     }