@@ -12,6 +12,7 @@ use rustc::hir::{self, ImplPolarity};
12
12
use rustc:: hir:: def_id:: DefId ;
13
13
use rustc:: hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
14
14
use rustc:: ty:: { self , TyCtxt } ;
15
+ use rustc:: ty:: subst:: Substs ;
15
16
use rustc:: traits:: { QuantifierKind , Goal , DomainGoal , Clause , WhereClauseAtom } ;
16
17
use syntax:: ast;
17
18
use rustc_data_structures:: sync:: Lrc ;
@@ -104,29 +105,69 @@ crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI
104
105
let node_id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
105
106
let item = tcx. hir . expect_item ( node_id) ;
106
107
match item. node {
108
+ hir:: ItemTrait ( ..) => program_clauses_for_trait ( tcx, def_id) ,
107
109
hir:: ItemImpl ( ..) => program_clauses_for_impl ( tcx, def_id) ,
108
110
109
111
// FIXME: other constructions e.g. traits, associated types...
110
112
_ => Lrc :: new ( vec ! [ ] ) ,
111
113
}
112
114
}
113
115
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
+
114
146
fn program_clauses_for_impl < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId )
115
147
-> Lrc < Vec < Clause < ' tcx > > >
116
148
{
117
149
if let ImplPolarity :: Negative = tcx. impl_polarity ( def_id) {
118
150
return Lrc :: new ( vec ! [ ] ) ;
119
151
}
120
152
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 { .. }`
122
156
//
123
- // (see rustc guide)
157
+ // ```
158
+ // forall<P0..Pn> {
159
+ // Implemented(A0: Trait<A1..An>) :- WC
160
+ // }
161
+ // ```
124
162
125
163
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`
127
167
let where_clauses = tcx. predicates_of ( def_id) . predicates . lower ( ) ;
128
168
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) ;
130
171
Lrc :: new ( vec ! [ clause] )
131
172
}
132
173
0 commit comments