@@ -362,7 +362,7 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
362
362
. map ( |wc| tcx. mk_goal ( GoalKind :: from_poly_domain_goal ( wc, tcx) ) ) ,
363
363
) ,
364
364
} ;
365
- tcx. intern_clauses ( & [ Clause :: ForAll ( ty:: Binder :: dummy ( clause) ) ] )
365
+ tcx. mk_clauses ( iter :: once ( Clause :: ForAll ( ty:: Binder :: dummy ( clause) ) ) )
366
366
}
367
367
368
368
pub fn program_clauses_for_type_def < ' a , ' tcx > (
@@ -430,10 +430,86 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
430
430
}
431
431
432
432
pub fn program_clauses_for_associated_type_def < ' a , ' tcx > (
433
- _tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
434
- _item_id : DefId ,
433
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
434
+ item_id : DefId ,
435
435
) -> Clauses < ' tcx > {
436
- unimplemented ! ( )
436
+ // Rule ProjectionEq-Skolemize
437
+ //
438
+ // ```
439
+ // trait Trait<P1..Pn> {
440
+ // type AssocType<Pn+1..Pm>;
441
+ // }
442
+ // ```
443
+ //
444
+ // `ProjectionEq` can succeed by skolemizing, see "associated type"
445
+ // chapter for more:
446
+ // ```
447
+ // forall<Self, P1..Pn, Pn+1..Pm> {
448
+ // ProjectionEq(
449
+ // <Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> =
450
+ // (Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>
451
+ // )
452
+ // }
453
+ // ```
454
+
455
+ let item = tcx. associated_item ( item_id) ;
456
+ debug_assert_eq ! ( item. kind, ty:: AssociatedKind :: Type ) ;
457
+ let trait_id = match item. container {
458
+ ty:: AssociatedItemContainer :: TraitContainer ( trait_id) => trait_id,
459
+ _ => bug ! ( "not an trait container" ) ,
460
+ } ;
461
+ let trait_ref = ty:: TraitRef :: identity ( tcx, trait_id) ;
462
+
463
+ let projection_ty = ty:: ProjectionTy :: from_ref_and_name ( tcx, trait_ref, item. ident ) ;
464
+ let placeholder_ty = tcx. mk_ty ( ty:: UnnormalizedProjection ( projection_ty) ) ;
465
+ let projection_eq = WhereClause :: ProjectionEq ( ty:: ProjectionPredicate {
466
+ projection_ty,
467
+ ty : placeholder_ty,
468
+ } ) ;
469
+
470
+ let projection_eq_clause = ProgramClause {
471
+ goal : DomainGoal :: Holds ( projection_eq) ,
472
+ hypotheses : & ty:: List :: empty ( ) ,
473
+ } ;
474
+
475
+ // Rule WellFormed-AssocTy
476
+ // ```
477
+ // forall<Self, P1..Pn, Pn+1..Pm> {
478
+ // WellFormed((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
479
+ // :- Implemented(Self: Trait<P1..Pn>)
480
+ // }
481
+ // ```
482
+
483
+ let trait_predicate = ty:: TraitPredicate { trait_ref } ;
484
+ let hypothesis = tcx. mk_goal (
485
+ DomainGoal :: Holds ( WhereClause :: Implemented ( trait_predicate) ) . into_goal ( )
486
+ ) ;
487
+ let wf_clause = ProgramClause {
488
+ goal : DomainGoal :: WellFormed ( WellFormed :: Ty ( placeholder_ty) ) ,
489
+ hypotheses : tcx. mk_goals ( iter:: once ( hypothesis) ) ,
490
+ } ;
491
+
492
+ // Rule Implied-Trait-From-AssocTy
493
+ // ```
494
+ // forall<Self, P1..Pn, Pn+1..Pm> {
495
+ // FromEnv(Self: Trait<P1..Pn>)
496
+ // :- FromEnv((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
497
+ // }
498
+ // ```
499
+
500
+ let hypothesis = tcx. mk_goal (
501
+ DomainGoal :: FromEnv ( FromEnv :: Ty ( placeholder_ty) ) . into_goal ( )
502
+ ) ;
503
+ let from_env_clause = ProgramClause {
504
+ goal : DomainGoal :: FromEnv ( FromEnv :: Trait ( trait_predicate) ) ,
505
+ hypotheses : tcx. mk_goals ( iter:: once ( hypothesis) ) ,
506
+ } ;
507
+
508
+ let clauses = iter:: once ( projection_eq_clause)
509
+ . chain ( iter:: once ( wf_clause) )
510
+ . chain ( iter:: once ( from_env_clause) ) ;
511
+ let clauses = clauses. map ( |clause| Clause :: ForAll ( ty:: Binder :: dummy ( clause) ) ) ;
512
+ tcx. mk_clauses ( clauses)
437
513
}
438
514
439
515
pub fn program_clauses_for_associated_type_value < ' a , ' tcx > (
@@ -442,10 +518,11 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
442
518
) -> Clauses < ' tcx > {
443
519
// Rule Normalize-From-Impl (see rustc guide)
444
520
//
445
- // ```impl<P0..Pn> Trait<A1..An> for A0
446
- // {
521
+ // ```
522
+ // impl<P0..Pn> Trait<A1..An> for A0 {
447
523
// type AssocType<Pn+1..Pm> = T;
448
- // }```
524
+ // }
525
+ // ```
449
526
//
450
527
// FIXME: For the moment, we don't account for where clauses written on the associated
451
528
// ty definition (i.e. in the trait def, as in `type AssocType<T> where T: Sized`).
@@ -492,7 +569,7 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
492
569
. map ( |wc| tcx. mk_goal ( GoalKind :: from_poly_domain_goal ( wc, tcx) ) ) ,
493
570
) ,
494
571
} ;
495
- tcx. intern_clauses ( & [ Clause :: ForAll ( ty:: Binder :: dummy ( clause) ) ] )
572
+ tcx. mk_clauses ( iter :: once ( Clause :: ForAll ( ty:: Binder :: dummy ( clause) ) ) )
496
573
}
497
574
498
575
pub fn dump_program_clauses < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) {
0 commit comments