@@ -18,10 +18,26 @@ use crate::delegation::inherit_predicates_for_delegation_item;
18
18
use crate :: hir_ty_lowering:: { HirTyLowerer , OnlySelfBounds , PredicateFilter , RegionInferReason } ;
19
19
20
20
/// 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) ) ]
23
24
pub ( 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
+ }
25
41
26
42
if tcx. is_trait ( def_id) {
27
43
// For traits, add `Self: Trait` predicate. This is
@@ -51,7 +67,8 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
51
67
. chain ( std:: iter:: once ( ( ty:: TraitRef :: identity ( tcx, def_id) . upcast ( tcx) , span) ) ) ,
52
68
) ;
53
69
}
54
- debug ! ( "predicates_of(def_id={:?}) = {:?}" , def_id, result) ;
70
+
71
+ debug ! ( "predicates_of({:?}) = {:?}" , def_id, result) ;
55
72
result
56
73
}
57
74
@@ -442,122 +459,63 @@ fn const_evaluatable_predicates_of(
442
459
collector. preds
443
460
}
444
461
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
-
453
462
pub ( super ) fn explicit_predicates_of < ' tcx > (
454
463
tcx : TyCtxt < ' tcx > ,
455
464
def_id : LocalDefId ,
456
465
) -> ty:: GenericPredicates < ' tcx > {
457
466
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
486
491
. 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
547
501
}
548
- } else {
549
- true
502
+ _ => bug ! (
503
+ "`ConstArgHasType` in `predicates_of`\
504
+ that isn't a `Param` const"
505
+ ) ,
550
506
}
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
+ } ;
560
517
}
518
+ gather_explicit_predicates_of ( tcx, def_id)
561
519
}
562
520
563
521
/// Ensures that the super-predicates of the trait with a `DefId`
0 commit comments