@@ -12,7 +12,7 @@ pub(crate) trait UnmarkPolicy {
12
12
fn invert_marker ( iter : & mut StacklessPreOrderHeapIter < Self > ) where Self : Sized ;
13
13
fn cycle_detected ( & mut self ) where Self : Sized ;
14
14
fn mark_phase ( & self ) -> bool ;
15
- fn var_rooted_cycle ( _iter : & mut StacklessPreOrderHeapIter < Self > , _var_loc : usize , _next : usize )
15
+ fn var_rooted_cycle ( _iter : & mut StacklessPreOrderHeapIter < Self > , _next : usize )
16
16
where
17
17
Self : Sized { }
18
18
fn detect_list_tail_cycle ( _iter : & mut StacklessPreOrderHeapIter < Self > ) where Self : Sized { }
@@ -104,8 +104,8 @@ impl UnmarkPolicy for CycleDetectorUMP {
104
104
}
105
105
}
106
106
107
- fn var_rooted_cycle ( iter : & mut StacklessPreOrderHeapIter < Self > , var_loc : usize , next : usize ) {
108
- if var_loc != next && iter. iter_state . mark_phase && !iter. iter_state . cycle_detected {
107
+ fn var_rooted_cycle ( iter : & mut StacklessPreOrderHeapIter < Self > , next : usize ) {
108
+ if iter . current != next && iter. iter_state . mark_phase && !iter. iter_state . cycle_detected {
109
109
iter. iter_state . cycle_detected = iter. detect_list_cycle ( next) ;
110
110
}
111
111
}
@@ -279,9 +279,13 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
279
279
}
280
280
281
281
#[ inline]
282
- fn is_cyclic ( & self , var_current : usize , var_next : usize ) -> bool {
282
+ fn is_cyclic ( & self , var_current : usize , var_next : usize , var_f : bool ) -> bool {
283
283
if self . heap [ var_next] . is_var ( ) {
284
- self . heap [ var_next] . get_mark_bit ( ) && var_current != var_next
284
+ // the third conjunct covers the case where var_current
285
+ // was just unforwarded by forward_var() and so
286
+ // self.current + 1 == var_current. see acyclic_term#2121
287
+ // & acyclic_term_30 for examples of how this occurs.
288
+ self . heap [ var_next] . get_mark_bit ( ) && var_current != var_next && !var_f
285
289
} else if self . heap [ var_next] . is_ref ( ) {
286
290
self . heap [ var_next] . get_mark_bit ( )
287
291
} else {
@@ -298,15 +302,18 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
298
302
HeapCellValueTag :: AttrVar => {
299
303
let next = self . next ;
300
304
let current = self . current ;
305
+ let f = self . heap [ self . current ] . get_forwarding_bit ( ) ;
306
+
307
+ if self . heap [ next as usize ] . get_mark_bit ( ) == self . iter_state . mark_phase ( ) {
308
+ UMP :: var_rooted_cycle ( self , next as usize ) ;
309
+ }
301
310
302
311
if let Some ( cell) = UMP :: forward_attr_var ( self ) {
303
- if self . is_cyclic ( current, next as usize ) {
312
+ if self . is_cyclic ( current, next as usize , f ) {
304
313
self . iter_state . cycle_detected ( ) ;
305
314
}
306
315
307
316
return Some ( cell) ;
308
- } else if self . heap [ next as usize ] . get_mark_bit ( ) == self . iter_state . mark_phase ( ) {
309
- UMP :: var_rooted_cycle ( self , current, next as usize ) ;
310
317
}
311
318
312
319
if self . next < self . heap . len ( ) as u64 {
@@ -319,15 +326,18 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
319
326
HeapCellValueTag :: Var => {
320
327
let next = self . next ;
321
328
let current = self . current ;
329
+ let f = self . heap [ self . current ] . get_forwarding_bit ( ) ;
330
+
331
+ if self . heap [ next as usize ] . get_mark_bit ( ) == self . iter_state . mark_phase ( ) {
332
+ UMP :: var_rooted_cycle ( self , next as usize ) ;
333
+ }
322
334
323
335
if let Some ( cell) = self . forward_var ( ) {
324
- if self . is_cyclic ( current, next as usize ) {
336
+ if self . is_cyclic ( current, next as usize , f ) {
325
337
self . iter_state . cycle_detected ( ) ;
326
338
}
327
339
328
340
return Some ( cell) ;
329
- } else if self . heap [ next as usize ] . get_mark_bit ( ) == self . iter_state . mark_phase ( ) {
330
- UMP :: var_rooted_cycle ( self , current, next as usize ) ;
331
341
}
332
342
333
343
if self . next < self . heap . len ( ) as u64 {
@@ -462,11 +472,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
462
472
}
463
473
}
464
474
} else {
465
- if self . heap [ self . current ] . get_tag ( ) == HeapCellValueTag :: Lis {
466
- if UMP :: list_head_cycle_detecting_backward ( self ) {
467
- return None ;
468
- }
469
- } else if self . backward ( ) {
475
+ if self . backward ( ) {
470
476
return None ;
471
477
}
472
478
}
0 commit comments