@@ -319,12 +319,58 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
319
319
FulfillmentErrorCode < ' tcx > >
320
320
{
321
321
match process_predicate1 ( selcx, pending_obligation, backtrace, region_obligations) {
322
- Ok ( Some ( v) ) => Ok ( Some ( v. into_iter ( )
323
- . map ( |o| PendingPredicateObligation {
324
- obligation : o,
325
- stalled_on : vec ! [ ]
326
- } )
327
- . collect ( ) ) ) ,
322
+ Ok ( Some ( v) ) => {
323
+ // FIXME the right thing to do here, I think, is to permit
324
+ // DAGs. That is, we should detect whenever this predicate
325
+ // has appeared somewhere in the current tree./ If it's a
326
+ // parent, that's a cycle, and we should either error out
327
+ // or consider it ok. But if it's NOT a parent, we can
328
+ // ignore it, since it will be proven (or not) separately.
329
+ // However, this is a touch tricky, so I'm doing something
330
+ // a bit hackier for now so that the `huge-struct.rs` passes.
331
+
332
+ let retain_vec: Vec < _ > = {
333
+ let mut dedup = FnvHashSet ( ) ;
334
+ v. iter ( )
335
+ . map ( |o| {
336
+ // Screen out obligations that we know globally
337
+ // are true. This should really be the DAG check
338
+ // mentioned above.
339
+ if
340
+ o. predicate . is_global ( ) &&
341
+ selcx. tcx ( ) . fulfilled_predicates . borrow ( ) . is_duplicate ( & o. predicate )
342
+ {
343
+ return false ;
344
+ }
345
+
346
+ // If we see two siblings that are exactly the
347
+ // same, no need to add them twice.
348
+ if !dedup. insert ( & o. predicate ) {
349
+ return false ;
350
+ }
351
+
352
+ true
353
+ } )
354
+ . collect ( )
355
+ } ;
356
+
357
+ let pending_predicate_obligations =
358
+ v. into_iter ( )
359
+ . zip ( retain_vec)
360
+ . flat_map ( |( o, retain) | {
361
+ if retain {
362
+ Some ( PendingPredicateObligation {
363
+ obligation : o,
364
+ stalled_on : vec ! [ ]
365
+ } )
366
+ } else {
367
+ None
368
+ }
369
+ } )
370
+ . collect ( ) ;
371
+
372
+ Ok ( Some ( pending_predicate_obligations) )
373
+ }
328
374
Ok ( None ) => Ok ( None ) ,
329
375
Err ( e) => Err ( e)
330
376
}
0 commit comments