@@ -356,29 +356,38 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
356356 return IntersectionHasImpossibleObligations :: Yes ;
357357 }
358358
359- let ocx = ObligationCtxt :: new_with_diagnostics ( infcx) ;
359+ let ocx = ObligationCtxt :: new ( infcx) ;
360360 ocx. register_obligations ( obligations. iter ( ) . cloned ( ) ) ;
361+ let hard_errors = ocx. select_where_possible ( ) ;
362+ if !hard_errors. is_empty ( ) {
363+ assert ! (
364+ hard_errors. iter( ) . all( |e| e. is_true_error( ) ) ,
365+ "should not have detected ambiguity during first pass"
366+ ) ;
367+ return IntersectionHasImpossibleObligations :: Yes ;
368+ }
369+
370+ // Make a new `ObligationCtxt` and re-prove the ambiguities with a richer
371+ // `FulfillmentError`. This is so that we can detect overflowing obligations
372+ // without needing to run the `BestBestObligation` visitor on true errors.
373+ let ambiguities = ocx. into_pending_obligations ( ) ;
374+ let ocx = ObligationCtxt :: new_with_diagnostics ( infcx) ;
375+ ocx. register_obligations ( ambiguities) ;
361376 let errors_and_ambiguities = ocx. select_all_or_error ( ) ;
362377 // We only care about the obligations that are *definitely* true errors.
363378 // Ambiguities do not prove the disjointness of two impls.
364379 let ( errors, ambiguities) : ( Vec < _ > , Vec < _ > ) =
365380 errors_and_ambiguities. into_iter ( ) . partition ( |error| error. is_true_error ( ) ) ;
366-
367- if errors. is_empty ( ) {
368- IntersectionHasImpossibleObligations :: No {
369- overflowing_predicates : ambiguities
370- . into_iter ( )
371- . filter ( |error| {
372- matches ! (
373- error. code,
374- FulfillmentErrorCode :: Ambiguity { overflow: Some ( true ) }
375- )
376- } )
377- . map ( |e| infcx. resolve_vars_if_possible ( e. obligation . predicate ) )
378- . collect ( ) ,
379- }
380- } else {
381- IntersectionHasImpossibleObligations :: Yes
381+ assert ! ( errors. is_empty( ) , "should not have ambiguities during second pass" ) ;
382+
383+ IntersectionHasImpossibleObligations :: No {
384+ overflowing_predicates : ambiguities
385+ . into_iter ( )
386+ . filter ( |error| {
387+ matches ! ( error. code, FulfillmentErrorCode :: Ambiguity { overflow: Some ( true ) } )
388+ } )
389+ . map ( |e| infcx. resolve_vars_if_possible ( e. obligation . predicate ) )
390+ . collect ( ) ,
382391 }
383392 } else {
384393 for obligation in obligations {
0 commit comments