提交 2a0b3d62 编写于 作者: N Niko Matsakis

introduce `Normalizable` trait for things directly normalizable

上级 de7e941e
......@@ -72,9 +72,10 @@
use syntax_pos::symbol::InternedString;
use traits::query::{
CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal,
CanonicalPredicateGoal, CanonicalTypeOpProvePredicateGoal,
CanonicalPredicateGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal,
};
use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty};
use ty::{TyCtxt, FnSig, Instance, InstanceDef,
ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty};
use ty::subst::Substs;
// erase!() just makes tokens go away. It's used to specify which macro argument
......@@ -652,6 +653,10 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
[] TypeOpEq(CanonicalTypeOpEqGoal<'tcx>),
[] TypeOpSubtype(CanonicalTypeOpSubtypeGoal<'tcx>),
[] TypeOpProvePredicate(CanonicalTypeOpProvePredicateGoal<'tcx>),
[] TypeOpNormalizeTy(CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>),
[] TypeOpNormalizePredicate(CanonicalTypeOpNormalizeGoal<'tcx, Predicate<'tcx>>),
[] TypeOpNormalizePolyFnSig(CanonicalTypeOpNormalizeGoal<'tcx, PolyFnSig<'tcx>>),
[] TypeOpNormalizeFnSig(CanonicalTypeOpNormalizeGoal<'tcx, FnSig<'tcx>>),
[] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
......
......@@ -41,6 +41,9 @@
pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
Canonical<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>;
pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
Canonical<'tcx, type_op::normalize::Normalize<'tcx, T>>;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct NoSolution;
......
......@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use infer::canonical::{Canonical, CanonicalizedQueryResult};
use infer::canonical::{Canonical, CanonicalizedQueryResult, QueryResult};
use ty::{self, ParamEnv, Ty, TyCtxt};
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
......@@ -45,6 +45,12 @@ fn perform_query(
) -> CanonicalizedQueryResult<'gcx, ()> {
tcx.type_op_eq(canonicalized).unwrap()
}
fn upcast_result(
v: &'a CanonicalizedQueryResult<'gcx, ()>,
) -> &'a Canonical<'tcx, QueryResult<'tcx, ()>> {
v
}
}
BraceStructTypeFoldableImpl! {
......
......@@ -9,15 +9,17 @@
// except according to those terms.
use infer::canonical::query_result;
use infer::canonical::{Canonicalized, CanonicalizedQueryResult, QueryRegionConstraint};
use infer::canonical::{
Canonical, Canonicalized, CanonicalizedQueryResult, QueryRegionConstraint, QueryResult,
};
use infer::{InferCtxt, InferOk, InferResult};
use std::fmt;
use std::rc::Rc;
use syntax::codemap::DUMMY_SP;
use traits::{ObligationCause, TraitEngine};
use ty::error::TypeError;
use ty::fold::TypeFoldable;
use ty::{Lift, ParamEnv, TyCtxt};
use std::fmt;
use std::rc::Rc;
use syntax::codemap::DUMMY_SP;
pub mod custom;
pub mod eq;
......@@ -98,17 +100,12 @@ fn fully_perform_nontrivial(
}
}
type Lifted<'gcx, T> = <T as Lift<'gcx>>::Lifted;
pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>: TypeFoldable<'tcx> + Lift<'gcx> {
type QueryResult: TypeFoldable<'tcx> + Lift<'gcx>;
/// Micro-optimization: returns `Ok(x)` if we can trivially
/// produce the output, else returns `Err(self)` back.
fn trivial_noop(
self,
tcx: TyCtxt<'_, 'gcx, 'tcx>,
) -> Result<Lifted<'gcx, Self::QueryResult>, Self>;
fn trivial_noop(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::QueryResult, Self>;
fn param_env(&self) -> ParamEnv<'tcx>;
......@@ -116,14 +113,24 @@ fn perform_query(
tcx: TyCtxt<'_, 'gcx, 'tcx>,
canonicalized: Canonicalized<'gcx, Self>,
) -> CanonicalizedQueryResult<'gcx, Self::QueryResult>;
/// "Upcasts" a lifted query result (which is in the gcx lifetime)
/// into the tcx lifetime. This is always just an identity cast,
/// but the generic code does't realize it, so we have to push the
/// operation into the impls that know more specifically what
/// `QueryResult` is. This operation would (maybe) be nicer with
/// something like HKTs or GATs, since then we could make
/// `QueryResult` parametric and `'gcx` and `'tcx` etc.
fn upcast_result(
lifted_query_result: &'a CanonicalizedQueryResult<'gcx, Self::QueryResult>,
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self::QueryResult>>;
}
impl<'gcx: 'tcx, 'tcx, Q> TypeOp<'gcx, 'tcx> for Q
where
Q: QueryTypeOp<'gcx, 'tcx>,
Lifted<'gcx, Q::QueryResult>: TypeFoldable<'tcx>,
{
type Output = Lifted<'gcx, Q::QueryResult>;
type Output = Q::QueryResult;
fn trivial_noop(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
QueryTypeOp::trivial_noop(self, tcx)
......@@ -152,7 +159,7 @@ fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::O
&ObligationCause::dummy(),
param_env,
&canonical_var_values,
&canonical_result,
Q::upcast_result(&canonical_result),
)
}
}
......@@ -8,17 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use infer::{InferCtxt, InferOk, InferResult};
use traits::query::NoSolution;
use traits::{Normalized, ObligationCause};
use ty::fold::TypeFoldable;
use ty::{ParamEnv, TyCtxt};
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult};
use std::fmt;
use ty::fold::TypeFoldable;
use ty::{self, Lift, ParamEnv, Ty, TyCtxt};
#[derive(Debug)]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct Normalize<'tcx, T> {
param_env: ParamEnv<'tcx>,
value: T,
pub param_env: ParamEnv<'tcx>,
pub value: T,
}
impl<'tcx, T> Normalize<'tcx, T>
......@@ -30,13 +28,13 @@ pub fn new(param_env: ParamEnv<'tcx>, value: T) -> Self {
}
}
impl<'gcx, 'tcx, T> super::TypeOp<'gcx, 'tcx> for Normalize<'tcx, T>
impl<'gcx: 'tcx, 'tcx, T> super::QueryTypeOp<'gcx, 'tcx> for Normalize<'tcx, T>
where
T: fmt::Debug + TypeFoldable<'tcx>,
T: Normalizable<'gcx, 'tcx>,
{
type Output = T;
type QueryResult = T;
fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<T, Self> {
if !self.value.has_projections() {
Ok(self.value)
} else {
......@@ -44,13 +42,126 @@ fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, 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 })
fn param_env(&self) -> ParamEnv<'tcx> {
self.param_env
}
fn perform_query(
tcx: TyCtxt<'_, 'gcx, 'tcx>,
canonicalized: Canonicalized<'gcx, Self>,
) -> CanonicalizedQueryResult<'gcx, Self::QueryResult> {
T::type_op_method(tcx, canonicalized)
}
fn upcast_result(
v: &'a CanonicalizedQueryResult<'gcx, T>,
) -> &'a Canonical<'tcx, QueryResult<'tcx, T>> {
T::upcast_result(v)
}
}
pub trait Normalizable<'gcx, 'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'gcx> {
fn type_op_method(
tcx: TyCtxt<'_, 'gcx, 'tcx>,
canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>,
) -> CanonicalizedQueryResult<'gcx, Self>;
/// Convert from the `'gcx` (lifted) form of `Self` into the `tcx`
/// form of `Self`.
fn upcast_result(
v: &'a CanonicalizedQueryResult<'gcx, Self>,
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self>>;
}
impl Normalizable<'gcx, 'tcx> for Ty<'tcx>
where
'gcx: 'tcx,
{
fn type_op_method(
tcx: TyCtxt<'_, 'gcx, 'tcx>,
canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>,
) -> CanonicalizedQueryResult<'gcx, Self> {
tcx.type_op_normalize_ty(canonicalized).unwrap()
}
fn upcast_result(
v: &'a CanonicalizedQueryResult<'gcx, Self>,
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self>> {
v
}
}
impl Normalizable<'gcx, 'tcx> for ty::Predicate<'tcx>
where
'gcx: 'tcx,
{
fn type_op_method(
tcx: TyCtxt<'_, 'gcx, 'tcx>,
canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>,
) -> CanonicalizedQueryResult<'gcx, Self> {
tcx.type_op_normalize_predicate(canonicalized).unwrap()
}
fn upcast_result(
v: &'a CanonicalizedQueryResult<'gcx, Self>,
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self>> {
v
}
}
impl Normalizable<'gcx, 'tcx> for ty::PolyFnSig<'tcx>
where
'gcx: 'tcx,
{
fn type_op_method(
tcx: TyCtxt<'_, 'gcx, 'tcx>,
canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>,
) -> CanonicalizedQueryResult<'gcx, Self> {
tcx.type_op_normalize_poly_fn_sig(canonicalized).unwrap()
}
fn upcast_result(
v: &'a CanonicalizedQueryResult<'gcx, Self>,
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self>> {
v
}
}
impl Normalizable<'gcx, 'tcx> for ty::FnSig<'tcx>
where
'gcx: 'tcx,
{
fn type_op_method(
tcx: TyCtxt<'_, 'gcx, 'tcx>,
canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>,
) -> CanonicalizedQueryResult<'gcx, Self> {
tcx.type_op_normalize_fn_sig(canonicalized).unwrap()
}
fn upcast_result(
v: &'a CanonicalizedQueryResult<'gcx, Self>,
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self>> {
v
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for Normalize<'tcx, T> {
param_env,
value,
} where T: TypeFoldable<'tcx>,
}
BraceStructLiftImpl! {
impl<'a, 'tcx, T> Lift<'tcx> for Normalize<'a, T> {
type Lifted = Normalize<'tcx, T::Lifted>;
param_env,
value,
} where T: Lift<'tcx>,
}
impl_stable_hash_for! {
impl<'tcx, T> for struct Normalize<'tcx, T> {
param_env, value
}
}
......@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use infer::canonical::{Canonical, CanonicalizedQueryResult};
use infer::canonical::{Canonical, CanonicalizedQueryResult, QueryResult};
use ty::{ParamEnv, Predicate, TyCtxt};
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
......@@ -18,11 +18,11 @@ pub struct ProvePredicate<'tcx> {
}
impl<'tcx> ProvePredicate<'tcx> {
pub fn new(
param_env: ParamEnv<'tcx>,
predicate: Predicate<'tcx>,
) -> Self {
ProvePredicate { param_env, predicate }
pub fn new(param_env: ParamEnv<'tcx>, predicate: Predicate<'tcx>) -> Self {
ProvePredicate {
param_env,
predicate,
}
}
}
......@@ -43,6 +43,12 @@ fn perform_query(
) -> CanonicalizedQueryResult<'gcx, ()> {
tcx.type_op_prove_predicate(canonicalized).unwrap()
}
fn upcast_result(
v: &'a CanonicalizedQueryResult<'gcx, ()>,
) -> &'a Canonical<'tcx, QueryResult<'tcx, ()>> {
v
}
}
BraceStructTypeFoldableImpl! {
......
......@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use infer::canonical::{Canonical, CanonicalizedQueryResult};
use infer::canonical::{Canonical, CanonicalizedQueryResult, QueryResult};
use ty::{ParamEnv, Ty, TyCtxt};
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
......@@ -49,6 +49,12 @@ fn perform_query(
) -> CanonicalizedQueryResult<'gcx, ()> {
tcx.type_op_subtype(canonicalized).unwrap()
}
fn upcast_result(
v: &'a CanonicalizedQueryResult<'gcx, ()>,
) -> &'a Canonical<'tcx, QueryResult<'tcx, ()>> {
v
}
}
BraceStructTypeFoldableImpl! {
......
......@@ -14,7 +14,7 @@
use mir::interpret::{GlobalId, ConstValue};
use traits::query::{
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal,
CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
};
use ty::{self, ParamEnvAnd, Ty, TyCtxt};
use ty::subst::Substs;
......@@ -123,6 +123,36 @@ fn describe(_tcx: TyCtxt, goal: CanonicalTypeOpProvePredicateGoal<'tcx>) -> Stri
}
}
impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_ty<'tcx> {
fn describe(_tcx: TyCtxt, goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>) -> String {
format!("normalizing `{:?}`", goal)
}
}
impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_predicate<'tcx> {
fn describe(
_tcx: TyCtxt,
goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Predicate<'tcx>>,
) -> String {
format!("normalizing `{:?}`", goal)
}
}
impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_poly_fn_sig<'tcx> {
fn describe(
_tcx: TyCtxt,
goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>>,
) -> String {
format!("normalizing `{:?}`", goal)
}
}
impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_fn_sig<'tcx> {
fn describe(_tcx: TyCtxt, goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>>) -> String {
format!("normalizing `{:?}`", goal)
}
}
impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> {
fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
format!("computing whether `{}` is `Copy`", env.value)
......
......@@ -35,7 +35,7 @@
use traits::{self, Vtable};
use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal,
CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal,
CanonicalTypeOpProvePredicateGoal, NoSolution};
CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal, NoSolution};
use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult};
use traits::query::normalize::NormalizationResult;
use traits::specialization_graph;
......@@ -447,7 +447,7 @@
CanonicalPredicateGoal<'tcx>
) -> Result<traits::EvaluationResult, traits::OverflowError>,
/// Do not call this query directly: invoke `infcx.eq()` instead.
/// Do not call this query directly: part of the `Eq` type-op
[] fn type_op_eq: TypeOpEq(
CanonicalTypeOpEqGoal<'tcx>
) -> Result<
......@@ -455,7 +455,7 @@
NoSolution,
>,
/// Do not call this query directly: invoke `infcx.at().subtype()` instead.
/// Do not call this query directly: part of the `Subtype` type-op
[] fn type_op_subtype: TypeOpSubtype(
CanonicalTypeOpSubtypeGoal<'tcx>
) -> Result<
......@@ -463,7 +463,7 @@
NoSolution,
>,
/// Do not call this query directly: invoke `infcx.at().prove_predicates()` instead.
/// Do not call this query directly: part of the `ProvePredicate` type-op
[] fn type_op_prove_predicate: TypeOpProvePredicate(
CanonicalTypeOpProvePredicateGoal<'tcx>
) -> Result<
......@@ -471,6 +471,38 @@
NoSolution,
>,
/// Do not call this query directly: part of the `Normalize` type-op
[] fn type_op_normalize_ty: TypeOpNormalizeTy(
CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>
) -> Result<
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, Ty<'tcx>>>>,
NoSolution,
>,
/// Do not call this query directly: part of the `Normalize` type-op
[] fn type_op_normalize_predicate: TypeOpNormalizePredicate(
CanonicalTypeOpNormalizeGoal<'tcx, ty::Predicate<'tcx>>
) -> Result<
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ty::Predicate<'tcx>>>>,
NoSolution,
>,
/// Do not call this query directly: part of the `Normalize` type-op
[] fn type_op_normalize_poly_fn_sig: TypeOpNormalizePolyFnSig(
CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>>
) -> Result<
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ty::PolyFnSig<'tcx>>>>,
NoSolution,
>,
/// Do not call this query directly: part of the `Normalize` type-op
[] fn type_op_normalize_fn_sig: TypeOpNormalizeFnSig(
CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>>
) -> Result<
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ty::FnSig<'tcx>>>>,
NoSolution,
>,
[] fn substitute_normalize_and_test_predicates:
substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool,
......
......@@ -1031,6 +1031,10 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::TypeOpEq |
DepKind::TypeOpSubtype |
DepKind::TypeOpProvePredicate |
DepKind::TypeOpNormalizeTy |
DepKind::TypeOpNormalizePredicate |
DepKind::TypeOpNormalizePolyFnSig |
DepKind::TypeOpNormalizeFnSig |
DepKind::SubstituteNormalizeAndTestPredicates |
DepKind::InstanceDefSizeEstimate |
DepKind::ProgramClausesForEnv |
......
......@@ -286,9 +286,10 @@ fn sanitize_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
let instantiated_predicates =
tcx.predicates_of(def_id).instantiate(tcx, substs);
let predicates =
type_checker.normalize(instantiated_predicates.predicates, location);
type_checker.prove_predicates(predicates, location);
type_checker.normalize_and_prove_instantiated_predicates(
instantiated_predicates,
location,
);
}
value.ty
......@@ -1526,9 +1527,7 @@ fn prove_aggregate_predicates(
AggregateKind::Array(_) | AggregateKind::Tuple => ty::InstantiatedPredicates::empty(),
};
let predicates = self.normalize(instantiated_predicates.predicates, location);
debug!("prove_aggregate_predicates: predicates={:?}", predicates);
self.prove_predicates(predicates, location);
self.normalize_and_prove_instantiated_predicates(instantiated_predicates, location);
}
fn prove_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>, location: Location) {
......@@ -1540,12 +1539,22 @@ fn prove_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>, location: Location)
);
}
fn prove_predicates(
fn normalize_and_prove_instantiated_predicates(
&mut self,
predicates: impl IntoIterator<Item = ty::Predicate<'tcx>> + Clone,
instantiated_predicates: ty::InstantiatedPredicates<'tcx>,
location: Location,
) {
for predicate in instantiated_predicates.predicates {
let predicate = self.normalize(predicate, location);
self.prove_predicate(predicate, location);
}
}
fn prove_predicates(
&mut self,
predicates: impl IntoIterator<Item = ty::Predicate<'tcx>>,
location: Location,
) {
for predicate in predicates {
debug!(
"prove_predicates(predicate={:?}, location={:?})",
......@@ -1560,6 +1569,19 @@ fn prove_predicates(
}
}
fn prove_predicate(&mut self, predicate: ty::Predicate<'tcx>, location: Location) {
debug!(
"prove_predicate(predicate={:?}, location={:?})",
predicate, location,
);
let param_env = self.param_env;
self.fully_perform_op(
location.at_self(),
type_op::prove_predicate::ProvePredicate::new(param_env, predicate),
).unwrap()
}
fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
self.last_span = mir.span;
debug!("run_on_mir: {:?}", mir.span);
......@@ -1588,7 +1610,7 @@ fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
fn normalize<T>(&mut self, value: T, location: impl ToLocations) -> T
where
T: fmt::Debug + TypeFoldable<'tcx>,
T: type_op::normalize::Normalizable<'gcx, 'tcx>,
{
debug!("normalize(value={:?}, location={:?})", value, location);
let param_env = self.param_env;
......
......@@ -35,6 +35,7 @@
mod normalize_erasing_regions;
pub mod lowering;
mod type_op_eq;
mod type_op_normalize;
mod type_op_prove_predicate;
mod type_op_subtype;
......@@ -53,6 +54,10 @@ pub fn provide(p: &mut Providers) {
type_op_eq: type_op_eq::type_op_eq,
type_op_prove_predicate: type_op_prove_predicate::type_op_prove_predicate,
type_op_subtype: type_op_subtype::type_op_subtype,
type_op_normalize_ty: type_op_normalize::type_op_normalize_ty,
type_op_normalize_predicate: type_op_normalize::type_op_normalize_predicate,
type_op_normalize_fn_sig: type_op_normalize::type_op_normalize_fn_sig,
type_op_normalize_poly_fn_sig: type_op_normalize::type_op_normalize_poly_fn_sig,
..*p
};
}
// Copyright 2014 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::canonical::{Canonical, QueryResult};
use rustc::infer::InferCtxt;
use rustc::traits::query::type_op::normalize::Normalize;
use rustc::traits::query::NoSolution;
use rustc::traits::{FulfillmentContext, Normalized, ObligationCause};
use rustc::ty::{FnSig, Lift, PolyFnSig, Predicate, Ty, TyCtxt, TypeFoldable};
use rustc_data_structures::sync::Lrc;
use std::fmt;
use syntax::codemap::DUMMY_SP;
fn type_op_normalize<'gcx, 'tcx, T>(
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
canonicalized: Canonical<'tcx, Normalize<'tcx, T>>,
) -> Result<Lrc<Canonical<'gcx, QueryResult<'gcx, <T as Lift<'gcx>>::Lifted>>>, NoSolution>
where
T: fmt::Debug + TypeFoldable<'tcx> + Lift<'gcx>,
{
let (Normalize { param_env, value }, canonical_inference_vars) =
infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonicalized);
let fulfill_cx = &mut FulfillmentContext::new();
let Normalized { value, obligations } = infcx
.at(&ObligationCause::dummy(), param_env)
.normalize(&value)?;
fulfill_cx.register_predicate_obligations(infcx, obligations);
infcx.make_canonicalized_query_result(canonical_inference_vars, value, fulfill_cx)
}
crate fn type_op_normalize_ty<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, Normalize<'tcx, Ty<'tcx>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, Ty<'tcx>>>>, NoSolution> {
tcx.infer_ctxt()
.enter(|ref infcx| type_op_normalize(infcx, canonicalized))
}
crate fn type_op_normalize_predicate<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, Normalize<'tcx, Predicate<'tcx>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, Predicate<'tcx>>>>, NoSolution> {
tcx.infer_ctxt()
.enter(|ref infcx| type_op_normalize(infcx, canonicalized))
}
crate fn type_op_normalize_fn_sig<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, Normalize<'tcx, FnSig<'tcx>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, FnSig<'tcx>>>>, NoSolution> {
tcx.infer_ctxt()
.enter(|ref infcx| type_op_normalize(infcx, canonicalized))
}
crate fn type_op_normalize_poly_fn_sig<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, Normalize<'tcx, PolyFnSig<'tcx>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, PolyFnSig<'tcx>>>>, NoSolution> {
tcx.infer_ctxt()
.enter(|ref infcx| type_op_normalize(infcx, canonicalized))
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册