@@ -45,6 +45,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
45
45
if self . tcx . sess . opts . debugging_opts . mir_emit_validate == 0 {
46
46
return Ok ( ( ) ) ;
47
47
}
48
+ debug_assert ! ( self . memory. cur_frame == self . cur_frame( ) ) ;
48
49
49
50
// HACK: Determine if this method is whitelisted and hence we do not perform any validation.
50
51
// We currently insta-UB on anything passing around uninitialized memory, so we have to whitelist
@@ -93,7 +94,8 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
93
94
if query. mutbl == MutMutable {
94
95
let lft = DynamicLifetime {
95
96
frame : self . cur_frame ( ) ,
96
- region : Some ( scope) ,
97
+ region : Some ( scope) , // Notably, we only ever suspend things for given regions.
98
+ // Suspending for the entire function does not make any sense.
97
99
} ;
98
100
trace ! ( "Suspending {:?} until {:?}" , query, scope) ;
99
101
self . suspended . entry ( lft) . or_insert_with ( Vec :: new) . push (
@@ -106,17 +108,30 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
106
108
self . validate ( query, mode)
107
109
}
108
110
109
- pub ( crate ) fn end_region ( & mut self , scope : region:: Scope ) -> EvalResult < ' tcx > {
110
- self . memory . locks_lifetime_ended ( Some ( scope) ) ;
111
- // Recover suspended lvals
112
- let lft = DynamicLifetime {
113
- frame : self . cur_frame ( ) ,
114
- region : Some ( scope) ,
115
- } ;
116
- if let Some ( queries) = self . suspended . remove ( & lft) {
117
- for query in queries {
118
- trace ! ( "Recovering {:?} from suspension" , query) ;
119
- self . validate ( query, ValidationMode :: Recover ( scope) ) ?;
111
+ /// Release locks and executes suspensions of the given region (or the entire fn, in case of None).
112
+ pub ( crate ) fn end_region ( & mut self , scope : Option < region:: Scope > ) -> EvalResult < ' tcx > {
113
+ debug_assert ! ( self . memory. cur_frame == self . cur_frame( ) ) ;
114
+ self . memory . locks_lifetime_ended ( scope) ;
115
+ match scope {
116
+ Some ( scope) => {
117
+ // Recover suspended lvals
118
+ let lft = DynamicLifetime {
119
+ frame : self . cur_frame ( ) ,
120
+ region : Some ( scope) ,
121
+ } ;
122
+ if let Some ( queries) = self . suspended . remove ( & lft) {
123
+ for query in queries {
124
+ trace ! ( "Recovering {:?} from suspension" , query) ;
125
+ self . validate ( query, ValidationMode :: Recover ( scope) ) ?;
126
+ }
127
+ }
128
+ }
129
+ None => {
130
+ // Clean suspension table of current frame
131
+ let cur_frame = self . cur_frame ( ) ;
132
+ self . suspended . retain ( |lft, _| {
133
+ lft. frame != cur_frame // keep only what is in the other (lower) frames
134
+ } ) ;
120
135
}
121
136
}
122
137
Ok ( ( ) )
0 commit comments