1 use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; 2 use crate::traits::ObligationCtxt; 3 use rustc_middle::traits::query::NoSolution; 4 use rustc_middle::traits::ObligationCause; 5 use rustc_middle::ty::fold::TypeFoldable; 6 use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; 7 use std::fmt; 8 9 pub use rustc_middle::traits::query::type_op::Normalize; 10 11 impl<'tcx, T> super::QueryTypeOp<'tcx> for Normalize<T> 12 where 13 T: Normalizable<'tcx> + 'tcx, 14 { 15 type QueryResponse = T; 16 try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T>17 fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> { 18 if !key.value.value.has_projections() { Some(key.value.value) } else { None } 19 } 20 perform_query( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution>21 fn perform_query( 22 tcx: TyCtxt<'tcx>, 23 canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, 24 ) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> { 25 T::type_op_method(tcx, canonicalized) 26 } 27 perform_locally_in_new_solver( ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Self>, ) -> Result<Self::QueryResponse, NoSolution>28 fn perform_locally_in_new_solver( 29 ocx: &ObligationCtxt<'_, 'tcx>, 30 key: ParamEnvAnd<'tcx, Self>, 31 ) -> Result<Self::QueryResponse, NoSolution> { 32 // FIXME(-Ztrait-solver=next): shouldn't be using old normalizer 33 Ok(ocx.normalize(&ObligationCause::dummy(), key.param_env, key.value.value)) 34 } 35 } 36 37 pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx> + Copy { type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>38 fn type_op_method( 39 tcx: TyCtxt<'tcx>, 40 canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, 41 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>; 42 } 43 44 impl<'tcx> Normalizable<'tcx> for Ty<'tcx> { type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>45 fn type_op_method( 46 tcx: TyCtxt<'tcx>, 47 canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, 48 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> { 49 tcx.type_op_normalize_ty(canonicalized) 50 } 51 } 52 53 impl<'tcx> Normalizable<'tcx> for ty::Clause<'tcx> { type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>54 fn type_op_method( 55 tcx: TyCtxt<'tcx>, 56 canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, 57 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> { 58 tcx.type_op_normalize_clause(canonicalized) 59 } 60 } 61 62 impl<'tcx> Normalizable<'tcx> for ty::PolyFnSig<'tcx> { type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>63 fn type_op_method( 64 tcx: TyCtxt<'tcx>, 65 canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, 66 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> { 67 tcx.type_op_normalize_poly_fn_sig(canonicalized) 68 } 69 } 70 71 impl<'tcx> Normalizable<'tcx> for ty::FnSig<'tcx> { type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>72 fn type_op_method( 73 tcx: TyCtxt<'tcx>, 74 canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, 75 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> { 76 tcx.type_op_normalize_fn_sig(canonicalized) 77 } 78 } 79