@@ -14,9 +14,8 @@ use rustc_hir::lang_items::LangItem;
1414use rustc_hir:: ItemKind ;
1515use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
1616use rustc_infer:: infer:: outlives:: obligations:: TypeOutlives ;
17+ use rustc_infer:: infer:: TyCtxtInferExt ;
1718use rustc_infer:: infer:: { self , RegionckMode , SubregionOrigin } ;
18- use rustc_infer:: infer:: { RegionResolutionError , TyCtxtInferExt } ;
19- use rustc_infer:: traits:: TraitEngine ;
2019use rustc_middle:: hir:: map as hir_map;
2120use rustc_middle:: ty:: subst:: { GenericArgKind , InternalSubsts , Subst } ;
2221use rustc_middle:: ty:: trait_def:: TraitSpecializationKind ;
@@ -27,9 +26,7 @@ use rustc_session::parse::feature_err;
2726use rustc_span:: symbol:: { sym, Ident , Symbol } ;
2827use rustc_span:: { Span , DUMMY_SP } ;
2928use 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 } ;
3330
3431use std:: convert:: TryInto ;
3532use std:: iter;
@@ -435,99 +432,70 @@ fn check_gat_where_clauses(
435432 if !clauses. is_empty ( ) {
436433 let param_env = tcx. param_env ( trait_item. def_id ) ;
437434
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 ( ) ,
455442 param_env,
456- predicate,
443+ & FxHashSet :: default ( ) ,
444+ a,
445+ b,
457446 )
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 ( ) ;
468462
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 ( ) ;
501465
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+ ) ;
517472
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+ ) ;
527488
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+ }
531499 }
532500}
533501
0 commit comments