@@ -13,7 +13,7 @@ use rustc::hir::def_id::DefId;
1313use rustc:: hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
1414use rustc:: ty:: { self , TyCtxt } ;
1515use rustc:: ty:: subst:: Substs ;
16- use rustc:: traits:: { QuantifierKind , Goal , DomainGoal , Clause , WhereClauseAtom } ;
16+ use rustc:: traits:: { WhereClauseAtom , PolyDomainGoal , DomainGoal , ProgramClause , Clause } ;
1717use syntax:: ast;
1818use rustc_data_structures:: sync:: Lrc ;
1919
@@ -61,36 +61,27 @@ impl<'tcx> Lower<DomainGoal<'tcx>> for ty::TypeOutlivesPredicate<'tcx> {
6161/// `ty::Binder` is used for wrapping a rustc construction possibly containing generic
6262/// lifetimes, e.g. `for<'a> T: Fn(&'a i32)`. Instead of representing higher-ranked things
6363/// 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:
6565/// `forall<'a> { T: Fn(&'a i32) }` which corresponds to something like
6666/// `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 >
7269{
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 ( ) )
8172 }
8273}
8374
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 > {
8677 use rustc:: ty:: Predicate :: * ;
8778
8879 match self {
8980 Trait ( predicate) => predicate. lower ( ) ,
9081 RegionOutlives ( predicate) => predicate. lower ( ) ,
9182 TypeOutlives ( predicate) => predicate. lower ( ) ,
9283 Projection ( predicate) => predicate. lower ( ) ,
93- WellFormed ( ty) => DomainGoal :: WellFormedTy ( * ty) . into ( ) ,
84+ WellFormed ( ty) => ty :: Binder :: dummy ( DomainGoal :: WellFormedTy ( * ty) ) ,
9485 ObjectSafe ( ..) |
9586 ClosureKind ( ..) |
9687 Subtype ( ..) |
@@ -134,13 +125,16 @@ fn program_clauses_for_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI
134125 }
135126 } ;
136127 // `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 ( ) ;
138129 // `Implemented(Self: Trait<P1..Pn>)`
139130 let impl_trait = DomainGoal :: Holds ( WhereClauseAtom :: Implemented ( trait_pred) ) ;
140131
141132 // `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) ) ] )
144138}
145139
146140fn 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
167161 let where_clauses = tcx. predicates_of ( def_id) . predicates . lower ( ) ;
168162
169163 // `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) ) ] )
172169}
173170
174171pub fn dump_program_clauses < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) {
@@ -184,14 +181,19 @@ struct ClauseDumper<'a, 'tcx: 'a> {
184181 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
185182}
186183
187- impl < ' a , ' tcx > ClauseDumper < ' a , ' tcx > {
184+ impl < ' a , ' tcx > ClauseDumper < ' a , ' tcx > {
188185 fn process_attrs ( & mut self , node_id : ast:: NodeId , attrs : & [ ast:: Attribute ] ) {
189186 let def_id = self . tcx . hir . local_def_id ( node_id) ;
190187 for attr in attrs {
191188 if attr. check_name ( "rustc_dump_program_clauses" ) {
192189 let clauses = self . tcx . program_clauses_for ( def_id) ;
193190 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 ( ) ;
195197 }
196198 }
197199 }
0 commit comments