8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ use middle:: mem_categorization:: Typer ;
11
12
use middle:: ty;
12
- use middle:: typeck:: infer:: { InferCtxt , skolemize} ;
13
- use util:: nodemap:: DefIdMap ;
13
+ use middle:: typeck:: infer:: InferCtxt ;
14
14
use util:: ppaux:: Repr ;
15
15
16
16
use super :: CodeAmbiguity ;
17
17
use super :: Obligation ;
18
18
use super :: FulfillmentError ;
19
19
use super :: CodeSelectionError ;
20
20
use super :: select:: SelectionContext ;
21
- use super :: Unimplemented ;
22
21
23
22
/**
24
23
* The fulfillment context is used to drive trait resolution. It
@@ -36,17 +35,12 @@ pub struct FulfillmentContext {
36
35
// A list of all obligations that have been registered with this
37
36
// fulfillment context.
38
37
trait_obligations : Vec < Obligation > ,
39
-
40
- // For semi-hacky reasons (see FIXME below) we keep the builtin
41
- // trait obligations segregated.
42
- builtin_obligations : Vec < Obligation > ,
43
38
}
44
39
45
40
impl FulfillmentContext {
46
41
pub fn new ( ) -> FulfillmentContext {
47
42
FulfillmentContext {
48
43
trait_obligations : Vec :: new ( ) ,
49
- builtin_obligations : Vec :: new ( )
50
44
}
51
45
}
52
46
@@ -55,24 +49,16 @@ impl FulfillmentContext {
55
49
obligation : Obligation )
56
50
{
57
51
debug ! ( "register_obligation({})" , obligation. repr( tcx) ) ;
58
- match tcx. lang_items . to_builtin_kind ( obligation. trait_ref . def_id ) {
59
- Some ( _) => {
60
- self . builtin_obligations . push ( obligation) ;
61
- }
62
- None => {
63
- self . trait_obligations . push ( obligation) ;
64
- }
65
- }
52
+ self . trait_obligations . push ( obligation) ;
66
53
}
67
54
68
- pub fn select_all_or_error ( & mut self ,
69
- infcx : & InferCtxt ,
70
- param_env : & ty:: ParameterEnvironment ,
71
- unboxed_closures : & DefIdMap < ty :: UnboxedClosure > )
72
- -> Result < ( ) , Vec < FulfillmentError > >
55
+ pub fn select_all_or_error < ' a , ' tcx > ( & mut self ,
56
+ infcx : & InferCtxt < ' a , ' tcx > ,
57
+ param_env : & ty:: ParameterEnvironment ,
58
+ typer : & Typer < ' tcx > )
59
+ -> Result < ( ) , Vec < FulfillmentError > >
73
60
{
74
- try!( self . select_where_possible ( infcx, param_env,
75
- unboxed_closures) ) ;
61
+ try!( self . select_where_possible ( infcx, param_env, typer) ) ;
76
62
77
63
// Anything left is ambiguous.
78
64
let errors: Vec < FulfillmentError > =
@@ -88,15 +74,14 @@ impl FulfillmentContext {
88
74
}
89
75
}
90
76
91
- pub fn select_where_possible ( & mut self ,
92
- infcx : & InferCtxt ,
93
- param_env : & ty:: ParameterEnvironment ,
94
- unboxed_closures : & DefIdMap < ty :: UnboxedClosure > )
95
- -> Result < ( ) , Vec < FulfillmentError > >
77
+ pub fn select_where_possible < ' a , ' tcx > ( & mut self ,
78
+ infcx : & InferCtxt < ' a , ' tcx > ,
79
+ param_env : & ty:: ParameterEnvironment ,
80
+ typer : & Typer < ' tcx > )
81
+ -> Result < ( ) , Vec < FulfillmentError > >
96
82
{
97
83
let tcx = infcx. tcx ;
98
- let selcx = SelectionContext :: new ( infcx, param_env,
99
- unboxed_closures) ;
84
+ let mut selcx = SelectionContext :: new ( infcx, param_env, typer) ;
100
85
101
86
debug ! ( "select_where_possible({} obligations) start" ,
102
87
self . trait_obligations. len( ) ) ;
@@ -158,92 +143,4 @@ impl FulfillmentContext {
158
143
Err ( errors)
159
144
}
160
145
}
161
-
162
- pub fn check_builtin_bound_obligations (
163
- & self ,
164
- infcx : & InferCtxt )
165
- -> Result < ( ) , Vec < FulfillmentError > >
166
- {
167
- let tcx = infcx. tcx ;
168
- let mut errors = Vec :: new ( ) ;
169
- debug ! ( "check_builtin_bound_obligations" ) ;
170
- for obligation in self . builtin_obligations . iter ( ) {
171
- debug ! ( "obligation={}" , obligation. repr( tcx) ) ;
172
-
173
- let def_id = obligation. trait_ref . def_id ;
174
- let bound = match tcx. lang_items . to_builtin_kind ( def_id) {
175
- Some ( bound) => { bound }
176
- None => { continue ; }
177
- } ;
178
-
179
- let unskol_self_ty = obligation. self_ty ( ) ;
180
-
181
- // Skolemize the self-type so that it no longer contains
182
- // inference variables. Note that this also replaces
183
- // regions with 'static. You might think that this is not
184
- // ok, because checking whether something is `Send`
185
- // implies checking whether it is 'static: that's true,
186
- // but in fact the region bound is fed into region
187
- // inference separately and enforced there (and that has
188
- // even already been done before this code executes,
189
- // generally speaking).
190
- let self_ty = skolemize ( infcx, unskol_self_ty) ;
191
-
192
- debug ! ( "bound={} self_ty={}" , bound, self_ty. repr( tcx) ) ;
193
- if ty:: type_is_error ( self_ty) {
194
- // Indicates an error that was/will-be
195
- // reported elsewhere.
196
- continue ;
197
- }
198
-
199
- // Determine if builtin bound is met.
200
- let tc = ty:: type_contents ( tcx, self_ty) ;
201
- debug ! ( "tc={}" , tc) ;
202
- let met = match bound {
203
- ty:: BoundSend => tc. is_sendable ( tcx) ,
204
- ty:: BoundSized => tc. is_sized ( tcx) ,
205
- ty:: BoundCopy => tc. is_copy ( tcx) ,
206
- ty:: BoundSync => tc. is_sync ( tcx) ,
207
- } ;
208
-
209
- if met {
210
- continue ;
211
- }
212
-
213
- // FIXME -- This is kind of a hack: it requently happens
214
- // that some earlier error prevents types from being fully
215
- // inferred, and then we get a bunch of uninteresting
216
- // errors saying something like "<generic #0> doesn't
217
- // implement Sized". It may even be true that we could
218
- // just skip over all checks where the self-ty is an
219
- // inference variable, but I was afraid that there might
220
- // be an inference variable created, registered as an
221
- // obligation, and then never forced by writeback, and
222
- // hence by skipping here we'd be ignoring the fact that
223
- // we don't KNOW the type works out. Though even that
224
- // would probably be harmless, given that we're only
225
- // talking about builtin traits, which are known to be
226
- // inhabited. But in any case I just threw in this check
227
- // for has_errors() to be sure that compilation isn't
228
- // happening anyway. In that case, why inundate the user.
229
- if ty:: type_needs_infer ( self_ty) &&
230
- tcx. sess . has_errors ( )
231
- {
232
- debug ! ( "skipping printout because self_ty={}" ,
233
- self_ty. repr( tcx) ) ;
234
- continue ;
235
- }
236
-
237
- errors. push (
238
- FulfillmentError :: new (
239
- ( * obligation) . clone ( ) ,
240
- CodeSelectionError ( Unimplemented ) ) ) ;
241
- }
242
-
243
- if errors. is_empty ( ) {
244
- Ok ( ( ) )
245
- } else {
246
- Err ( errors)
247
- }
248
- }
249
146
}
0 commit comments