about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-06-08 21:04:03 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-06-26 10:49:24 -0400
commit3f1961d62e166cfe71273175296d9d59222ca81c (patch)
tree3673c9fda79c90c2718dbd04c1321445fefd1658
parent7cb86ed1e360be8a978e6e4c891c01bc1d8deaaa (diff)
downloadrust-3f1961d62e166cfe71273175296d9d59222ca81c.tar.gz
rust-3f1961d62e166cfe71273175296d9d59222ca81c.zip
extract type-ops into their own submodules
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/input_output.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness.rs3
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs8
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/type_op/custom.rs56
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/type_op/eq.rs44
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/type_op/mod.rs240
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/type_op/normalize.rs56
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/type_op/outlives.rs48
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/type_op/predicates.rs51
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/type_op/subtype.rs48
10 files changed, 323 insertions, 233 deletions
diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
index 8144641a5ef..a127128818e 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
@@ -18,7 +18,7 @@
 //! contain revealed `impl Trait` values).
 
 use borrow_check::nll::renumber;
-use borrow_check::nll::type_check::type_op::CustomTypeOp;
+use borrow_check::nll::type_check::type_op::custom::CustomTypeOp;
 use borrow_check::nll::universal_regions::UniversalRegions;
 use rustc::hir::def_id::DefId;
 use rustc::infer::InferOk;
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
index 37898adeb92..78026993091 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 use borrow_check::nll::region_infer::Cause;
-use borrow_check::nll::type_check::type_op::{DropckOutlives, TypeOp};
+use borrow_check::nll::type_check::type_op::TypeOp;
+use borrow_check::nll::type_check::type_op::outlives::DropckOutlives;
 use borrow_check::nll::type_check::AtLocation;
 use dataflow::move_paths::{HasMoveData, MoveData};
 use dataflow::MaybeInitializedPlaces;
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 92ee1f2a892..d7812d86574 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -776,12 +776,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         locations: Locations,
     ) -> UnitResult<'tcx> {
         let param_env = self.param_env;
-        self.fully_perform_op(locations, type_op::Subtype::new(param_env, sub, sup))
+        self.fully_perform_op(locations, type_op::subtype::Subtype::new(param_env, sub, sup))
     }
 
     fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> UnitResult<'tcx> {
         let param_env = self.param_env;
-        self.fully_perform_op(locations, type_op::Eq::new(param_env, b, a))
+        self.fully_perform_op(locations, type_op::eq::Eq::new(param_env, b, a))
     }
 
     fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
@@ -1560,7 +1560,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         let param_env = self.param_env;
         self.fully_perform_op(
             location.at_self(),
-            type_op::ProvePredicates::new(param_env, predicates),
+            type_op::predicates::ProvePredicates::new(param_env, predicates),
         ).unwrap()
     }
 
@@ -1598,7 +1598,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         let param_env = self.param_env;
         self.fully_perform_op(
             location.to_locations(),
-            type_op::Normalize::new(param_env, value),
+            type_op::normalize::Normalize::new(param_env, value),
         ).unwrap()
     }
 }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/type_op/custom.rs b/src/librustc_mir/borrow_check/nll/type_check/type_op/custom.rs
new file mode 100644
index 00000000000..ce17cab8dcb
--- /dev/null
+++ b/src/librustc_mir/borrow_check/nll/type_check/type_op/custom.rs
@@ -0,0 +1,56 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rustc::infer::{InferCtxt, InferResult};
+use rustc::ty::TyCtxt;
+use std::fmt;
+
+crate struct CustomTypeOp<F, G> {
+    closure: F,
+    description: G,
+}
+
+impl<F, G> CustomTypeOp<F, G> {
+    crate fn new<'gcx, 'tcx, R>(closure: F, description: G) -> Self
+    where
+        F: FnOnce(&InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R>,
+        G: Fn() -> String,
+    {
+        CustomTypeOp {
+            closure,
+            description,
+        }
+    }
+}
+
+impl<'gcx, 'tcx, F, R, G> super::TypeOp<'gcx, 'tcx> for CustomTypeOp<F, G>
+where
+    F: FnOnce(&InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R>,
+    G: Fn() -> String,
+{
+    type Output = R;
+
+    fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
+        Err(self)
+    }
+
+    fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R> {
+        (self.closure)(infcx)
+    }
+}
+
+impl<F, G> fmt::Debug for CustomTypeOp<F, G>
+where
+    G: Fn() -> String,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", (self.description)())
+    }
+}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/type_op/eq.rs b/src/librustc_mir/borrow_check/nll/type_check/type_op/eq.rs
new file mode 100644
index 00000000000..b062eff0733
--- /dev/null
+++ b/src/librustc_mir/borrow_check/nll/type_check/type_op/eq.rs
@@ -0,0 +1,44 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rustc::infer::{InferCtxt, InferResult};
+use rustc::traits::ObligationCause;
+use rustc::ty::{ParamEnv, Ty, TyCtxt};
+
+#[derive(Debug)]
+crate struct Eq<'tcx> {
+    param_env: ParamEnv<'tcx>,
+    a: Ty<'tcx>,
+    b: Ty<'tcx>,
+}
+
+impl<'tcx> Eq<'tcx> {
+    crate fn new(param_env: ParamEnv<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> Self {
+        Self { param_env, a, b }
+    }
+}
+
+impl<'gcx, 'tcx> super::TypeOp<'gcx, 'tcx> for Eq<'tcx> {
+    type Output = ();
+
+    fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
+        if self.a == self.b {
+            Ok(())
+        } else {
+            Err(self)
+        }
+    }
+
+    fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
+        infcx
+            .at(&ObligationCause::dummy(), self.param_env)
+            .eq(self.a, self.b)
+    }
+}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/type_op/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/type_op/mod.rs
index da8d17767af..448dfd853c1 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/type_op/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/type_op/mod.rs
@@ -11,17 +11,20 @@
 use rustc::infer::canonical::query_result;
 use rustc::infer::canonical::QueryRegionConstraint;
 use rustc::infer::{InferCtxt, InferOk, InferResult};
