@@ -18,7 +18,7 @@ use rustc_errors::Diagnostic;
1818use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
1919use rustc_hir:: CRATE_HIR_ID ;
2020use rustc_infer:: infer:: TyCtxtInferExt ;
21- use rustc_infer:: traits:: TraitEngine ;
21+ use rustc_infer:: traits:: { util , TraitEngine } ;
2222use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
2323use rustc_middle:: ty:: fast_reject:: { self , TreatParams } ;
2424use rustc_middle:: ty:: fold:: TypeFoldable ;
@@ -353,6 +353,7 @@ fn negative_impl<'cx, 'tcx>(
353353 } )
354354}
355355
356+ #[ instrument( level = "debug" , skip( selcx) ) ]
356357fn negative_impl_exists < ' cx , ' tcx > (
357358 selcx : & SelectionContext < ' cx , ' tcx > ,
358359 param_env : ty:: ParamEnv < ' tcx > ,
@@ -361,14 +362,18 @@ fn negative_impl_exists<'cx, 'tcx>(
361362) -> bool {
362363 let infcx = & selcx. infcx ( ) . fork ( ) ;
363364 let tcx = infcx. tcx ;
364- o. flip_polarity ( tcx)
365- . map ( |o| {
365+
366+ let super_obligations = util:: elaborate_predicates ( tcx, iter:: once ( o. predicate ) ) ;
367+
368+ for o in iter:: once ( o. clone ( ) ) . chain ( super_obligations) {
369+ if let Some ( o) = o. flip_polarity ( tcx) {
366370 let mut fulfillment_cx = FulfillmentContext :: new ( ) ;
367371 fulfillment_cx. register_predicate_obligation ( infcx, o) ;
368372
369373 let errors = fulfillment_cx. select_all_or_error ( infcx) ;
374+
370375 if !errors. is_empty ( ) {
371- return false ;
376+ continue ;
372377 }
373378
374379 let mut outlives_env = OutlivesEnvironment :: new ( param_env) ;
@@ -389,13 +394,16 @@ fn negative_impl_exists<'cx, 'tcx>(
389394
390395 let errors =
391396 infcx. resolve_regions ( region_context, & outlives_env, RegionckMode :: default ( ) ) ;
397+
392398 if !errors. is_empty ( ) {
393- return false ;
399+ continue ;
394400 }
395401
396- true
397- } )
398- . unwrap_or ( false )
402+ return true ;
403+ }
404+ }
405+
406+ false
399407}
400408
401409pub fn trait_ref_is_knowable < ' tcx > (
0 commit comments