@@ -13,11 +13,10 @@ use rustc::traits::{
1313 Clauses ,
1414 DomainGoal ,
1515 FromEnv ,
16- Goal ,
1716 ProgramClause ,
1817 Environment ,
1918} ;
20- use rustc:: ty:: { TyCtxt , Ty } ;
19+ use rustc:: ty:: { self , TyCtxt , Ty } ;
2120use rustc_data_structures:: fx:: FxHashSet ;
2221
2322struct ClauseVisitor < ' set , ' a , ' tcx : ' a > {
@@ -33,8 +32,63 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
3332 }
3433 }
3534
36- fn visit_ty ( & mut self , _ty : Ty < ' tcx > ) {
35+ fn visit_ty ( & mut self , ty : Ty < ' tcx > ) {
36+ match ty. sty {
37+ ty:: Projection ( data) => {
38+ self . round . extend (
39+ self . tcx . program_clauses_for ( data. item_def_id )
40+ . iter ( )
41+ . cloned ( )
42+ ) ;
43+ }
44+
45+ // forall<'a, T> { `Outlives(T, 'a) :- FromEnv(&'a T)` }
46+ ty:: Ref ( _region, _sub_ty, ..) => {
47+ // FIXME: we need bound tys in order to write the above rule
48+ }
49+
50+ ty:: Dynamic ( ..) => {
51+ // FIXME: trait object rules are not yet implemented
52+ }
53+
54+ ty:: Adt ( def, ..) => {
55+ self . round . extend (
56+ self . tcx . program_clauses_for ( def. did )
57+ . iter ( )
58+ . cloned ( )
59+ ) ;
60+ }
3761
62+ ty:: Foreign ( def_id) |
63+ ty:: FnDef ( def_id, ..) |
64+ ty:: Closure ( def_id, ..) |
65+ ty:: Generator ( def_id, ..) |
66+ ty:: Opaque ( def_id, ..) => {
67+ self . round . extend (
68+ self . tcx . program_clauses_for ( def_id)
69+ . iter ( )
70+ . cloned ( )
71+ ) ;
72+ }
73+
74+ ty:: Bool |
75+ ty:: Char |
76+ ty:: Int ( ..) |
77+ ty:: Uint ( ..) |
78+ ty:: Float ( ..) |
79+ ty:: Str |
80+ ty:: Array ( ..) |
81+ ty:: Slice ( ..) |
82+ ty:: RawPtr ( ..) |
83+ ty:: FnPtr ( ..) |
84+ ty:: Never |
85+ ty:: Tuple ( ..) |
86+ ty:: GeneratorWitness ( ..) |
87+ ty:: UnnormalizedProjection ( ..) |
88+ ty:: Param ( ..) |
89+ ty:: Infer ( ..) |
90+ ty:: Error => ( ) ,
91+ }
3892 }
3993
4094 fn visit_from_env ( & mut self , from_env : FromEnv < ' tcx > ) {
@@ -52,37 +106,20 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
52106 }
53107
54108 fn visit_domain_goal ( & mut self , domain_goal : DomainGoal < ' tcx > ) {
109+ // The only domain goals we can find in an environment are:
110+ // * `DomainGoal::Holds(..)`
111+ // * `DomainGoal::FromEnv(..)`
112+ // The former do not lead to any implied bounds. So we only need
113+ // to visit the latter.
55114 if let DomainGoal :: FromEnv ( from_env) = domain_goal {
56115 self . visit_from_env ( from_env) ;
57116 }
58117 }
59118
60- fn visit_goal ( & mut self , goal : Goal < ' tcx > ) {
61- match goal {
62- Goal :: Implies ( clauses, goal) => {
63- for clause in clauses {
64- self . visit_clause ( * clause) ;
65- }
66- self . visit_goal ( * goal) ;
67- }
68-
69- Goal :: And ( goal1, goal2) => {
70- self . visit_goal ( * goal1) ;
71- self . visit_goal ( * goal2) ;
72- }
73-
74- Goal :: Not ( goal) => self . visit_goal ( * goal) ,
75- Goal :: DomainGoal ( domain_goal) => self . visit_domain_goal ( domain_goal) ,
76- Goal :: Quantified ( _, goal) => self . visit_goal ( * * goal. skip_binder ( ) ) ,
77- Goal :: CannotProve => ( ) ,
78- }
79- }
80-
81119 fn visit_program_clause ( & mut self , clause : ProgramClause < ' tcx > ) {
82120 self . visit_domain_goal ( clause. goal ) ;
83- for goal in clause. hypotheses {
84- self . visit_goal ( * goal) ;
85- }
121+ // No need to visit `clause.hypotheses`: they are always of the form
122+ // `FromEnv(...)` and were visited at a previous round.
86123 }
87124
88125 fn visit_clause ( & mut self , clause : Clause < ' tcx > ) {
@@ -102,8 +139,8 @@ crate fn program_clauses_for_env<'a, 'tcx>(
102139 let mut last_round = FxHashSet ( ) ;
103140 {
104141 let mut visitor = ClauseVisitor :: new ( tcx, & mut last_round) ;
105- for clause in environment. clauses {
106- visitor. visit_clause ( * clause) ;
142+ for & clause in environment. clauses {
143+ visitor. visit_clause ( clause) ;
107144 }
108145 }
109146
0 commit comments