@@ -51,8 +51,18 @@ fn lookup_vtables(fcx: @fn_ctxt,
51
51
match * bound {
52
52
ty:: bound_trait( i_ty) => {
53
53
let i_ty = ty:: subst ( tcx, substs, i_ty) ;
54
- result. push ( lookup_vtable ( fcx, expr, * ty, i_ty,
55
- allow_unsafe, is_early) ) ;
54
+ match lookup_vtable ( fcx, expr, * ty, i_ty, allow_unsafe,
55
+ is_early) {
56
+ Some ( vtable) => result. push ( vtable) ,
57
+ None => {
58
+ fcx. tcx ( ) . sess . span_fatal (
59
+ expr. span ,
60
+ fmt ! ( "failed to find an implementation of trait \
61
+ %s for %s",
62
+ ty_to_str( fcx. tcx( ) , i_ty) ,
63
+ ty_to_str( fcx. tcx( ) , * ty) ) ) ;
64
+ }
65
+ }
56
66
}
57
67
_ => ( )
58
68
}
@@ -91,7 +101,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
91
101
trait_ty : ty:: t ,
92
102
allow_unsafe : bool ,
93
103
is_early : bool )
94
- -> vtable_origin
104
+ -> Option < vtable_origin >
95
105
{
96
106
97
107
debug ! ( "lookup_vtable(ty=%s, trait_ty=%s)" ,
@@ -113,7 +123,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
113
123
// The type has unconstrained type variables in it, so we can't
114
124
// do early resolution on it. Return some completely bogus vtable
115
125
// information: we aren't storing it anyways.
116
- return vtable_param ( 0 , 0 ) ;
126
+ return Some ( vtable_param ( 0 , 0 ) ) ;
117
127
}
118
128
} ;
119
129
@@ -135,7 +145,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
135
145
idid) ;
136
146
relate_trait_tys ( fcx, expr,
137
147
trait_ty, ity) ;
138
- return vtable_param ( n, n_bound) ;
148
+ return Some ( vtable_param ( n, n_bound) ) ;
139
149
}
140
150
}
141
151
_ => tcx. sess . impossible_case (
@@ -170,7 +180,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
170
180
}
171
181
}
172
182
}
173
- return vtable_trait ( did, substs. tps ) ;
183
+ return Some ( vtable_trait ( did, substs. tps ) ) ;
174
184
}
175
185
176
186
_ => {
@@ -303,7 +313,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
303
313
None => {
304
314
assert is_early;
305
315
// Bail out with a bogus answer
306
- return vtable_param ( 0 , 0 ) ;
316
+ return Some ( vtable_param ( 0 , 0 ) ) ;
307
317
}
308
318
} ;
309
319
@@ -341,23 +351,20 @@ fn lookup_vtable(fcx: @fn_ctxt,
341
351
342
352
match found. len ( ) {
343
353
0 => { /* fallthrough */ }
344
- 1 => { return found[ 0 ] ; }
354
+ 1 => { return Some ( found[ 0 ] ) ; }
345
355
_ => {
346
356
if !is_early {
347
357
fcx. ccx . tcx . sess . span_err (
348
358
expr. span ,
349
359
~"multiple applicable methods in scope") ;
350
360
}
351
- return found[ 0 ] ;
361
+ return Some ( found[ 0 ] ) ;
352
362
}
353
363
}
354
364
}
355
365
}
356
366
357
- tcx. sess . span_fatal (
358
- expr. span ,
359
- fmt ! ( "failed to find an implementation of trait %s for %s" ,
360
- ty_to_str( tcx, trait_ty) , ty_to_str( tcx, ty) ) ) ;
367
+ return None ;
361
368
}
362
369
363
370
fn fixup_ty ( fcx : @fn_ctxt ,
@@ -459,13 +466,55 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
459
466
Look up vtables for the type we're casting to,
460
467
passing in the source and target type
461
468
*/
462
- let vtable = lookup_vtable ( fcx, ex, fcx. expr_ty ( src) ,
463
- target_ty, true , is_early) ;
464
- /*
465
- Map this expression to that vtable (that is: "ex has
466
- vtable <vtable>")
467
- */
468
- if !is_early { cx. vtable_map . insert ( ex. id , @~[ vtable] ) ; }
469
+ let ty = fcx. expr_ty ( src) ;
470
+ let vtable_opt = lookup_vtable ( fcx, ex, ty, target_ty, true ,
471
+ is_early) ;
472
+ match vtable_opt {
473
+ None => {
474
+ // Try the new-style boxed trait; "@int as @Trait".
475
+ let mut err = false ;
476
+ let ty = structurally_resolved_type ( fcx, ex. span , ty) ;
477
+ match ty:: get ( ty) . sty {
478
+ ty:: ty_box( boxed_ty) => {
479
+ let vtable_opt = lookup_vtable ( fcx, ex,
480
+ boxed_ty. ty ,
481
+ target_ty, true ,
482
+ is_early) ;
483
+ match vtable_opt {
484
+ Some ( vtable) => {
485
+ /*
486
+ Map this expression to that vtable (that
487
+ is: "ex has vtable <vtable>")
488
+ */
489
+ if !is_early {
490
+ cx. vtable_map . insert ( ex. id ,
491
+ @~[ vtable] ) ;
492
+ }
493
+ }
494
+ None => err = true
495
+ }
496
+ }
497
+ _ => err = true
498
+ }
499
+
500
+ if err {
501
+ fcx. tcx ( ) . sess . span_fatal (
502
+ ex. span ,
503
+ fmt ! ( "failed to find an implementation of trait \
504
+ %s for %s",
505
+ ty_to_str( fcx. tcx( ) , target_ty) ,
506
+ ty_to_str( fcx. tcx( ) , ty) ) ) ;
507
+ }
508
+ }
509
+ Some ( vtable) => {
510
+ /*
511
+ Map this expression to that vtable (that is: "ex has
512
+ vtable <vtable>")
513
+ */
514
+ if !is_early { cx. vtable_map . insert ( ex. id , @~[ vtable] ) ; }
515
+ fcx. tcx ( ) . legacy_boxed_traits . insert ( ex. id , ( ) ) ;
516
+ }
517
+ }
469
518
}
470
519
_ => ( )
471
520
}
0 commit comments