@@ -14,9 +14,8 @@ use rustc_hir::lang_items::LangItem;
14
14
use rustc_hir:: ItemKind ;
15
15
use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
16
16
use rustc_infer:: infer:: outlives:: obligations:: TypeOutlives ;
17
+ use rustc_infer:: infer:: TyCtxtInferExt ;
17
18
use rustc_infer:: infer:: { self , RegionckMode , SubregionOrigin } ;
18
- use rustc_infer:: infer:: { RegionResolutionError , TyCtxtInferExt } ;
19
- use rustc_infer:: traits:: TraitEngine ;
20
19
use rustc_middle:: hir:: map as hir_map;
21
20
use rustc_middle:: ty:: subst:: { GenericArgKind , InternalSubsts , Subst } ;
22
21
use rustc_middle:: ty:: trait_def:: TraitSpecializationKind ;
@@ -27,9 +26,7 @@ use rustc_session::parse::feature_err;
27
26
use rustc_span:: symbol:: { sym, Ident , Symbol } ;
28
27
use rustc_span:: { Span , DUMMY_SP } ;
29
28
use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
30
- use rustc_trait_selection:: traits:: {
31
- self , ObligationCause , ObligationCauseCode , TraitEngineExt , WellFormedLoc ,
32
- } ;
29
+ use rustc_trait_selection:: traits:: { self , ObligationCause , ObligationCauseCode , WellFormedLoc } ;
33
30
34
31
use std:: convert:: TryInto ;
35
32
use std:: iter;
@@ -435,99 +432,70 @@ fn check_gat_where_clauses(
435
432
if !clauses. is_empty ( ) {
436
433
let param_env = tcx. param_env ( trait_item. def_id ) ;
437
434
438
- // This shouldn't really matter, but we need it
439
- let cause = traits:: ObligationCause :: new (
440
- trait_item. span ,
441
- trait_item. hir_id ( ) ,
442
- ObligationCauseCode :: MiscObligation ,
443
- ) ;
444
- // Create an `InferCtxt` to try to prove the clauses we require
445
- tcx. infer_ctxt ( ) . enter ( |infcx| {
446
- let mut fulfillment_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
447
-
448
- // Register all the clauses as obligations
449
- clauses
450
- . clone ( )
451
- . into_iter ( )
452
- . map ( |predicate| {
453
- traits:: Obligation :: new (
454
- cause. clone ( ) ,
435
+ let mut clauses: Vec < _ > = clauses
436
+ . into_iter ( )
437
+ . filter ( |clause| match clause. kind ( ) . skip_binder ( ) {
438
+ ty:: PredicateKind :: RegionOutlives ( ty:: OutlivesPredicate ( a, b) ) => {
439
+ !region_known_to_outlive (
440
+ tcx,
441
+ trait_item. hir_id ( ) ,
455
442
param_env,
456
- predicate,
443
+ & FxHashSet :: default ( ) ,
444
+ a,
445
+ b,
457
446
)
458
- } )
459
- . for_each ( |obligation| {
460
- fulfillment_cx. register_predicate_obligation ( & infcx, obligation)
461
- } ) ;
462
-
463
- // Convert these obligations into constraints by selecting
464
- let errors = fulfillment_cx. select_all_or_error ( & infcx) ;
465
- if !errors. is_empty ( ) {
466
- bug ! ( "should have only registered region obligations, which get registerd as constraints" ) ;
467
- }
447
+ }
448
+ ty:: PredicateKind :: TypeOutlives ( ty:: OutlivesPredicate ( a, b) ) => {
449
+ !ty_known_to_outlive (
450
+ tcx,
451
+ trait_item. hir_id ( ) ,
452
+ param_env,
453
+ & FxHashSet :: default ( ) ,
454
+ a,
455
+ b,
456
+ )
457
+ }
458
+ _ => bug ! ( "Unexpected PredicateKind" ) ,
459
+ } )
460
+ . map ( |clause| format ! ( "{}" , clause) )
461
+ . collect ( ) ;
468
462
469
- // FIXME(jackh726): some of this code is shared with `regionctxt`, but in a different
470
- // flow; we could probably better extract the shared logic
471
-
472
- // Process the region obligations
473
- let body_id_map = infcx
474
- . inner
475
- . borrow ( )
476
- . region_obligations ( )
477
- . iter ( )
478
- . map ( |& ( id, _) | ( id, vec ! [ ] ) )
479
- . collect ( ) ;
480
-
481
- infcx. process_registered_region_obligations ( & body_id_map, None , param_env) ;
482
-
483
- // Resolve the region constraints to find any constraints that we're provable
484
- let outlives_env = OutlivesEnvironment :: new ( param_env) ;
485
- let errors = infcx. resolve_regions ( trait_item. def_id . to_def_id ( ) , & outlives_env, RegionckMode :: default ( ) ) ;
486
-
487
- // Emit an error if there are non-provable constriants
488
- if !errors. is_empty ( ) {
489
- let mut clauses: Vec < _ > = errors. into_iter ( ) . map ( |error| match error {
490
- RegionResolutionError :: ConcreteFailure ( _, sup, sub) => format ! ( "{}: {}" , sub, sup) ,
491
- RegionResolutionError :: GenericBoundFailure ( _, sub, sup) => format ! ( "{}: {}" , sub, sup) ,
492
- _ => bug ! ( "Unexpected region resolution error when resolving outlives lint" ) ,
493
- } ) . collect ( ) ;
494
- clauses. sort ( ) ;
495
-
496
- let plural = if clauses. len ( ) > 1 { "s" } else { "" } ;
497
- let mut err = tcx. sess . struct_span_err (
498
- trait_item. span ,
499
- & format ! ( "missing required bound{} on `{}`" , plural, trait_item. ident) ,
500
- ) ;
463
+ // We sort so that order is predictable
464
+ clauses. sort ( ) ;
501
465
502
- let suggestion = format ! (
503
- "{} {}" ,
504
- if !trait_item. generics. where_clause. predicates. is_empty( ) {
505
- ","
506
- } else {
507
- " where"
508
- } ,
509
- clauses. join( ", " ) ,
510
- ) ;
511
- err. span_suggestion (
512
- trait_item. generics . where_clause . tail_span_for_suggestion ( ) ,
513
- & format ! ( "add the required where clause{}" , plural) ,
514
- suggestion,
515
- Applicability :: MachineApplicable ,
516
- ) ;
466
+ if !clauses. is_empty ( ) {
467
+ let plural = if clauses. len ( ) > 1 { "s" } else { "" } ;
468
+ let mut err = tcx. sess . struct_span_err (
469
+ trait_item. span ,
470
+ & format ! ( "missing required bound{} on `{}`" , plural, trait_item. ident) ,
471
+ ) ;
517
472
518
- let bound = if clauses. len ( ) > 1 { "these bounds are" } else { "this bound is" } ;
519
- err. note (
520
- & format ! ( "{} required to ensure that impls have maximum flexibility" , bound)
521
- ) ;
522
- err. note (
523
- "see issue #87479 \
524
- <https://github.com/rust-lang/rust/issues/87479> \
525
- for more information",
526
- ) ;
473
+ let suggestion = format ! (
474
+ "{} {}" ,
475
+ if !trait_item. generics. where_clause. predicates. is_empty( ) {
476
+ ","
477
+ } else {
478
+ " where"
479
+ } ,
480
+ clauses. join( ", " ) ,
481
+ ) ;
482
+ err. span_suggestion (
483
+ trait_item. generics . where_clause . tail_span_for_suggestion ( ) ,
484
+ & format ! ( "add the required where clause{}" , plural) ,
485
+ suggestion,
486
+ Applicability :: MachineApplicable ,
487
+ ) ;
527
488
528
- err. emit ( )
529
- }
530
- } ) ;
489
+ let bound = if clauses. len ( ) > 1 { "these bounds are" } else { "this bound is" } ;
490
+ err. note ( & format ! ( "{} required to ensure that impls have maximum flexibility" , bound) ) ;
491
+ err. note (
492
+ "see issue #87479 \
493
+ <https://github.com/rust-lang/rust/issues/87479> \
494
+ for more information",
495
+ ) ;
496
+
497
+ err. emit ( )
498
+ }
531
499
}
532
500
}
533
501
0 commit comments