8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use infer:: canonical:: {
12
- Canonical , Canonicalized , CanonicalizedQueryResult , QueryRegionConstraint , QueryResult ,
13
- } ;
11
+ use infer:: canonical:: { Canonical , Canonicalized , CanonicalizedQueryResult , QueryRegionConstraint ,
12
+ QueryResult } ;
14
13
use infer:: { InferCtxt , InferOk } ;
15
14
use std:: fmt;
16
15
use std:: rc:: Rc ;
17
16
use traits:: query:: Fallible ;
18
17
use traits:: ObligationCause ;
19
18
use ty:: fold:: TypeFoldable ;
20
- use ty:: { Lift , ParamEnv , TyCtxt } ;
19
+ use ty:: { Lift , ParamEnvAnd , TyCtxt } ;
21
20
22
21
pub mod custom;
23
22
pub mod eq;
24
23
pub mod normalize;
25
24
pub mod outlives;
26
25
pub mod prove_predicate;
26
+ use self :: prove_predicate:: ProvePredicate ;
27
27
pub mod subtype;
28
28
29
29
pub trait TypeOp < ' gcx , ' tcx > : Sized + fmt:: Debug {
@@ -38,16 +38,18 @@ pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
38
38
) -> Fallible < ( Self :: Output , Option < Rc < Vec < QueryRegionConstraint < ' tcx > > > > ) > ;
39
39
}
40
40
41
- pub trait QueryTypeOp < ' gcx : ' tcx , ' tcx > : fmt:: Debug + Sized {
42
- type QueryKey : TypeFoldable < ' tcx > + Lift < ' gcx > ;
41
+ pub trait QueryTypeOp < ' gcx : ' tcx , ' tcx > :
42
+ fmt:: Debug + Sized + TypeFoldable < ' tcx > + Lift < ' gcx >
43
+ {
43
44
type QueryResult : TypeFoldable < ' tcx > + Lift < ' gcx > ;
44
45
45
46
/// Either converts `self` directly into a `QueryResult` (for
46
47
/// simple cases) or into a `QueryKey` (for more complex cases
47
48
/// where we actually have work to do).
48
- fn prequery ( self , tcx : TyCtxt < ' _ , ' gcx , ' tcx > ) -> Result < Self :: QueryResult , Self :: QueryKey > ;
49
-
50
- fn param_env ( key : & Self :: QueryKey ) -> ParamEnv < ' tcx > ;
49
+ fn prequery (
50
+ tcx : TyCtxt < ' _ , ' gcx , ' tcx > ,
51
+ key : & ParamEnvAnd < ' tcx , Self > ,
52
+ ) -> Option < Self :: QueryResult > ;
51
53
52
54
/// Performs the actual query with the canonicalized key -- the
53
55
/// real work happens here. This method is not given an `infcx`
@@ -57,7 +59,7 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>: fmt::Debug + Sized {
57
59
/// not captured in the return value.
58
60
fn perform_query (
59
61
tcx : TyCtxt < ' _ , ' gcx , ' tcx > ,
60
- canonicalized : Canonicalized < ' gcx , Self :: QueryKey > ,
62
+ canonicalized : Canonicalized < ' gcx , ParamEnvAnd < ' tcx , Self > > ,
61
63
) -> Fallible < CanonicalizedQueryResult < ' gcx , Self :: QueryResult > > ;
62
64
63
65
/// Casts a lifted query result (which is in the gcx lifetime)
@@ -77,52 +79,53 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>: fmt::Debug + Sized {
77
79
) -> & ' a Canonical < ' tcx , QueryResult < ' tcx , Self :: QueryResult > > ;
78
80
79
81
fn fully_perform_into (
80
- self ,
82
+ query_key : ParamEnvAnd < ' tcx , Self > ,
81
83
infcx : & InferCtxt < ' _ , ' gcx , ' tcx > ,
82
84
output_query_region_constraints : & mut Vec < QueryRegionConstraint < ' tcx > > ,
83
85
) -> Fallible < Self :: QueryResult > {
84
- match QueryTypeOp :: prequery ( self , infcx. tcx ) {
85
- Ok ( result) => Ok ( result) ,
86
- Err ( query_key) => {
87
- // FIXME(#33684) -- We need to use
88
- // `canonicalize_hr_query_hack` here because of things
89
- // like the subtype query, which go awry around
90
- // `'static` otherwise.
91
- let ( canonical_self, canonical_var_values) =
92
- infcx. canonicalize_hr_query_hack ( & query_key) ;
93
- let canonical_result = Self :: perform_query ( infcx. tcx , canonical_self) ?;
94
- let canonical_result = Self :: shrink_to_tcx_lifetime ( & canonical_result) ;
95
-
96
- let param_env = Self :: param_env ( & query_key) ;
97
-
98
- let InferOk { value, obligations } = infcx
99
- . instantiate_nll_query_result_and_region_obligations (
100
- & ObligationCause :: dummy ( ) ,
101
- param_env,
102
- & canonical_var_values,
103
- canonical_result,
104
- output_query_region_constraints,
105
- ) ?;
106
-
107
- // Typically, instantiating NLL query results does not
108
- // create obligations. However, in some cases there
109
- // are unresolved type variables, and unify them *can*
110
- // create obligations. In that case, we have to go
111
- // fulfill them. We do this via a (recursive) query.
112
- for obligation in obligations {
113
- let ( ) = prove_predicate:: ProvePredicate :: new (
114
- obligation. param_env ,
115
- obligation. predicate ,
116
- ) . fully_perform_into ( infcx, output_query_region_constraints) ?;
117
- }
118
-
119
- Ok ( value)
120
- }
86
+ if let Some ( result) = QueryTypeOp :: prequery ( infcx. tcx , & query_key) {
87
+ return Ok ( result) ;
121
88
}
89
+
90
+ // FIXME(#33684) -- We need to use
91
+ // `canonicalize_hr_query_hack` here because of things
92
+ // like the subtype query, which go awry around
93
+ // `'static` otherwise.
94
+ let ( canonical_self, canonical_var_values) = infcx. canonicalize_hr_query_hack ( & query_key) ;
95
+ let canonical_result = Self :: perform_query ( infcx. tcx , canonical_self) ?;
96
+ let canonical_result = Self :: shrink_to_tcx_lifetime ( & canonical_result) ;
97
+
98
+ let param_env = query_key. param_env ;
99
+
100
+ let InferOk { value, obligations } = infcx
101
+ . instantiate_nll_query_result_and_region_obligations (
102
+ & ObligationCause :: dummy ( ) ,
103
+ param_env,
104
+ & canonical_var_values,
105
+ canonical_result,
106
+ output_query_region_constraints,
107
+ ) ?;
108
+
109
+ // Typically, instantiating NLL query results does not
110
+ // create obligations. However, in some cases there
111
+ // are unresolved type variables, and unify them *can*
112
+ // create obligations. In that case, we have to go
113
+ // fulfill them. We do this via a (recursive) query.
114
+ for obligation in obligations {
115
+ let ( ) = ProvePredicate :: fully_perform_into (
116
+ obligation
117
+ . param_env
118
+ . and ( ProvePredicate :: new ( obligation. predicate ) ) ,
119
+ infcx,
120
+ output_query_region_constraints,
121
+ ) ?;
122
+ }
123
+
124
+ Ok ( value)
122
125
}
123
126
}
124
127
125
- impl < ' gcx : ' tcx , ' tcx , Q > TypeOp < ' gcx , ' tcx > for Q
128
+ impl < ' gcx : ' tcx , ' tcx , Q > TypeOp < ' gcx , ' tcx > for ParamEnvAnd < ' tcx , Q >
126
129
where
127
130
Q : QueryTypeOp < ' gcx , ' tcx > ,
128
131
{
0 commit comments