-use rustc::traits::query::dropck_outlives::trivial_dropck_outlives;
-use rustc::traits::query::NoSolution;
-use rustc::traits::{Normalized, Obligation, ObligationCause, PredicateObligation, TraitEngine};
+use rustc::traits::{ObligationCause, TraitEngine};
 use rustc::ty::error::TypeError;
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::Kind;
-use rustc::ty::{ParamEnv, Predicate, Ty, TyCtxt};
+use rustc::ty::TyCtxt;
 use std::fmt;
 use std::rc::Rc;
 use syntax::codemap::DUMMY_SP;
 
+crate mod custom;
+crate mod eq;
+crate mod normalize;
+crate mod predicates;
+crate mod outlives;
+crate mod subtype;
+
 crate trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
     type Output;
 
@@ -58,7 +61,10 @@ crate trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
         infcx: &InferCtxt<'_, 'gcx, 'tcx>,
     ) -> Result<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>), TypeError<'tcx>> {
         if cfg!(debug_assertions) {
-            info!("fully_perform_op_and_get_region_constraint_data({:?})", self);
+            info!(
+                "fully_perform_op_and_get_region_constraint_data({:?})",
+                self
+            );
         }
 
         let mut fulfill_cx = TraitEngine::new(infcx.tcx);
@@ -90,223 +96,3 @@ crate trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
         }
     }
 }
