@@ -196,44 +196,19 @@ impl History {
196
196
History { events : Vec :: new ( ) , created : self . created , tag : self . tag }
197
197
}
198
198
199
- /// Reconstruct the history relevant to `error_offset` knowing that
200
- /// its permission followed `complete_transition`.
201
- ///
202
- /// Here's how we do this:
203
- /// - we know `full := complete_transition` the transition of the permission from
204
- /// its initialization to the state just before the error was caused,
205
- /// we want to find a chain of events that produces `full`
206
- /// - we decompose `full` into `pre o post` where
207
- /// `pre` is the best applicable transition from recorded events
208
- /// - we select the event that caused `pre` and iterate
209
- /// to find the chain of events that produces `full := post`
210
- ///
211
- /// To find the "best applicable transition" for full:
212
- /// - eliminate events that cannot be applied because their offset is too big
213
- /// - eliminate events that cannot be applied because their starting point is wrong
214
- /// - select the one that happened closest to the range of interest
215
- fn extract_relevant ( & self , complete_transition : PermTransition , error_offset : Size ) -> Self {
216
- let mut selected_events: Vec < Event > = Vec :: new ( ) ;
217
- let mut full = complete_transition;
218
- while !full. is_noop ( ) {
219
- let ( pre, post) = self
199
+ /// Reconstruct the history relevant to `error_offset` by filtering
200
+ /// only events whose range contains the offset we are interested in.
201
+ fn extract_relevant ( & self , error_offset : u64 ) -> Self {
202
+ History {
203
+ events : self
220
204
. events
221
205
. iter ( )
222
- . filter ( |e| e. offset <= error_offset)
223
- . filter_map ( |pre_canditate| {
224
- full. apply_start ( pre_canditate. transition )
225
- . map ( |post_canditate| ( pre_canditate, post_canditate) )
226
- } )
227
- . max_by_key ( |( pre_canditate, _post_candidate) | pre_canditate. offset )
228
- . unwrap ( ) ;
229
- // If this occurs we will loop infinitely !
230
- // Make sure to only put non-noop transitions in `History`.
231
- assert ! ( !pre. transition. is_noop( ) ) ;
232
- full = post;
233
- selected_events. push ( pre. clone ( ) ) ;
206
+ . filter ( |e| e. offset . start <= error_offset && error_offset < e. offset . end )
207
+ . cloned ( )
208
+ . collect :: < Vec < _ > > ( ) ,
209
+ created : self . created ,
210
+ tag : self . tag ,
234
211
}
235
-
236
- History { events : selected_events, created : self . created , tag : self . tag }
237
212
}
238
213
}
239
214
@@ -260,12 +235,11 @@ impl TbError<'_> {
260
235
/// Produce a UB error.
261
236
pub fn build < ' tcx > ( self ) -> InterpError < ' tcx > {
262
237
use TransitionError :: * ;
263
- let started_as = self . conflicting_info . history . created . 1 ;
264
238
let kind = self . access_kind ;
265
239
let accessed = self . accessed_info ;
266
240
let conflicting = self . conflicting_info ;
267
241
let accessed_is_conflicting = accessed. tag == conflicting. tag ;
268
- let ( pre_error , title, details, conflicting_tag_name) = match self . error_kind {
242
+ let ( title, details, conflicting_tag_name) = match self . error_kind {
269
243
ChildAccessForbidden ( perm) => {
270
244
let conflicting_tag_name =
271
245
if accessed_is_conflicting { "accessed" } else { "conflicting" } ;
@@ -279,7 +253,7 @@ impl TbError<'_> {
279
253
details. push ( format ! (
280
254
"the {conflicting_tag_name} tag {conflicting} has state {perm} which forbids child {kind}es"
281
255
) ) ;
282
- ( perm , title, details, conflicting_tag_name)
256
+ ( title, details, conflicting_tag_name)
283
257
}
284
258
ProtectedTransition ( transition) => {
285
259
let conflicting_tag_name = "protected" ;
@@ -296,7 +270,7 @@ impl TbError<'_> {
296
270
loss = transition. summary( ) ,
297
271
) ,
298
272
] ;
299
- ( transition . started ( ) , title, details, conflicting_tag_name)
273
+ ( title, details, conflicting_tag_name)
300
274
}
301
275
ProtectedDealloc => {
302
276
let conflicting_tag_name = "strongly protected" ;
@@ -307,16 +281,15 @@ impl TbError<'_> {
307
281
) ,
308
282
format!( "the {conflicting_tag_name} tag {conflicting} disallows deallocations" ) ,
309
283
] ;
310
- ( started_as , title, details, conflicting_tag_name)
284
+ ( title, details, conflicting_tag_name)
311
285
}
312
286
} ;
313
- let pre_transition = PermTransition :: from ( started_as, pre_error) . unwrap ( ) ;
314
287
let mut history = HistoryData :: default ( ) ;
315
288
if !accessed_is_conflicting {
316
289
history. extend ( self . accessed_info . history . forget ( ) , "accessed" , false ) ;
317
290
}
318
291
history. extend (
319
- self . conflicting_info . history . extract_relevant ( pre_transition , self . error_offset ) ,
292
+ self . conflicting_info . history . extract_relevant ( self . error_offset ) ,
320
293
conflicting_tag_name,
321
294
true ,
322
295
) ;
0 commit comments