@@ -33,13 +33,13 @@ impl<Tag> ScalarExt for ScalarMaybeUndef<Tag> {
33
33
pub trait EvalContextExt < ' tcx > {
34
34
fn resolve_path ( & self , path : & [ & str ] ) -> EvalResult < ' tcx , ty:: Instance < ' tcx > > ;
35
35
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 (
39
39
& self ,
40
40
place : MPlaceTy < ' tcx , Borrow > ,
41
41
size : Size ,
42
- action : impl FnMut ( Pointer < Borrow > , Size ) -> EvalResult < ' tcx > ,
42
+ action : impl FnMut ( Pointer < Borrow > , Size , bool ) -> EvalResult < ' tcx > ,
43
43
) -> EvalResult < ' tcx > ;
44
44
}
45
45
@@ -79,13 +79,11 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
79
79
} )
80
80
}
81
81
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 (
85
83
& self ,
86
84
place : MPlaceTy < ' tcx , Borrow > ,
87
85
size : Size ,
88
- mut frozen_action : impl FnMut ( Pointer < Borrow > , Size ) -> EvalResult < ' tcx > ,
86
+ mut action : impl FnMut ( Pointer < Borrow > , Size , bool ) -> EvalResult < ' tcx > ,
89
87
) -> EvalResult < ' tcx > {
90
88
trace ! ( "visit_frozen(place={:?}, size={:?})" , * place, size) ;
91
89
debug_assert_eq ! ( size,
@@ -99,18 +97,29 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
99
97
let mut end_ptr = place. ptr ;
100
98
// Called when we detected an `UnsafeCell` at the given offset and size.
101
99
// 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
+ }
103
107
// We assume that we are given the fields in increasing offset order,
104
108
// and nothing else changes.
109
+ let unsafe_cell_offset = unsafe_cell_ptr. get_ptr_offset ( self ) ;
105
110
let end_offset = end_ptr. get_ptr_offset ( self ) ;
106
111
assert ! ( unsafe_cell_offset >= end_offset) ;
107
112
let frozen_size = unsafe_cell_offset - end_offset;
108
113
// Everything between the end_ptr and this `UnsafeCell` is frozen.
109
114
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 ) ?;
111
120
}
112
121
// 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 ) ;
114
123
// Done
115
124
Ok ( ( ) )
116
125
} ;
@@ -126,7 +135,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
126
135
. unwrap_or_else ( || place. layout . size_and_align ( ) ) ;
127
136
// Now handle this `UnsafeCell`, unless it is empty.
128
137
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)
130
139
} else {
131
140
Ok ( ( ) )
132
141
}
@@ -136,7 +145,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
136
145
}
137
146
// The part between the end_ptr and the end of the place is also frozen.
138
147
// 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 ) ?;
140
149
// Done!
141
150
return Ok ( ( ) ) ;
142
151
0 commit comments