@@ -24,24 +24,32 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
24
24
pub fn get_vtable (
25
25
& mut self ,
26
26
ty : Ty < ' tcx > ,
27
- trait_ref : ty:: PolyTraitRef < ' tcx > ,
27
+ poly_trait_ref : Option < ty:: PolyExistentialTraitRef < ' tcx > > ,
28
28
) -> EvalResult < ' tcx , Pointer < M :: PointerTag > > {
29
- debug ! ( "get_vtable(trait_ref={:?})" , trait_ref ) ;
29
+ debug ! ( "get_vtable(trait_ref={:?})" , poly_trait_ref ) ;
30
30
31
- if let Some ( & vtable) = self . vtables . get ( & ( ty, trait_ref) ) {
31
+ let ( ty, poly_trait_ref) = self . tcx . erase_regions ( & ( ty, poly_trait_ref) ) ;
32
+
33
+ if let Some ( & vtable) = self . vtables . get ( & ( ty, poly_trait_ref) ) {
32
34
return Ok ( Pointer :: from ( vtable) . with_default_tag ( ) ) ;
33
35
}
34
36
35
- let layout = self . layout_of ( trait_ref. self_ty ( ) ) ?;
37
+ let trait_ref = poly_trait_ref. map ( |trait_ref| {
38
+ let trait_ref = trait_ref. with_self_ty ( * self . tcx , ty) ;
39
+ self . tcx . erase_regions ( & trait_ref)
40
+ } ) ;
41
+
42
+ let methods = trait_ref. map ( |trait_ref| self . tcx . vtable_methods ( trait_ref) ) ;
43
+
44
+ let layout = self . layout_of ( ty) ?;
36
45
assert ! ( !layout. is_unsized( ) , "can't create a vtable for an unsized type" ) ;
37
46
let size = layout. size . bytes ( ) ;
38
47
let align = layout. align . abi ( ) ;
39
48
40
49
let ptr_size = self . pointer_size ( ) ;
41
50
let ptr_align = self . tcx . data_layout . pointer_align ;
42
- let methods = self . tcx . vtable_methods ( trait_ref) ;
43
51
let vtable = self . memory . allocate (
44
- ptr_size * ( 3 + methods. len ( ) as u64 ) ,
52
+ ptr_size * ( 3 + methods. as_ref ( ) . map_or ( 0 , |m| m . len ( ) as u64 ) ) ,
45
53
ptr_align,
46
54
MemoryKind :: Vtable ,
47
55
) ?;
@@ -56,17 +64,19 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
56
64
self . memory . write_ptr_sized ( align_ptr, ptr_align,
57
65
Scalar :: from_uint ( align, ptr_size) . into ( ) ) ?;
58
66
59
- for ( i, method) in methods. iter ( ) . enumerate ( ) {
60
- if let Some ( ( def_id, substs) ) = * method {
61
- let instance = self . resolve ( def_id, substs) ?;
62
- let fn_ptr = self . memory . create_fn_alloc ( instance) ;
63
- let method_ptr = vtable. offset ( ptr_size * ( 3 + i as u64 ) , & self ) ?;
64
- self . memory . write_ptr_sized ( method_ptr, ptr_align, Scalar :: Ptr ( fn_ptr) . into ( ) ) ?;
67
+ if let Some ( methods) = methods {
68
+ for ( i, method) in methods. iter ( ) . enumerate ( ) {
69
+ if let Some ( ( def_id, substs) ) = * method {
70
+ let instance = self . resolve ( def_id, substs) ?;
71
+ let fn_ptr = self . memory . create_fn_alloc ( instance) ;
72
+ let method_ptr = vtable. offset ( ptr_size * ( 3 + i as u64 ) , & self ) ?;
73
+ self . memory . write_ptr_sized ( method_ptr, ptr_align, Scalar :: Ptr ( fn_ptr) . into ( ) ) ?;
74
+ }
65
75
}
66
76
}
67
77
68
78
self . memory . mark_immutable ( vtable. alloc_id ) ?;
69
- assert ! ( self . vtables. insert( ( ty, trait_ref ) , vtable. alloc_id) . is_none( ) ) ;
79
+ assert ! ( self . vtables. insert( ( ty, poly_trait_ref ) , vtable. alloc_id) . is_none( ) ) ;
70
80
71
81
Ok ( vtable)
72
82
}
0 commit comments