@@ -17,7 +17,7 @@ use crate::traits::{
17
17
use rustc_errors:: Diagnostic ;
18
18
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
19
19
use rustc_hir:: CRATE_HIR_ID ;
20
- use rustc_infer:: infer:: TyCtxtInferExt ;
20
+ use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
21
21
use rustc_infer:: traits:: { util, TraitEngine } ;
22
22
use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
23
23
use rustc_middle:: ty:: fast_reject:: { self , TreatParams } ;
@@ -361,46 +361,62 @@ fn negative_impl_exists<'cx, 'tcx>(
361
361
o : & PredicateObligation < ' tcx > ,
362
362
) -> bool {
363
363
let infcx = & selcx. infcx ( ) . fork ( ) ;
364
- let tcx = infcx. tcx ;
365
364
366
- let super_obligations = util:: elaborate_predicates ( tcx, iter:: once ( o. predicate ) ) ;
365
+ if resolve_negative_obligation ( infcx, param_env, region_context, o) {
366
+ return true ;
367
+ }
367
368
368
- for o in iter:: once ( o. clone ( ) ) . chain ( super_obligations) {
369
- if let Some ( o) = o. flip_polarity ( tcx) {
370
- let mut fulfillment_cx = FulfillmentContext :: new ( ) ;
371
- fulfillment_cx. register_predicate_obligation ( infcx, o) ;
369
+ for o in util:: elaborate_predicates ( infcx. tcx , iter:: once ( o. predicate ) ) {
370
+ if resolve_negative_obligation ( infcx, param_env, region_context, & o) {
371
+ return true ;
372
+ }
373
+ }
372
374
373
- let errors = fulfillment_cx. select_all_or_error ( infcx) ;
375
+ false
376
+ }
374
377
375
- if !errors. is_empty ( ) {
376
- continue ;
377
- }
378
+ #[ instrument( level = "debug" , skip( infcx) ) ]
379
+ fn resolve_negative_obligation < ' cx , ' tcx > (
380
+ infcx : & InferCtxt < ' cx , ' tcx > ,
381
+ param_env : ty:: ParamEnv < ' tcx > ,
382
+ region_context : DefId ,
383
+ o : & PredicateObligation < ' tcx > ,
384
+ ) -> bool {
385
+ let tcx = infcx. tcx ;
378
386
379
- let mut outlives_env = OutlivesEnvironment :: new ( param_env) ;
380
- // FIXME -- add "assumed to be well formed" types into the `outlives_env`
387
+ if let Some ( o) = o. flip_polarity ( tcx) {
388
+ let mut fulfillment_cx = FulfillmentContext :: new ( ) ;
389
+ fulfillment_cx. register_predicate_obligation ( infcx, o) ;
381
390
382
- // "Save" the accumulated implied bounds into the outlives environment
383
- // (due to the FIXME above, there aren't any, but this step is still needed).
384
- // The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used
385
- // by the "dummy" causes elsewhere (body-id is only relevant when checking
386
- // function bodies with closures).
387
- outlives_env. save_implied_bounds ( CRATE_HIR_ID ) ;
391
+ let errors = fulfillment_cx. select_all_or_error ( infcx) ;
388
392
389
- infcx. process_registered_region_obligations (
390
- outlives_env. region_bound_pairs_map ( ) ,
391
- Some ( tcx. lifetimes . re_root_empty ) ,
392
- param_env,
393
- ) ;
393
+ if !errors. is_empty ( ) {
394
+ return false ;
395
+ }
394
396
395
- let errors =
396
- infcx . resolve_regions ( region_context , & outlives_env , RegionckMode :: default ( ) ) ;
397
+ let mut outlives_env = OutlivesEnvironment :: new ( param_env ) ;
398
+ // FIXME -- add "assumed to be well formed" types into the `outlives_env`
397
399
398
- if !errors. is_empty ( ) {
399
- continue ;
400
- }
400
+ // "Save" the accumulated implied bounds into the outlives environment
401
+ // (due to the FIXME above, there aren't any, but this step is still needed).
402
+ // The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used
403
+ // by the "dummy" causes elsewhere (body-id is only relevant when checking
404
+ // function bodies with closures).
405
+ outlives_env. save_implied_bounds ( CRATE_HIR_ID ) ;
401
406
402
- return true ;
407
+ infcx. process_registered_region_obligations (
408
+ outlives_env. region_bound_pairs_map ( ) ,
409
+ Some ( tcx. lifetimes . re_root_empty ) ,
410
+ param_env,
411
+ ) ;
412
+
413
+ let errors = infcx. resolve_regions ( region_context, & outlives_env, RegionckMode :: default ( ) ) ;
414
+
415
+ if !errors. is_empty ( ) {
416
+ return false ;
403
417
}
418
+
419
+ return true ;
404
420
}
405
421
406
422
false
0 commit comments