Skip to content

Commit 8113180

Browse files
committed
Visit tys in program_clauses_for_env
1 parent 62df973 commit 8113180

File tree

1 file changed

+66
-29
lines changed

1 file changed

+66
-29
lines changed

src/librustc_traits/lowering/environment.rs

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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};
2120
use rustc_data_structures::fx::FxHashSet;
2221

2322
struct 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

Comments
 (0)