Skip to main content

rustc_traits/
type_op.rs

1use std::fmt;
2
3use rustc_infer::infer::TyCtxtInferExt;
4use rustc_infer::infer::canonical::{Canonical, CanonicalQueryInput, QueryResponse};
5use rustc_middle::query::Providers;
6use rustc_middle::traits::query::NoSolution;
7use rustc_middle::ty::{Clause, FnSig, ParamEnvAnd, PolyFnSig, Ty, TyCtxt, TypeFoldable};
8use rustc_span::DUMMY_SP;
9use rustc_trait_selection::infer::InferCtxtBuilderExt;
10use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
11use rustc_trait_selection::traits::query::type_op::ascribe_user_type::{
12    AscribeUserType, type_op_ascribe_user_type_with_span,
13};
14use rustc_trait_selection::traits::query::type_op::normalize::Normalize;
15use rustc_trait_selection::traits::query::type_op::prove_predicate::{
16    ProvePredicate, type_op_prove_predicate_with_cause,
17};
18use rustc_trait_selection::traits::{Normalized, ObligationCause, ObligationCtxt};
19
20pub(crate) fn provide(p: &mut Providers) {
21    *p = Providers {
22        type_op_ascribe_user_type,
23        type_op_prove_predicate,
24        type_op_normalize_ty,
25        type_op_normalize_clause,
26        type_op_normalize_fn_sig,
27        type_op_normalize_poly_fn_sig,
28        ..*p
29    };
30}
31
32fn type_op_ascribe_user_type<'tcx>(
33    tcx: TyCtxt<'tcx>,
34    canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>,
35) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> {
36    tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| {
37        type_op_ascribe_user_type_with_span(ocx, key, DUMMY_SP)
38    })
39}
40
41fn type_op_normalize<'tcx, T>(
42    ocx: &ObligationCtxt<'_, 'tcx>,
43    key: ParamEnvAnd<'tcx, Normalize<'tcx, T>>,
44) -> Result<T, NoSolution>
45where
46    T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>,
47{
48    let ParamEnvAnd { param_env, value: Normalize { value } } = key;
49    let Normalized { value, obligations } = ocx
50        .infcx
51        .at(&ObligationCause::dummy(), param_env)
52        .query_normalize(value.skip_normalization())?;
53    ocx.register_obligations(obligations);
54    Ok(value)
55}
56
57fn type_op_normalize_ty<'tcx>(
58    tcx: TyCtxt<'tcx>,
59    canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Ty<'tcx>>>>,
60) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, NoSolution> {
61    tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize)
62}
63
64fn type_op_normalize_clause<'tcx>(
65    tcx: TyCtxt<'tcx>,
66    canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Clause<'tcx>>>>,
67) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, Clause<'tcx>>>, NoSolution> {
68    tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize)
69}
70
71fn type_op_normalize_fn_sig<'tcx>(
72    tcx: TyCtxt<'tcx>,
73    canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, FnSig<'tcx>>>>,
74) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, FnSig<'tcx>>>, NoSolution> {
75    tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize)
76}
77
78fn type_op_normalize_poly_fn_sig<'tcx>(
79    tcx: TyCtxt<'tcx>,
80    canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, PolyFnSig<'tcx>>>>,
81) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, PolyFnSig<'tcx>>>, NoSolution> {
82    tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize)
83}
84
85fn type_op_prove_predicate<'tcx>(
86    tcx: TyCtxt<'tcx>,
87    canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>,
88) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> {
89    tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| {
90        type_op_prove_predicate_with_cause(ocx, key, ObligationCause::dummy());
91        Ok(())
92    })
93}