1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use rustc::infer::canonical::{Canonical, QueryResult};
use rustc::infer::InferCtxt;
use rustc::traits::query::type_op::eq::Eq;
use rustc::traits::query::type_op::normalize::Normalize;
use rustc::traits::query::type_op::prove_predicate::ProvePredicate;
use rustc::traits::query::type_op::subtype::Subtype;
use rustc::traits::query::{Fallible, NoSolution};
use rustc::traits::{FulfillmentContext, Normalized, Obligation, ObligationCause, TraitEngine,
TraitEngineExt};
use rustc::ty::query::Providers;
use rustc::ty::{FnSig, Lift, ParamEnvAnd, PolyFnSig, Predicate, Ty, TyCtxt, TypeFoldable};
use rustc_data_structures::sync::Lrc;
use std::fmt;
crate fn provide(p: &mut Providers) {
*p = Providers {
type_op_eq,
type_op_prove_predicate,
type_op_subtype,
type_op_normalize_ty,
type_op_normalize_predicate,
type_op_normalize_fn_sig,
type_op_normalize_poly_fn_sig,
..*p
};
}
fn type_op_eq<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> {
tcx.infer_ctxt()
.enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
let (param_env, Eq { a, b }) = key.into_parts();
Ok(infcx
.at(&ObligationCause::dummy(), param_env)
.eq(a, b)?
.into_value_registering_obligations(infcx, fulfill_cx))
})
}
fn type_op_normalize<T>(
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
fulfill_cx: &mut FulfillmentContext<'tcx>,
key: ParamEnvAnd<'tcx, Normalize<T>>,
) -> Fallible<T>
where
T: fmt::Debug + TypeFoldable<'tcx> + Lift<'gcx>,
{
let (param_env, Normalize { value }) = key.into_parts();
let Normalized { value, obligations } = infcx
.at(&ObligationCause::dummy(), param_env)
.normalize(&value)?;
fulfill_cx.register_predicate_obligations(infcx, obligations);
Ok(value)
}
fn type_op_normalize_ty(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Ty<'tcx>>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, Ty<'tcx>>>>, NoSolution> {
tcx.infer_ctxt()
.enter_canonical_trait_query(&canonicalized, type_op_normalize)
}
fn type_op_normalize_predicate(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Predicate<'tcx>>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, Predicate<'tcx>>>>, NoSolution> {
tcx.infer_ctxt()
.enter_canonical_trait_query(&canonicalized, type_op_normalize)
}
fn type_op_normalize_fn_sig(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<FnSig<'tcx>>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, FnSig<'tcx>>>>, NoSolution> {
tcx.infer_ctxt()
.enter_canonical_trait_query(&canonicalized, type_op_normalize)
}
fn type_op_normalize_poly_fn_sig(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<PolyFnSig<'tcx>>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, PolyFnSig<'tcx>>>>, NoSolution> {
tcx.infer_ctxt()
.enter_canonical_trait_query(&canonicalized, type_op_normalize)
}
fn type_op_subtype<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Subtype<'tcx>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> {
tcx.infer_ctxt()
.enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
let (param_env, Subtype { sub, sup }) = key.into_parts();
Ok(infcx
.at(&ObligationCause::dummy(), param_env)
.sup(sup, sub)?
.into_value_registering_obligations(infcx, fulfill_cx))
})
}
fn type_op_prove_predicate<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>,
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> {
tcx.infer_ctxt()
.enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
let (param_env, ProvePredicate { predicate }) = key.into_parts();
fulfill_cx.register_predicate_obligation(
infcx,
Obligation::new(ObligationCause::dummy(), param_env, predicate),
);
Ok(())
})
}