Skip to main content

rustc_trait_selection/traits/query/type_op/
normalize.rs

1use std::fmt;
2
3use rustc_middle::traits::ObligationCause;
4use rustc_middle::traits::query::NoSolution;
5pub use rustc_middle::traits::query::type_op::Normalize;
6use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
7use rustc_span::Span;
8
9use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse};
10use crate::traits::ObligationCtxt;
11
12impl<'tcx, T> super::QueryTypeOp<'tcx> for Normalize<'tcx, T>
13where
14    T: Normalizable<'tcx> + 'tcx,
15{
16    type QueryResponse = T;
17
18    fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
19        if !key.value.value.skip_normalization().has_aliases() {
20            Some(key.value.value.skip_normalization())
21        } else {
22            None
23        }
24    }
25
26    fn perform_query(
27        tcx: TyCtxt<'tcx>,
28        canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
29    ) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
30        T::type_op_method(tcx, canonicalized)
31    }
32
33    fn perform_locally_with_next_solver(
34        ocx: &ObligationCtxt<'_, 'tcx>,
35        key: ParamEnvAnd<'tcx, Self>,
36        span: Span,
37    ) -> Result<Self::QueryResponse, NoSolution> {
38        ocx.deeply_normalize(
39            &ObligationCause::dummy_with_span(span),
40            key.param_env,
41            key.value.value,
42        )
43        .map_err(|_| NoSolution)
44    }
45}
46
47pub trait Normalizable<'tcx>:
48    fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<TyCtxt<'tcx>> + Copy
49{
50    fn type_op_method(
51        tcx: TyCtxt<'tcx>,
52        canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
53    ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>;
54}
55
56impl<'tcx> Normalizable<'tcx> for Ty<'tcx> {
57    fn type_op_method(
58        tcx: TyCtxt<'tcx>,
59        canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
60    ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
61        tcx.type_op_normalize_ty(canonicalized)
62    }
63}
64
65impl<'tcx> Normalizable<'tcx> for ty::Clause<'tcx> {
66    fn type_op_method(
67        tcx: TyCtxt<'tcx>,
68        canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
69    ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
70        tcx.type_op_normalize_clause(canonicalized)
71    }
72}
73
74impl<'tcx> Normalizable<'tcx> for ty::PolyFnSig<'tcx> {
75    fn type_op_method(
76        tcx: TyCtxt<'tcx>,
77        canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
78    ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
79        tcx.type_op_normalize_poly_fn_sig(canonicalized)
80    }
81}
82
83impl<'tcx> Normalizable<'tcx> for ty::FnSig<'tcx> {
84    fn type_op_method(
85        tcx: TyCtxt<'tcx>,
86        canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
87    ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
88        tcx.type_op_normalize_fn_sig(canonicalized)
89    }
90}
91
92/// This impl is not needed, since we never normalize type outlives predicates
93/// in the old solver, but is required by trait bounds to be happy.
94impl<'tcx> Normalizable<'tcx> for ty::PolyTypeOutlivesPredicate<'tcx> {
95    fn type_op_method(
96        _tcx: TyCtxt<'tcx>,
97        _canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
98    ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
99        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("we never normalize PolyTypeOutlivesPredicate")));
}unreachable!("we never normalize PolyTypeOutlivesPredicate")
100    }
101}