1
1
import check:: { fn_ctxt, impl_self_ty, methods} ;
2
2
import infer:: { resolve_type, resolve_all, force_all, fixup_err_to_str} ;
3
3
import ast_util:: new_def_hash;
4
+ import dvec:: extensions;
4
5
5
6
fn has_trait_bounds ( tps : ~[ ty:: param_bounds ] ) -> bool {
6
7
vec:: any ( tps, |bs| {
@@ -10,7 +11,7 @@ fn has_trait_bounds(tps: ~[ty::param_bounds]) -> bool {
10
11
} )
11
12
}
12
13
13
- fn lookup_vtables ( fcx : @fn_ctxt , isc : resolve3 :: ImplScopes , sp : span ,
14
+ fn lookup_vtables ( fcx : @fn_ctxt , sp : span ,
14
15
bounds : @~[ ty:: param_bounds ] , substs : ty:: substs ,
15
16
allow_unsafe : bool ) -> vtable_res {
16
17
let tcx = fcx. ccx . tcx ;
@@ -20,8 +21,8 @@ fn lookup_vtables(fcx: @fn_ctxt, isc: resolve3::ImplScopes, sp: span,
20
21
alt bound {
21
22
ty : : bound_trait( i_ty) {
22
23
let i_ty = ty:: subst( tcx, substs, i_ty) ;
23
- vec:: push( result, lookup_vtable( fcx, isc , sp, ty, i_ty,
24
- allow_unsafe) ) ;
24
+ vec:: push( result, lookup_vtable( fcx, sp, ty, i_ty,
25
+ allow_unsafe) ) ;
25
26
}
26
27
_ { }
27
28
}
@@ -50,12 +51,10 @@ fn relate_trait_tys(fcx: @fn_ctxt, sp: span,
50
51
/*
51
52
Look up the vtable to use when treating an item of type <t>
52
53
as if it has type <trait_ty>
53
-
54
- XXX: This doesn't use the coherence tables yet.
55
54
*/
56
- fn lookup_vtable ( fcx : @fn_ctxt , isc : resolve3 :: ImplScopes , sp : span ,
57
- ty : ty :: t , trait_ty : ty :: t , allow_unsafe : bool )
58
- -> vtable_origin {
55
+ fn lookup_vtable ( fcx : @fn_ctxt , sp : span , ty : ty :: t , trait_ty : ty :: t ,
56
+ allow_unsafe : bool )
57
+ -> vtable_origin {
59
58
60
59
#debug[ "lookup_vtable(ty=%s, trait_ty=%s)" ,
61
60
fcx. infcx . ty_to_str ( ty) , fcx. infcx . ty_to_str ( trait_ty) ] ;
@@ -119,64 +118,72 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve3::ImplScopes, sp: span,
119
118
120
119
let mut impls_seen = new_def_hash ( ) ;
121
120
122
- for list:: each( isc) |impls| {
123
- /* For each impl in scope... */
124
- for vec:: each( * impls) |im| {
125
- // im = one specific impl
121
+ alt fcx. ccx . coherence_info . extension_methods . find ( trait_id) {
122
+ none {
123
+ // Nothing found. Continue.
124
+ }
125
+ some( implementations) {
126
+ for uint:: range( 0 , implementations. len( ) ) |i| {
127
+ let im = implementations[ i] ;
126
128
127
- // First, ensure that we haven't processed this impl yet.
128
- if impls_seen. contains_key ( im. did ) {
129
- again;
130
- }
131
- impls_seen. insert ( im. did , ( ) ) ;
129
+ // im = one specific impl
132
130
133
- // find the trait that im implements (if any)
134
- for vec:: each( ty:: impl_traits( tcx, im. did) ) |of_ty| {
135
- // it must have the same id as the expected one
136
- alt ty:: get( of_ty) . struct {
137
- ty:: ty_trait( id, _) if id != trait_id { again; }
138
- _ { /* ok */ }
131
+ // First, ensure that we haven't processed this impl yet.
132
+ if impls_seen. contains_key ( im. did ) {
133
+ again;
139
134
}
135
+ impls_seen. insert ( im. did , ( ) ) ;
140
136
141
- // check whether the type unifies with the type
142
- // that the impl is for, and continue if not
143
- let { substs: substs, ty: for_ty} =
144
- impl_self_ty ( fcx, im. did ) ;
145
- let im_bs = ty:: lookup_item_type ( tcx, im. did ) . bounds ;
146
- alt fcx. mk_subty ( ty, for_ty) {
147
- result:: err ( _) { again; }
148
- result:: ok ( ( ) ) { }
149
- }
137
+ // find the trait that im implements (if any)
138
+ for vec:: each( ty:: impl_traits( tcx, im. did) ) |of_ty| {
139
+ // it must have the same id as the expected one
140
+ alt ty:: get( of_ty) . struct {
141
+ ty:: ty_trait( id, _) if id != trait_id { again; }
142
+ _ { /* ok */ }
143
+ }
144
+
145
+ // check whether the type unifies with the type
146
+ // that the impl is for, and continue if not
147
+ let { substs: substs, ty: for_ty} =
148
+ impl_self_ty ( fcx, im. did ) ;
149
+ let im_bs = ty:: lookup_item_type ( tcx, im. did ) . bounds ;
150
+ alt fcx. mk_subty ( ty, for_ty) {
151
+ result:: err ( _) { again; }
152
+ result:: ok ( ( ) ) { }
153
+ }
150
154
151
- // check that desired trait type unifies
152
- #debug ( "(checking vtable) @2 relating trait ty %s to \
153
- of_ty %s",
154
- fcx. infcx . ty_to_str ( trait_ty) ,
155
- fcx. infcx . ty_to_str ( of_ty) ) ;
156
- let of_ty = ty:: subst ( tcx, substs, of_ty) ;
157
- relate_trait_tys ( fcx, sp, trait_ty, of_ty) ;
155
+ // check that desired trait type unifies
156
+ #debug ( "(checking vtable) @2 relating trait ty %s to \
157
+ of_ty %s",
158
+ fcx. infcx . ty_to_str ( trait_ty) ,
159
+ fcx. infcx . ty_to_str ( of_ty) ) ;
160
+ let of_ty = ty:: subst ( tcx, substs, of_ty) ;
161
+ relate_trait_tys ( fcx, sp, trait_ty, of_ty) ;
158
162
159
- // recursively process the bounds
160
- let trait_tps = trait_substs. tps ;
161
- let substs_f = fixup_substs ( fcx, sp, trait_id, substs) ;
162
- connect_trait_tps ( fcx, sp, substs_f. tps ,
163
- trait_tps, im. did ) ;
164
- let subres = lookup_vtables ( fcx, isc, sp,
165
- im_bs, substs_f, false ) ;
166
- vec:: push ( found,
167
- vtable_static ( im. did , substs_f. tps , subres) ) ;
163
+ // recursively process the bounds
164
+ let trait_tps = trait_substs. tps ;
165
+ let substs_f = fixup_substs ( fcx, sp, trait_id,
166
+ substs) ;
167
+ connect_trait_tps ( fcx, sp, substs_f. tps ,
168
+ trait_tps, im. did ) ;
169
+ let subres = lookup_vtables ( fcx, sp, im_bs, substs_f,
170
+ false ) ;
171
+ vec:: push ( found,
172
+ vtable_static ( im. did , substs_f. tps ,
173
+ subres) ) ;
174
+ }
168
175
}
169
176
}
177
+ }
170
178
171
- alt found. len ( ) {
172
- 0 u { /* fallthrough */ }
173
- 1 u { ret found[ 0 ] ; }
174
- _ {
175
- fcx. ccx . tcx . sess . span_err (
176
- sp, ~"multiple applicable methods in scope") ;
177
- ret found[ 0 ] ;
178
- }
179
- }
179
+ alt found. len ( ) {
180
+ 0 u { /* fallthrough */ }
181
+ 1 u { ret found[ 0 ] ; }
182
+ _ {
183
+ fcx. ccx . tcx . sess . span_err (
184
+ sp, ~"multiple applicable methods in scope") ;
185
+ ret found[ 0 ] ;
186
+ }
180
187
}
181
188
}
182
189
}
@@ -227,10 +234,11 @@ fn resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, v: visit::vt<@fn_ctxt>) {
227
234
let did = ast_util:: def_id_of_def( cx. tcx. def_map. get( ex. id) ) ;
228
235
let item_ty = ty:: lookup_item_type( cx. tcx, did) ;
229
236
if has_trait_bounds( * item_ty. bounds) {
230
- let impls = cx. impl_map. get( ex. id) ;
231
- cx. vtable_map. insert( ex. id, lookup_vtables(
232
- fcx, impls, ex. span,
233
- item_ty. bounds, substs, false ) ) ;
237
+ cx. vtable_map. insert( ex. id, lookup_vtables( fcx,
238
+ ex. span,
239
+ item_ty. bounds,
240
+ substs,
241
+ false ) ) ;
234
242
}
235
243
}
236
244
_ { }
@@ -249,9 +257,11 @@ fn resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, v: visit::vt<@fn_ctxt>) {
249
257
_ { ex. callee_id }
250
258
} ;
251
259
let substs = fcx. node_ty_substs( callee_id) ;
252
- let iscs = cx. impl_map. get( ex. id) ;
253
- cx. vtable_map. insert( callee_id, lookup_vtables(
254
- fcx, iscs, ex. span, bounds, substs, false) ) ;
260
+ cx. vtable_map. insert( callee_id, lookup_vtables( fcx,
261
+ ex. span,
262
+ bounds,
263
+ substs,
264
+ false) ) ;
255
265
}
256
266
}
257
267
_ { }
@@ -261,17 +271,12 @@ fn resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, v: visit::vt<@fn_ctxt>) {
261
271
let target_ty = fcx. expr_ty( ex) ;
262
272
alt ty:: get( target_ty) . struct {
263
273
ty:: ty_trait( * ) {
264
- /* Casting to an interface type.
265
- Look up all impls for the cast expr...
266
- */
267
- let impls = cx. impl_map. get( ex. id) ;
268
274
/*
269
275
Look up vtables for the type we're casting to,
270
276
passing in the source and target type
271
277
*/
272
- let vtable = lookup_vtable( fcx, impls, ex. span,
273
- fcx. expr_ty( src) , target_ty,
274
- true) ;
278
+ let vtable = lookup_vtable( fcx, ex. span, fcx. expr_ty( src) ,
279
+ target_ty, true) ;
275
280
/*
276
281
Map this expression to that vtable (that is: "ex has
277
282
vtable <vtable>")
0 commit comments