@@ -21,6 +21,7 @@ use middle::const_val::{ConstEvalErr, ErrKind};
21
21
use super :: CodeAmbiguity ;
22
22
use super :: CodeProjectionError ;
23
23
use super :: CodeSelectionError ;
24
+ use super :: engine:: TraitEngine ;
24
25
use super :: { FulfillmentError , FulfillmentErrorCode } ;
25
26
use super :: { ObligationCause , PredicateObligation , Obligation } ;
26
27
use super :: project;
@@ -85,19 +86,72 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
85
86
}
86
87
}
87
88
89
+ pub fn register_predicate_obligations < I > ( & mut self ,
90
+ infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
91
+ obligations : I )
92
+ where I : IntoIterator < Item = PredicateObligation < ' tcx > >
93
+ {
94
+ for obligation in obligations {
95
+ self . register_predicate_obligation ( infcx, obligation) ;
96
+ }
97
+ }
98
+
99
+ /// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
100
+ /// only attempts to select obligations that haven't been seen before.
101
+ fn select ( & mut self , selcx : & mut SelectionContext < ' a , ' gcx , ' tcx > )
102
+ -> Result < ( ) , Vec < FulfillmentError < ' tcx > > > {
103
+ debug ! ( "select(obligation-forest-size={})" , self . predicates. len( ) ) ;
104
+
105
+ let mut errors = Vec :: new ( ) ;
106
+
107
+ loop {
108
+ debug ! ( "select: starting another iteration" ) ;
109
+
110
+ // Process pending obligations.
111
+ let outcome = self . predicates . process_obligations ( & mut FulfillProcessor {
112
+ selcx,
113
+ register_region_obligations : self . register_region_obligations
114
+ } ) ;
115
+ debug ! ( "select: outcome={:?}" , outcome) ;
116
+
117
+ // FIXME: if we kept the original cache key, we could mark projection
118
+ // obligations as complete for the projection cache here.
119
+
120
+ errors. extend (
121
+ outcome. errors . into_iter ( )
122
+ . map ( |e| to_fulfillment_error ( e) ) ) ;
123
+
124
+ // If nothing new was added, no need to keep looping.
125
+ if outcome. stalled {
126
+ break ;
127
+ }
128
+ }
129
+
130
+ debug ! ( "select({} predicates remaining, {} errors) done" ,
131
+ self . predicates. len( ) , errors. len( ) ) ;
132
+
133
+ if errors. is_empty ( ) {
134
+ Ok ( ( ) )
135
+ } else {
136
+ Err ( errors)
137
+ }
138
+ }
139
+ }
140
+
141
+ impl < ' tcx > TraitEngine < ' tcx > for FulfillmentContext < ' tcx > {
88
142
/// "Normalize" a projection type `<SomeType as SomeTrait>::X` by
89
143
/// creating a fresh type variable `$0` as well as a projection
90
144
/// predicate `<SomeType as SomeTrait>::X == $0`. When the
91
145
/// inference engine runs, it will attempt to find an impl of
92
146
/// `SomeTrait` or a where clause that lets us unify `$0` with
93
147
/// something concrete. If this fails, we'll unify `$0` with
94
148
/// `projection_ty` again.
95
- pub fn normalize_projection_type ( & mut self ,
96
- infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
97
- param_env : ty:: ParamEnv < ' tcx > ,
98
- projection_ty : ty:: ProjectionTy < ' tcx > ,
99
- cause : ObligationCause < ' tcx > )
100
- -> Ty < ' tcx >
149
+ fn normalize_projection_type < ' a , ' gcx > ( & mut self ,
150
+ infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
151
+ param_env : ty:: ParamEnv < ' tcx > ,
152
+ projection_ty : ty:: ProjectionTy < ' tcx > ,
153
+ cause : ObligationCause < ' tcx > )
154
+ -> Ty < ' tcx >
101
155
{
102
156
debug ! ( "normalize_projection_type(projection_ty={:?})" ,
103
157
projection_ty) ;
@@ -125,12 +179,12 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
125
179
/// Requires that `ty` must implement the trait with `def_id` in
126
180
/// the given environment. This trait must not have any type
127
181
/// parameters (except for `Self`).
128
- pub fn register_bound ( & mut self ,
129
- infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
130
- param_env : ty:: ParamEnv < ' tcx > ,
131
- ty : Ty < ' tcx > ,
132
- def_id : DefId ,
133
- cause : ObligationCause < ' tcx > )
182
+ fn register_bound < ' a , ' gcx > ( & mut self ,
183
+ infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
184
+ param_env : ty:: ParamEnv < ' tcx > ,
185
+ ty : Ty < ' tcx > ,
186
+ def_id : DefId ,
187
+ cause : ObligationCause < ' tcx > )
134
188
{
135
189
let trait_ref = ty:: TraitRef {
136
190
def_id,
@@ -144,9 +198,9 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
144
198
} ) ;
145
199
}
146
200
147
- pub fn register_predicate_obligation ( & mut self ,
148
- infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
149
- obligation : PredicateObligation < ' tcx > )
201
+ fn register_predicate_obligation < ' a , ' gcx > ( & mut self ,
202
+ infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
203
+ obligation : PredicateObligation < ' tcx > )
150
204
{
151
205
// this helps to reduce duplicate errors, as well as making
152
206
// debug output much nicer to read and so on.
@@ -162,19 +216,9 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
162
216
} ) ;
163
217
}
164
218
165
- pub fn register_predicate_obligations < I > ( & mut self ,
166
- infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
167
- obligations : I )
168
- where I : IntoIterator < Item = PredicateObligation < ' tcx > >
169
- {
170
- for obligation in obligations {
171
- self . register_predicate_obligation ( infcx, obligation) ;
172
- }
173
- }
174
-
175
- pub fn select_all_or_error ( & mut self ,
176
- infcx : & InferCtxt < ' a , ' gcx , ' tcx > )
177
- -> Result < ( ) , Vec < FulfillmentError < ' tcx > > >
219
+ fn select_all_or_error < ' a , ' gcx > ( & mut self ,
220
+ infcx : & InferCtxt < ' a , ' gcx , ' tcx > )
221
+ -> Result < ( ) , Vec < FulfillmentError < ' tcx > > >
178
222
{
179
223
self . select_where_possible ( infcx) ?;
180
224
@@ -190,58 +234,17 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
190
234
}
191
235
}
192
236
193
- pub fn select_where_possible ( & mut self ,
194
- infcx : & InferCtxt < ' a , ' gcx , ' tcx > )
195
- -> Result < ( ) , Vec < FulfillmentError < ' tcx > > >
237
+ fn select_where_possible < ' a , ' gcx > ( & mut self ,
238
+ infcx : & InferCtxt < ' a , ' gcx , ' tcx > )
239
+ -> Result < ( ) , Vec < FulfillmentError < ' tcx > > >
196
240
{
197
241
let mut selcx = SelectionContext :: new ( infcx) ;
198
242
self . select ( & mut selcx)
199
243
}
200
244
201
- pub fn pending_obligations ( & self ) -> Vec < PendingPredicateObligation < ' tcx > > {
245
+ fn pending_obligations ( & self ) -> Vec < PendingPredicateObligation < ' tcx > > {
202
246
self . predicates . pending_obligations ( )
203
247
}
204
-
205
- /// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
206
- /// only attempts to select obligations that haven't been seen before.
207
- fn select ( & mut self , selcx : & mut SelectionContext < ' a , ' gcx , ' tcx > )
208
- -> Result < ( ) , Vec < FulfillmentError < ' tcx > > > {
209
- debug ! ( "select(obligation-forest-size={})" , self . predicates. len( ) ) ;
210
-
211
- let mut errors = Vec :: new ( ) ;
212
-
213
- loop {
214
- debug ! ( "select: starting another iteration" ) ;
215
-
216
- // Process pending obligations.
217
- let outcome = self . predicates . process_obligations ( & mut FulfillProcessor {
218
- selcx,
219
- register_region_obligations : self . register_region_obligations
220
- } ) ;
221
- debug ! ( "select: outcome={:?}" , outcome) ;
222
-
223
- // FIXME: if we kept the original cache key, we could mark projection
224
- // obligations as complete for the projection cache here.
225
-
226
- errors. extend (
227
- outcome. errors . into_iter ( )
228
- . map ( |e| to_fulfillment_error ( e) ) ) ;
229
-
230
- // If nothing new was added, no need to keep looping.
231
- if outcome. stalled {
232
- break ;
233
- }
234
- }
235
-
236
- debug ! ( "select({} predicates remaining, {} errors) done" ,
237
- self . predicates. len( ) , errors. len( ) ) ;
238
-
239
- if errors. is_empty ( ) {
240
- Ok ( ( ) )
241
- } else {
242
- Err ( errors)
243
- }
244
- }
245
248
}
246
249
247
250
struct FulfillProcessor < ' a , ' b : ' a , ' gcx : ' tcx , ' tcx : ' b > {
0 commit comments