diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-06-08 21:04:03 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-06-26 10:49:24 -0400 |
| commit | 3f1961d62e166cfe71273175296d9d59222ca81c (patch) | |
| tree | 3673c9fda79c90c2718dbd04c1321445fefd1658 | |
| parent | 7cb86ed1e360be8a978e6e4c891c01bc1d8deaaa (diff) | |
| download | rust-3f1961d62e166cfe71273175296d9d59222ca81c.tar.gz rust-3f1961d62e166cfe71273175296d9d59222ca81c.zip | |
extract type-ops into their own submodules
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) + } +} |
