@@ -13,7 +13,7 @@ use rustc::hir::def_id::DefId;
13
13
use rustc:: hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
14
14
use rustc:: ty:: { self , TyCtxt } ;
15
15
use rustc:: ty:: subst:: Substs ;
16
- use rustc:: traits:: { QuantifierKind , Goal , DomainGoal , Clause , WhereClauseAtom } ;
16
+ use rustc:: traits:: { WhereClauseAtom , PolyDomainGoal , DomainGoal , ProgramClause , Clause } ;
17
17
use syntax:: ast;
18
18
use rustc_data_structures:: sync:: Lrc ;
19
19
@@ -61,36 +61,27 @@ impl<'tcx> Lower<DomainGoal<'tcx>> for ty::TypeOutlivesPredicate<'tcx> {
61
61
/// `ty::Binder` is used for wrapping a rustc construction possibly containing generic
62
62
/// lifetimes, e.g. `for<'a> T: Fn(&'a i32)`. Instead of representing higher-ranked things
63
63
/// in that leaf-form (i.e. `Holds(Implemented(Binder<TraitPredicate>))` in the previous
64
- /// example), we model them with quantified goals, e.g. as for the previous example:
64
+ /// example), we model them with quantified domain goals, e.g. as for the previous example:
65
65
/// `forall<'a> { T: Fn(&'a i32) }` which corresponds to something like
66
66
/// `Binder<Holds(Implemented(TraitPredicate))>`.
67
- ///
68
- /// Also, if `self` does not contain generic lifetimes, we can safely drop the binder and we
69
- /// can directly lower to a leaf goal instead of a quantified goal.
70
- impl < ' tcx , T > Lower < Goal < ' tcx > > for ty:: Binder < T >
71
- where T : Lower < DomainGoal < ' tcx > > + ty:: fold:: TypeFoldable < ' tcx > + Copy
67
+ impl < ' tcx , T > Lower < PolyDomainGoal < ' tcx > > for ty:: Binder < T >
68
+ where T : Lower < DomainGoal < ' tcx > > + ty:: fold:: TypeFoldable < ' tcx >
72
69
{
73
- fn lower ( & self ) -> Goal < ' tcx > {
74
- match self . no_late_bound_regions ( ) {
75
- Some ( p) => p. lower ( ) . into ( ) ,
76
- None => Goal :: Quantified (
77
- QuantifierKind :: Universal ,
78
- Box :: new ( self . map_bound ( |p| p. lower ( ) . into ( ) ) )
79
- ) ,
80
- }
70
+ fn lower ( & self ) -> PolyDomainGoal < ' tcx > {
71
+ self . map_bound_ref ( |p| p. lower ( ) )
81
72
}
82
73
}
83
74
84
- impl < ' tcx > Lower < Goal < ' tcx > > for ty:: Predicate < ' tcx > {
85
- fn lower ( & self ) -> Goal < ' tcx > {
75
+ impl < ' tcx > Lower < PolyDomainGoal < ' tcx > > for ty:: Predicate < ' tcx > {
76
+ fn lower ( & self ) -> PolyDomainGoal < ' tcx > {
86
77
use rustc:: ty:: Predicate :: * ;
87
78
88
79
match self {
89
80
Trait ( predicate) => predicate. lower ( ) ,
90
81
RegionOutlives ( predicate) => predicate. lower ( ) ,
91
82
TypeOutlives ( predicate) => predicate. lower ( ) ,
92
83
Projection ( predicate) => predicate. lower ( ) ,
93
- WellFormed ( ty) => DomainGoal :: WellFormedTy ( * ty) . into ( ) ,
84
+ WellFormed ( ty) => ty :: Binder :: dummy ( DomainGoal :: WellFormedTy ( * ty) ) ,
94
85
ObjectSafe ( ..) |
95
86
ClosureKind ( ..) |
96
87
Subtype ( ..) |
@@ -134,13 +125,16 @@ fn program_clauses_for_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI
134
125
}
135
126
} ;
136
127
// `FromEnv(Self: Trait<P1..Pn>)`
137
- let from_env = Goal :: DomainGoal ( DomainGoal :: FromEnv ( trait_pred. lower ( ) ) ) ;
128
+ let from_env = DomainGoal :: FromEnv ( trait_pred. lower ( ) ) . into ( ) ;
138
129
// `Implemented(Self: Trait<P1..Pn>)`
139
130
let impl_trait = DomainGoal :: Holds ( WhereClauseAtom :: Implemented ( trait_pred) ) ;
140
131
141
132
// `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] )
133
+ let clause = ProgramClause {
134
+ goal : impl_trait,
135
+ hypotheses : vec ! [ from_env] ,
136
+ } ;
137
+ Lrc :: new ( vec ! [ Clause :: ForAll ( ty:: Binder :: dummy( clause) ) ] )
144
138
}
145
139
146
140
fn program_clauses_for_impl < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId )
@@ -167,8 +161,11 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
167
161
let where_clauses = tcx. predicates_of ( def_id) . predicates . lower ( ) ;
168
162
169
163
// `Implemented(A0: Trait<A1..An>) :- WC`
170
- let clause = Clause :: Implies ( where_clauses, trait_pred) ;
171
- Lrc :: new ( vec ! [ clause] )
164
+ let clause = ProgramClause {
165
+ goal : trait_pred,
166
+ hypotheses : where_clauses. into_iter ( ) . map ( |wc| wc. into ( ) ) . collect ( )
167
+ } ;
168
+ Lrc :: new ( vec ! [ Clause :: ForAll ( ty:: Binder :: dummy( clause) ) ] )
172
169
}
173
170
174
171
pub fn dump_program_clauses < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) {
@@ -184,14 +181,19 @@ struct ClauseDumper<'a, 'tcx: 'a> {
184
181
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
185
182
}
186
183
187
- impl < ' a , ' tcx > ClauseDumper < ' a , ' tcx > {
184
+ impl < ' a , ' tcx > ClauseDumper < ' a , ' tcx > {
188
185
fn process_attrs ( & mut self , node_id : ast:: NodeId , attrs : & [ ast:: Attribute ] ) {
189
186
let def_id = self . tcx . hir . local_def_id ( node_id) ;
190
187
for attr in attrs {
191
188
if attr. check_name ( "rustc_dump_program_clauses" ) {
192
189
let clauses = self . tcx . program_clauses_for ( def_id) ;
193
190
for clause in & * clauses {
194
- self . tcx . sess . struct_span_err ( attr. span , & format ! ( "{}" , clause) ) . emit ( ) ;
191
+ // Skip the top-level binder for a less verbose output
192
+ let program_clause = match clause {
193
+ Clause :: Implies ( program_clause) => program_clause,
194
+ Clause :: ForAll ( program_clause) => program_clause. skip_binder ( ) ,
195
+ } ;
196
+ self . tcx . sess . struct_span_err ( attr. span , & format ! ( "{}" , program_clause) ) . emit ( ) ;
195
197
}
196
198
}
197
199
}
0 commit comments