@@ -18,10 +18,26 @@ use crate::delegation::inherit_predicates_for_delegation_item;
1818use crate :: hir_ty_lowering:: { HirTyLowerer , OnlySelfBounds , PredicateFilter , RegionInferReason } ;
1919
2020/// Returns a list of all type predicates (explicit and implicit) for the definition with
21- /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
22- /// `Self: Trait` predicates for traits.
21+ /// ID `def_id`. This includes all predicates returned by `explicit_predicates_of`, plus
22+ /// inferred constraints concerning which regions outlive other regions.
23+ #[ instrument( level = "debug" , skip( tcx) ) ]
2324pub ( super ) fn predicates_of ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> ty:: GenericPredicates < ' _ > {
24- let mut result = tcx. predicates_defined_on ( def_id) ;
25+ let mut result = tcx. explicit_predicates_of ( def_id) ;
26+ debug ! ( "predicates_of: explicit_predicates_of({:?}) = {:?}" , def_id, result) ;
27+
28+ let inferred_outlives = tcx. inferred_outlives_of ( def_id) ;
29+ if !inferred_outlives. is_empty ( ) {
30+ debug ! ( "predicates_of: inferred_outlives_of({:?}) = {:?}" , def_id, inferred_outlives, ) ;
31+ let inferred_outlives_iter =
32+ inferred_outlives. iter ( ) . map ( |( clause, span) | ( ( * clause) . upcast ( tcx) , * span) ) ;
33+ if result. predicates . is_empty ( ) {
34+ result. predicates = tcx. arena . alloc_from_iter ( inferred_outlives_iter) ;
35+ } else {
36+ result. predicates = tcx. arena . alloc_from_iter (
37+ result. predicates . into_iter ( ) . copied ( ) . chain ( inferred_outlives_iter) ,
38+ ) ;
39+ }
40+ }
2541
2642 if tcx. is_trait ( def_id) {
2743 // For traits, add `Self: Trait` predicate. This is
@@ -51,7 +67,8 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
5167 . chain ( std:: iter:: once ( ( ty:: TraitRef :: identity ( tcx, def_id) . upcast ( tcx) , span) ) ) ,
5268 ) ;
5369 }
54- debug ! ( "predicates_of(def_id={:?}) = {:?}" , def_id, result) ;
70+
71+ debug ! ( "predicates_of({:?}) = {:?}" , def_id, result) ;
5572 result
5673}
5774
@@ -442,122 +459,63 @@ fn const_evaluatable_predicates_of(
442459 collector. preds
443460}
444461
445- pub ( super ) fn trait_explicit_predicates_and_bounds (
446- tcx : TyCtxt < ' _ > ,
447- def_id : LocalDefId ,
448- ) -> ty:: GenericPredicates < ' _ > {
449- assert_eq ! ( tcx. def_kind( def_id) , DefKind :: Trait ) ;
450- gather_explicit_predicates_of ( tcx, def_id)
451- }
452-
453462pub ( super ) fn explicit_predicates_of < ' tcx > (
454463 tcx : TyCtxt < ' tcx > ,
455464 def_id : LocalDefId ,
456465) -> ty:: GenericPredicates < ' tcx > {
457466 let def_kind = tcx. def_kind ( def_id) ;
458- if let DefKind :: Trait = def_kind {
459- // Remove bounds on associated types from the predicates, they will be
460- // returned by `explicit_item_bounds`.
461- let predicates_and_bounds = tcx. trait_explicit_predicates_and_bounds ( def_id) ;
462- let trait_identity_args = ty:: GenericArgs :: identity_for_item ( tcx, def_id) ;
463-
464- let is_assoc_item_ty = |ty : Ty < ' tcx > | {
465- // For a predicate from a where clause to become a bound on an
466- // associated type:
467- // * It must use the identity args of the item.
468- // * We're in the scope of the trait, so we can't name any
469- // parameters of the GAT. That means that all we need to
470- // check are that the args of the projection are the
471- // identity args of the trait.
472- // * It must be an associated type for this trait (*not* a
473- // supertrait).
474- if let ty:: Alias ( ty:: Projection , projection) = ty. kind ( ) {
475- projection. args == trait_identity_args
476- // FIXME(return_type_notation): This check should be more robust
477- && !tcx. is_impl_trait_in_trait ( projection. def_id )
478- && tcx. associated_item ( projection. def_id ) . container_id ( tcx)
479- == def_id. to_def_id ( )
480- } else {
481- false
482- }
483- } ;
484-
485- let predicates: Vec < _ > = predicates_and_bounds
467+ if matches ! ( def_kind, DefKind :: AnonConst )
468+ && tcx. features ( ) . generic_const_exprs
469+ && let Some ( defaulted_param_def_id) =
470+ tcx. hir ( ) . opt_const_param_default_param_def_id ( tcx. local_def_id_to_hir_id ( def_id) )
471+ {
472+ // In `generics_of` we set the generics' parent to be our parent's parent which means that
473+ // we lose out on the predicates of our actual parent if we dont return those predicates here.
474+ // (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
475+ //
476+ // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
477+ // ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
478+ // ^^^ explicit_predicates_of on
479+ // parent item we dont have set as the
480+ // parent of generics returned by `generics_of`
481+ //
482+ // In the above code we want the anon const to have predicates in its param env for `T: Trait`
483+ // and we would be calling `explicit_predicates_of(Foo)` here
484+ let parent_def_id = tcx. local_parent ( def_id) ;
485+ let parent_preds = tcx. explicit_predicates_of ( parent_def_id) ;
486+
487+ // If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter
488+ // will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
489+ // to #106994 is implemented.
490+ let filtered_predicates = parent_preds
486491 . predicates
487- . iter ( )
488- . copied ( )
489- . filter ( |( pred, _) | match pred. kind ( ) . skip_binder ( ) {
490- ty:: ClauseKind :: Trait ( tr) => !is_assoc_item_ty ( tr. self_ty ( ) ) ,
491- ty:: ClauseKind :: Projection ( proj) => {
492- !is_assoc_item_ty ( proj. projection_term . self_ty ( ) )
493- }
494- ty:: ClauseKind :: TypeOutlives ( outlives) => !is_assoc_item_ty ( outlives. 0 ) ,
495- _ => true ,
496- } )
497- . collect ( ) ;
498- if predicates. len ( ) == predicates_and_bounds. predicates . len ( ) {
499- predicates_and_bounds
500- } else {
501- ty:: GenericPredicates {
502- parent : predicates_and_bounds. parent ,
503- predicates : tcx. arena . alloc_slice ( & predicates) ,
504- effects_min_tys : predicates_and_bounds. effects_min_tys ,
505- }
506- }
507- } else {
508- if matches ! ( def_kind, DefKind :: AnonConst )
509- && tcx. features ( ) . generic_const_exprs
510- && let Some ( defaulted_param_def_id) =
511- tcx. hir ( ) . opt_const_param_default_param_def_id ( tcx. local_def_id_to_hir_id ( def_id) )
512- {
513- // In `generics_of` we set the generics' parent to be our parent's parent which means that
514- // we lose out on the predicates of our actual parent if we dont return those predicates here.
515- // (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
516- //
517- // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
518- // ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
519- // ^^^ explicit_predicates_of on
520- // parent item we dont have set as the
521- // parent of generics returned by `generics_of`
522- //
523- // In the above code we want the anon const to have predicates in its param env for `T: Trait`
524- // and we would be calling `explicit_predicates_of(Foo)` here
525- let parent_def_id = tcx. local_parent ( def_id) ;
526- let parent_preds = tcx. explicit_predicates_of ( parent_def_id) ;
527-
528- // If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter
529- // will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
530- // to #106994 is implemented.
531- let filtered_predicates = parent_preds
532- . predicates
533- . into_iter ( )
534- . filter ( |( pred, _) | {
535- if let ty:: ClauseKind :: ConstArgHasType ( ct, _) = pred. kind ( ) . skip_binder ( ) {
536- match ct. kind ( ) {
537- ty:: ConstKind :: Param ( param_const) => {
538- let defaulted_param_idx = tcx
539- . generics_of ( parent_def_id)
540- . param_def_id_to_index [ & defaulted_param_def_id. to_def_id ( ) ] ;
541- param_const. index < defaulted_param_idx
542- }
543- _ => bug ! (
544- "`ConstArgHasType` in `predicates_of`\
545- that isn't a `Param` const"
546- ) ,
492+ . into_iter ( )
493+ . filter ( |( pred, _) | {
494+ if let ty:: ClauseKind :: ConstArgHasType ( ct, _) = pred. kind ( ) . skip_binder ( ) {
495+ match ct. kind ( ) {
496+ ty:: ConstKind :: Param ( param_const) => {
497+ let defaulted_param_idx = tcx
498+ . generics_of ( parent_def_id)
499+ . param_def_id_to_index [ & defaulted_param_def_id. to_def_id ( ) ] ;
500+ param_const. index < defaulted_param_idx
547501 }
548- } else {
549- true
502+ _ => bug ! (
503+ "`ConstArgHasType` in `predicates_of`\
504+ that isn't a `Param` const"
505+ ) ,
550506 }
551- } )
552- . cloned ( ) ;
553- return GenericPredicates {
554- parent : parent_preds. parent ,
555- predicates : { tcx. arena . alloc_from_iter ( filtered_predicates) } ,
556- effects_min_tys : parent_preds. effects_min_tys ,
557- } ;
558- }
559- gather_explicit_predicates_of ( tcx, def_id)
507+ } else {
508+ true
509+ }
510+ } )
511+ . cloned ( ) ;
512+ return GenericPredicates {
513+ parent : parent_preds. parent ,
514+ predicates : { tcx. arena . alloc_from_iter ( filtered_predicates) } ,
515+ effects_min_tys : parent_preds. effects_min_tys ,
516+ } ;
560517 }
518+ gather_explicit_predicates_of ( tcx, def_id)
561519}
562520
563521/// Ensures that the super-predicates of the trait with a `DefId`
0 commit comments