@@ -362,7 +362,7 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
362362 . map ( |wc| tcx. mk_goal ( GoalKind :: from_poly_domain_goal ( wc, tcx) ) ) ,
363363 ) ,
364364 } ;
365- tcx. intern_clauses ( & [ Clause :: ForAll ( ty:: Binder :: dummy ( clause) ) ] )
365+ tcx. mk_clauses ( iter :: once ( Clause :: ForAll ( ty:: Binder :: dummy ( clause) ) ) )
366366}
367367
368368pub fn program_clauses_for_type_def < ' a , ' tcx > (
@@ -430,10 +430,86 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
430430}
431431
432432pub 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 ,
435435) -> 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)
437513}
438514
439515pub fn program_clauses_for_associated_type_value < ' a , ' tcx > (
@@ -442,10 +518,11 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
442518) -> Clauses < ' tcx > {
443519 // Rule Normalize-From-Impl (see rustc guide)
444520 //
445- // ```impl<P0..Pn> Trait<A1..An> for A0
446- // {
521+ // ```
522+ // impl<P0..Pn> Trait<A1..An> for A0 {
447523 // type AssocType<Pn+1..Pm> = T;
448- // }```
524+ // }
525+ // ```
449526 //
450527 // FIXME: For the moment, we don't account for where clauses written on the associated
451528 // 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>(
492569 . map ( |wc| tcx. mk_goal ( GoalKind :: from_poly_domain_goal ( wc, tcx) ) ) ,
493570 ) ,
494571 } ;
495- tcx. intern_clauses ( & [ Clause :: ForAll ( ty:: Binder :: dummy ( clause) ) ] )
572+ tcx. mk_clauses ( iter :: once ( Clause :: ForAll ( ty:: Binder :: dummy ( clause) ) ) )
496573}
497574
498575pub fn dump_program_clauses < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) {
0 commit comments