@@ -12,6 +12,7 @@ use rustc::hir::{self, ImplPolarity};
1212use rustc:: hir:: def_id:: DefId ;
1313use rustc:: hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
1414use rustc:: ty:: { self , TyCtxt } ;
15+ use rustc:: ty:: subst:: Substs ;
1516use rustc:: traits:: { QuantifierKind , Goal , DomainGoal , Clause , WhereClauseAtom } ;
1617use syntax:: ast;
1718use rustc_data_structures:: sync:: Lrc ;
@@ -104,29 +105,69 @@ crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI
104105 let node_id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
105106 let item = tcx. hir . expect_item ( node_id) ;
106107 match item. node {
108+ hir:: ItemTrait ( ..) => program_clauses_for_trait ( tcx, def_id) ,
107109 hir:: ItemImpl ( ..) => program_clauses_for_impl ( tcx, def_id) ,
108110
109111 // FIXME: other constructions e.g. traits, associated types...
110112 _ => Lrc :: new ( vec ! [ ] ) ,
111113 }
112114}
113115
116+ fn program_clauses_for_trait < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId )
117+ -> Lrc < Vec < Clause < ' tcx > > >
118+ {
119+ // Rule Implemented-From-Env (see rustc guide)
120+ //
121+ // `trait Trait<P1..Pn> where WC { .. } // P0 == Self`
122+ //
123+ // ```
124+ // forall<Self, P1..Pn> {
125+ // Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)
126+ // }
127+ // ```
128+
129+ // `Self: Trait<P1..Pn>`
130+ let trait_pred = ty:: TraitPredicate {
131+ trait_ref : ty:: TraitRef {
132+ def_id,
133+ substs : Substs :: identity_for_item ( tcx, def_id)
134+ }
135+ } ;
136+ // `FromEnv(Self: Trait<P1..Pn>)`
137+ let from_env = Goal :: DomainGoal ( DomainGoal :: FromEnv ( trait_pred. lower ( ) ) ) ;
138+ // `Implemented(Self: Trait<P1..Pn>)`
139+ let impl_trait = DomainGoal :: Holds ( WhereClauseAtom :: Implemented ( trait_pred) ) ;
140+
141+ // `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
142+ let clause = Clause :: Implies ( vec ! [ from_env] , impl_trait) ;
143+ Lrc :: new ( vec ! [ clause] )
144+ }
145+
114146fn program_clauses_for_impl < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId )
115147 -> Lrc < Vec < Clause < ' tcx > > >
116148{
117149 if let ImplPolarity :: Negative = tcx. impl_polarity ( def_id) {
118150 return Lrc :: new ( vec ! [ ] ) ;
119151 }
120152
121- // Rule Implemented-From-Impl
153+ // Rule Implemented-From-Impl (see rustc guide)
154+ //
155+ // `impl<P0..Pn> Trait<A1..An> for A0 where WC { .. }`
122156 //
123- // (see rustc guide)
157+ // ```
158+ // forall<P0..Pn> {
159+ // Implemented(A0: Trait<A1..An>) :- WC
160+ // }
161+ // ```
124162
125163 let trait_ref = tcx. impl_trait_ref ( def_id) . unwrap ( ) ;
126- let trait_ref = ty:: TraitPredicate { trait_ref } . lower ( ) ;
164+ // `Implemented(A0: Trait<A1..An>)`
165+ let trait_pred = ty:: TraitPredicate { trait_ref } . lower ( ) ;
166+ // `WC`
127167 let where_clauses = tcx. predicates_of ( def_id) . predicates . lower ( ) ;
128168
129- let clause = Clause :: Implies ( where_clauses, trait_ref) ;
169+ // `Implemented(A0: Trait<A1..An>) :- WC`
170+ let clause = Clause :: Implies ( where_clauses, trait_pred) ;
130171 Lrc :: new ( vec ! [ clause] )
131172}
132173
0 commit comments