@@ -33,13 +33,13 @@ impl<Tag> ScalarExt for ScalarMaybeUndef<Tag> {
3333pub trait EvalContextExt < ' tcx > {
3434 fn resolve_path ( & self , path : & [ & str ] ) -> EvalResult < ' tcx , ty:: Instance < ' tcx > > ;
3535
36- /// Visit the memory covered by `place` that is frozen -- i.e., NOT
37- /// what is inside an `UnsafeCell`.
38- fn visit_frozen (
36+ /// Visit the memory covered by `place`, sensitive to freezing: The 3rd parameter
37+ /// will be true if this is frozen, false if this is in an `UnsafeCell`.
38+ fn visit_freeze_sensitive (
3939 & self ,
4040 place : MPlaceTy < ' tcx , Borrow > ,
4141 size : Size ,
42- action : impl FnMut ( Pointer < Borrow > , Size ) -> EvalResult < ' tcx > ,
42+ action : impl FnMut ( Pointer < Borrow > , Size , bool ) -> EvalResult < ' tcx > ,
4343 ) -> EvalResult < ' tcx > ;
4444}
4545
@@ -79,13 +79,11 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
7979 } )
8080 }
8181
82- /// Visit the memory covered by `place` that is frozen -- i.e., NOT
83- /// what is inside an `UnsafeCell`.
84- fn visit_frozen (
82+ fn visit_freeze_sensitive (
8583 & self ,
8684 place : MPlaceTy < ' tcx , Borrow > ,
8785 size : Size ,
88- mut frozen_action : impl FnMut ( Pointer < Borrow > , Size ) -> EvalResult < ' tcx > ,
86+ mut action : impl FnMut ( Pointer < Borrow > , Size , bool ) -> EvalResult < ' tcx > ,
8987 ) -> EvalResult < ' tcx > {
9088 trace ! ( "visit_frozen(place={:?}, size={:?})" , * place, size) ;
9189 debug_assert_eq ! ( size,
@@ -99,18 +97,29 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
9997 let mut end_ptr = place. ptr ;
10098 // Called when we detected an `UnsafeCell` at the given offset and size.
10199 // Calls `action` and advances `end_ptr`.
102- let mut unsafe_cell_action = |unsafe_cell_offset, unsafe_cell_size| {
100+ let mut unsafe_cell_action = |unsafe_cell_ptr : Scalar < Borrow > , unsafe_cell_size : Size | {
101+ if unsafe_cell_size != Size :: ZERO {
102+ debug_assert_eq ! ( unsafe_cell_ptr. to_ptr( ) . unwrap( ) . alloc_id,
103+ end_ptr. to_ptr( ) . unwrap( ) . alloc_id) ;
104+ debug_assert_eq ! ( unsafe_cell_ptr. to_ptr( ) . unwrap( ) . tag,
105+ end_ptr. to_ptr( ) . unwrap( ) . tag) ;
106+ }
103107 // We assume that we are given the fields in increasing offset order,
104108 // and nothing else changes.
109+ let unsafe_cell_offset = unsafe_cell_ptr. get_ptr_offset ( self ) ;
105110 let end_offset = end_ptr. get_ptr_offset ( self ) ;
106111 assert ! ( unsafe_cell_offset >= end_offset) ;
107112 let frozen_size = unsafe_cell_offset - end_offset;
108113 // Everything between the end_ptr and this `UnsafeCell` is frozen.
109114 if frozen_size != Size :: ZERO {
110- frozen_action ( end_ptr. to_ptr ( ) ?, frozen_size) ?;
115+ action ( end_ptr. to_ptr ( ) ?, frozen_size, /*frozen*/ true ) ?;
116+ }
117+ // This `UnsafeCell` is NOT frozen.
118+ if unsafe_cell_size != Size :: ZERO {
119+ action ( unsafe_cell_ptr. to_ptr ( ) ?, unsafe_cell_size, /*frozen*/ false ) ?;
111120 }
112121 // Update end end_ptr.
113- end_ptr = end_ptr . ptr_wrapping_offset ( frozen_size+ unsafe_cell_size, self ) ;
122+ end_ptr = unsafe_cell_ptr . ptr_wrapping_offset ( unsafe_cell_size, self ) ;
114123 // Done
115124 Ok ( ( ) )
116125 } ;
@@ -126,7 +135,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
126135 . unwrap_or_else ( || place. layout . size_and_align ( ) ) ;
127136 // Now handle this `UnsafeCell`, unless it is empty.
128137 if unsafe_cell_size != Size :: ZERO {
129- unsafe_cell_action ( place. ptr . get_ptr_offset ( self ) , unsafe_cell_size)
138+ unsafe_cell_action ( place. ptr , unsafe_cell_size)
130139 } else {
131140 Ok ( ( ) )
132141 }
@@ -136,7 +145,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
136145 }
137146 // The part between the end_ptr and the end of the place is also frozen.
138147 // So pretend there is a 0-sized `UnsafeCell` at the end.
139- unsafe_cell_action ( place. ptr . get_ptr_offset ( self ) + size , Size :: ZERO ) ?;
148+ unsafe_cell_action ( place. ptr . ptr_wrapping_offset ( size , self ) , Size :: ZERO ) ?;
140149 // Done!
141150 return Ok ( ( ) ) ;
142151
0 commit comments