-
-crate struct CustomTypeOp<F, G> {
-    closure: F,
-    description: G,
-}
-
-impl<F, G> CustomTypeOp<F, G> {
-    pub(super) fn new<'gcx, 'tcx, R>(closure: F, description: G) -> Self
-    where
-        F: FnOnce(&InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R>,
-        G: Fn() -> String,
-    {
-        CustomTypeOp {
-            closure,
-            description,
-        }
-    }
-}
-
-impl<'gcx, 'tcx, F, R, G> TypeOp<'gcx, 'tcx> for CustomTypeOp<F, G>
-where
-    F: FnOnce(&InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R>,
-    G: Fn() -> String,
-{
-    type Output = R;
-
-    fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
-        Err(self)
-    }
-
-    fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R> {
-        (self.closure)(infcx)
-    }
-}
-
-impl<F, G> fmt::Debug for CustomTypeOp<F, G>
-where
-    G: Fn() -> String,
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", (self.description)())
-    }
-}
-
-#[derive(Debug)]
-crate struct Subtype<'tcx> {
-    param_env: ParamEnv<'tcx>,
-    sub: Ty<'tcx>,
-    sup: Ty<'tcx>,
-}
-
-impl<'tcx> Subtype<'tcx> {
-    crate fn new(param_env: ParamEnv<'tcx>, sub: Ty<'tcx>, sup: Ty<'tcx>) -> Self {
-        Self {
-            param_env,
-            sub,
-            sup,
-        }
-    }
-}
-
-impl<'gcx, 'tcx> TypeOp<'gcx, 'tcx> for Subtype<'tcx> {
-    type Output = ();
-
-    fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
-        if self.sub == self.sup {
-            Ok(())
-        } else {
-            Err(self)
-        }
-    }
-
-    fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
-        infcx
-            .at(&ObligationCause::dummy(), self.param_env)
-            .sup(self.sup, self.sub)
-    }
-}
-
-#[derive(Debug)]
-crate struct Eq<'tcx> {
-    param_env: ParamEnv<'tcx>,
-    a: Ty<'tcx>,
-    b: Ty<'tcx>,
-}
-
-impl<'tcx> Eq<'tcx> {
-    crate fn new(param_env: ParamEnv<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> Self {
-        Self { param_env, a, b }
-    }
-}
-
-impl<'gcx, 'tcx> TypeOp<'gcx, 'tcx> for Eq<'tcx> {
-    type Output = ();
-
-    fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
-        if self.a == self.b {
-            Ok(())
-        } else {
-            Err(self)
-        }
-    }
-
-    fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
-        infcx
-            .at(&ObligationCause::dummy(), self.param_env)
-            .eq(self.a, self.b)
-    }
-}
-
-#[derive(Debug)]
-crate struct ProvePredicates<'tcx> {
-    obligations: Vec<PredicateObligation<'tcx>>,
-}
-
-impl<'tcx> ProvePredicates<'tcx> {
-    crate 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, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
-        if self.obligations.is_empty() {
-            Ok(())
-        } else {
-            Err(self)
-        }
-    }
-
-    fn perform(self, _infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
-        Ok(InferOk {
-            value: (),
-            obligations: self.obligations,
-        })
-    }
-}
-
-#[derive(Debug)]
-crate struct Normalize<'tcx, T> {
-    param_env: ParamEnv<'tcx>,
-    value: T,
-}
-
-impl<'tcx, T> Normalize<'tcx, T>
-where
-    T: fmt::Debug + TypeFoldable<'tcx>,
-{
-    crate fn new(param_env: ParamEnv<'tcx>, value: T) -> Self {
-        Self { param_env, value }
-    }
-}
-
-impl<'gcx, 'tcx, T> TypeOp<'gcx, 'tcx> for Normalize<'tcx, T>
-where
-    T: fmt::Debug + TypeFoldable<'tcx>,
-{
-    type Output = T;
-
-    fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
-        if !self.value.has_projections() {
-            Ok(self.value)
-        } else {
-            Err(self)
-        }
-    }
-
-    fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
-        let Normalized { value, obligations } = infcx
-            .at(&ObligationCause::dummy(), self.param_env)
-            .normalize(&self.value)
-            .unwrap_or_else(|NoSolution| {
-                bug!("normalization of `{:?}` failed", self.value,);
-            });
-        Ok(InferOk { value, obligations })
-    }
-}
-
-#[derive(Debug)]
-crate struct DropckOutlives<'tcx> {
-    param_env: ParamEnv<'tcx>,
-    dropped_ty: Ty<'tcx>,
-}
-
-impl<'tcx> DropckOutlives<'tcx> {
-    crate fn new(param_env: ParamEnv<'tcx>, dropped_ty: Ty<'tcx>) -> Self {
-        DropckOutlives {
-            param_env,
-            dropped_ty,
-        }
-    }
-}
-
-impl<'gcx, 'tcx> TypeOp<'gcx, 'tcx> for DropckOutlives<'tcx> {
-    type Output = Vec<Kind<'tcx>>;
-
-    fn trivial_noop(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
-        if trivial_dropck_outlives(tcx, self.dropped_ty) {
-            Ok(vec![])
-        } else {
-            Err(self)
-        }
-    }
-
-    fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
-        Ok(infcx
-            .at(&ObligationCause::dummy(), self.param_env)
-            .dropck_outlives(self.dropped_ty))
-    }
-}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/type_op/normalize.rs b/src/librustc_mir/borrow_check/nll/type_check/type_op/normalize.rs
new file mode 100644
index 00000000000..35242a5bc29
--- /dev/null
+++ b/src/librustc_mir/borrow_check/nll/type_check/type_op/normalize.rs
@@ -0,0 +1,56 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rustc::infer::{InferCtxt, InferOk, InferResult};
+use rustc::traits::query::NoSolution;
+use rustc::traits::{Normalized, ObligationCause};
+use rustc::ty::fold::TypeFoldable;
+use rustc::ty::{ParamEnv, TyCtxt};
+use std::fmt;
+
+#[derive(Debug)]
+crate struct Normalize<'tcx, T> {
+    param_env: ParamEnv<'tcx>,
+    value: T,
+}
+
+impl<'tcx, T> Normalize<'tcx, T>
+where
+    T: fmt::Debug + TypeFoldable<'tcx>,
+{
+    crate fn new(param_env: ParamEnv<'tcx>, value: T) -> Self {
+        Self { param_env, value }
+    }
+}
+
+impl<'gcx, 'tcx, T> super::TypeOp<'gcx, 'tcx> for Normalize<'tcx, T>
+where
+    T: fmt::Debug + TypeFoldable<'tcx>,
+{
+    type Output = T;
+
+    fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
+        if !self.value.has_projections() {
+            Ok(self.value)
+        } else {
+            Err(self)
+        }
+    }
+
+    fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
+        let Normalized { value, obligations } = infcx
+            .at(&ObligationCause::dummy(), self.param_env)
+            .normalize(&self.value)
+            .unwrap_or_else(|NoSolution| {
+                bug!("normalization of `{:?}` failed", self.value,);
+            });
+        Ok(InferOk { value, obligations })
+    }
+}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/type_op/outlives.rs b/src/librustc_mir/borrow_check/nll/type_check/type_op/outlives.rs
new file mode 100644
index 00000000000..655ede4793a
--- /dev/null
+++ b/src/librustc_mir/borrow_check/nll/type_check/type_op/outlives.rs
@@ -0,0 +1,48 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rustc::infer::{InferCtxt, InferResult};
+use rustc::traits::query::dropck_outlives::trivial_dropck_outlives;
+use rustc::traits::ObligationCause;
+use rustc::ty::subst::Kind;
+use rustc::ty::{ParamEnv, Ty, TyCtxt};
+
+#[derive(Debug)]
+crate struct DropckOutlives<'tcx> {
+    param_env: ParamEnv<'tcx>,
+    dropped_ty: Ty<'tcx>,
+}
+
+impl<'tcx> DropckOutlives<'tcx> {
+    crate fn new(param_env: ParamEnv<'tcx>, dropped_ty: Ty<'tcx>) -> Self {
+        DropckOutlives {
+            param_env,
+            dropped_ty,
+        }
+    }
+}
+
+impl<'gcx, 'tcx> super::TypeOp<'gcx, 'tcx> for DropckOutlives<'tcx> {
+    type Output = Vec<Kind<'tcx>>;
+
+    fn trivial_noop(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
+        if trivial_dropck_outlives(tcx, self.dropped_ty) {
+            Ok(vec![])
+        } else {
+            Err(self)
+        }
+    }
+
+    fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
+        Ok(infcx
+            .at(&ObligationCause::dummy(), self.param_env)
+            .dropck_outlives(self.dropped_ty))
+    }
+}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/type_op/predicates.rs b/src/librustc_mir/borrow_check/nll/type_check/type_op/predicates.rs
new file mode 100644
index 00000000000..18128d2234e
--- /dev/null
+++ b/src/librustc_mir/borrow_check/nll/type_check/type_op/predicates.rs
@@ -0,0 +1,51 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rustc::infer::{InferCtxt, InferOk, InferResult};
+use rustc::traits::{Obligation, ObligationCause, PredicateObligation};
+use rustc::ty::{ParamEnv, Predicate, TyCtxt};
+
+#[derive(Debug)]
+crate struct ProvePredicates<'tcx> {
+    obligations: Vec<PredicateObligation<'tcx>>,
+}
+
+impl<'tcx> ProvePredicates<'tcx> {
+    crate 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> super::TypeOp<'gcx, 'tcx> for ProvePredicates<'tcx> {
+    type Output = ();
+
+    fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
+        if self.obligations.is_empty() {
+            Ok(())
+        } else {
+            Err(self)
+        }
+    }
+
+    fn perform(self, _infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
+        Ok(InferOk {
+            value: (),
+            obligations: self.obligations,
+        })
+    }
+}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/type_op/subtype.rs b/src/librustc_mir/borrow_check/nll/type_check/type_op/subtype.rs
new file mode 100644
index 00000000000..83cc3c7d09b
--- /dev/null
+++ b/src/librustc_mir/borrow_check/nll/type_check/type_op/subtype.rs
@@ -0,0 +1,48 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rustc::infer::{InferCtxt, InferResult};
+use rustc::traits::ObligationCause;
+use rustc::ty::{ParamEnv, Ty, TyCtxt};
+
+#[derive(Debug)]
+crate struct Subtype<'tcx> {
+    param_env: ParamEnv<'tcx>,
+    sub: Ty<'tcx>,
+    sup: Ty<'tcx>,
+}
+
+impl<'tcx> Subtype<'tcx> {
+    crate fn new(param_env: ParamEnv<'tcx>, sub: Ty<'tcx>, sup: Ty<'tcx>) -> Self {
+        Self {
+            param_env,
+            sub,
+            sup,
+        }
+    }
+}
+
+impl<'gcx, 'tcx> super::TypeOp<'gcx, 'tcx> for Subtype<'tcx> {
+    type Output = ();
+
+    fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
+        if self.sub == self.sup {
+            Ok(())
+        } else {
+            Err(self)
+        }
+    }
+
+    fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
+        infcx
+            .at(&ObligationCause::dummy(), self.param_env)
+            .sup(self.sup, self.sub)
+    }
+}