@@ -496,9 +496,51 @@ pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
496
496
} ;
497
497
let from_env_clause = Clause :: ForAll ( ty:: Binder :: bind ( from_env_clause) ) ;
498
498
499
+ // Rule ProjectionEq-Normalize
500
+ //
501
+ // ProjectionEq can succeed by normalizing:
502
+ // ```
503
+ // forall<Self, P1..Pn, Pn+1..Pm, U> {
504
+ // ProjectionEq(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> = U) :-
505
+ // Normalize(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> -> U)
506
+ // }
507
+ // ```
508
+
509
+ let offset = tcx. generics_of ( trait_id) . params
510
+ . iter ( )
511
+ . map ( |p| p. index )
512
+ . max ( )
513
+ . unwrap_or ( 0 ) ;
514
+ // Add a new type param after the existing ones (`U` in the comment above).
515
+ let ty_var = ty:: Bound (
516
+ ty:: BoundTy :: new ( ty:: INNERMOST , ty:: BoundVar :: from_u32 ( offset + 1 ) )
517
+ ) ;
518
+
519
+ // `ProjectionEq(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> = U)`
520
+ let projection = ty:: ProjectionPredicate {
521
+ projection_ty,
522
+ ty : tcx. mk_ty ( ty_var) ,
523
+ } ;
524
+
525
+ // `Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> U)`
526
+ let hypothesis = tcx. mk_goal (
527
+ DomainGoal :: Normalize ( projection) . into_goal ( )
528
+ ) ;
529
+
530
+ // ProjectionEq(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> = U) :-
531
+ // Normalize(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> -> U)
532
+ let normalize_clause = ProgramClause {
533
+ goal : DomainGoal :: Holds ( WhereClause :: ProjectionEq ( projection) ) ,
534
+ hypotheses : tcx. mk_goals ( iter:: once ( hypothesis) ) ,
535
+ category : ProgramClauseCategory :: Other ,
536
+ } ;
537
+ let normalize_clause = Clause :: ForAll ( ty:: Binder :: bind ( normalize_clause) ) ;
538
+
499
539
let clauses = iter:: once ( projection_eq_clause)
500
540
. chain ( iter:: once ( wf_clause) )
501
- . chain ( iter:: once ( from_env_clause) ) ;
541
+ . chain ( iter:: once ( from_env_clause) )
542
+ . chain ( iter:: once ( normalize_clause) ) ;
543
+
502
544
tcx. mk_clauses ( clauses)
503
545
}
504
546
0 commit comments