@@ -12,8 +12,10 @@ use rustc::hir::def_id::DefId;
1212use rustc:: hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
1313use rustc:: hir:: map:: definitions:: DefPathData ;
1414use rustc:: hir:: { self , ImplPolarity } ;
15- use rustc:: traits:: { Clause , Clauses , DomainGoal , Goal , PolyDomainGoal , ProgramClause ,
16- WhereClause , FromEnv , WellFormed } ;
15+ use rustc:: traits:: {
16+ Clause , Clauses , DomainGoal , FromEnv , Goal , PolyDomainGoal , ProgramClause , WellFormed ,
17+ WhereClause ,
18+ } ;
1719use rustc:: ty:: query:: Providers ;
1820use rustc:: ty:: { self , Slice , TyCtxt } ;
1921use rustc_data_structures:: fx:: FxHashSet ;
@@ -101,39 +103,52 @@ impl<'tcx> Lower<PolyDomainGoal<'tcx>> for ty::Predicate<'tcx> {
101103 Predicate :: RegionOutlives ( predicate) => predicate. lower ( ) ,
102104 Predicate :: TypeOutlives ( predicate) => predicate. lower ( ) ,
103105 Predicate :: Projection ( predicate) => predicate. lower ( ) ,
104- Predicate :: WellFormed ( ty) => ty:: Binder :: dummy (
105- DomainGoal :: WellFormed ( WellFormed :: Ty ( * ty) )
106- ) ,
107- Predicate :: ObjectSafe ( ..) |
108- Predicate :: ClosureKind ( ..) |
109- Predicate :: Subtype ( ..) |
110- Predicate :: ConstEvaluatable ( ..) => {
111- unimplemented ! ( )
106+ Predicate :: WellFormed ( ty) => {
107+ ty:: Binder :: dummy ( DomainGoal :: WellFormed ( WellFormed :: Ty ( * ty) ) )
112108 }
109+ Predicate :: ObjectSafe ( ..)
110+ | Predicate :: ClosureKind ( ..)
111+ | Predicate :: Subtype ( ..)
112+ | Predicate :: ConstEvaluatable ( ..) => unimplemented ! ( ) ,
113113 }
114114 }
115115}
116116
117- /// Transforms an existing goal into a FromEnv goal.
118- ///
119117/// Used for lowered where clauses (see rustc guide).
120118trait IntoFromEnvGoal {
119+ // Transforms an existing goal into a FromEnv goal.
121120 fn into_from_env_goal ( self ) -> Self ;
122121}
123122
124- impl < ' tcx > IntoFromEnvGoal for DomainGoal < ' tcx > {
123+ trait IntoWellFormedGoal {
124+ fn into_wellformed_goal ( self ) -> Self ;
125+ }
126+
127+ impl < ' tcx > IntoGoal for DomainGoal < ' tcx > {
128+ // Transforms an existing goal into a WellFormed goal.
125129 fn into_from_env_goal ( self ) -> DomainGoal < ' tcx > {
126130 use self :: WhereClause :: * ;
127131
128132 match self {
129- DomainGoal :: Holds ( Implemented ( trait_ref) ) => DomainGoal :: FromEnv (
130- FromEnv :: Trait ( trait_ref)
131- ) ,
133+ DomainGoal :: Holds ( Implemented ( trait_ref) ) => {
134+ DomainGoal :: FromEnv ( FromEnv :: Trait ( trait_ref) )
135+ }
132136 other => other,
133137 }
134138 }
135139}
136140
141+ impl < ' tcx > IntoFromEnvGoal for DomainGoal < ' tcx > {
142+ fn into_wellformed_goal ( self ) -> DomainGoal < ' tcx > {
143+ use self :: DomainGoal :: * ;
144+ match self {
145+ Holds ( wc_atom) => WellFormed ( wc_atom) ,
146+ WellFormed ( ..) | FromEnv ( ..) | WellFormedTy ( ..) | FromEnvTy ( ..) | Normalize ( ..)
147+ | RegionOutlives ( ..) | TypeOutlives ( ..) => self ,
148+ }
149+ }
150+ }
151+
137152crate fn program_clauses_for < ' a , ' tcx > (
138153 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
139154 def_id : DefId ,
@@ -230,7 +245,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
230245 // `Implemented(Self: Trait<P1..Pn>)`
231246 let impl_trait: DomainGoal = trait_pred. lower ( ) ;
232247
233- // `FromEnv(Self: Trait<P1..Pn>)`
248+ // `FromEnv(Self: Trait<P1..Pn>)`
234249 let from_env_goal = impl_trait. into_from_env_goal ( ) . into_goal ( ) ;
235250 let hypotheses = tcx. intern_goals ( & [ from_env_goal] ) ;
236251
@@ -262,10 +277,50 @@ fn program_clauses_for_trait<'a, 'tcx>(
262277 goal : goal. into_from_env_goal ( ) ,
263278 hypotheses,
264279 } ) )
280+ . map ( |wc| implied_bound_from_trait ( tcx, trait_pred, wc) ) ;
281+ let wellformed_clauses = where_clauses[ 1 ..]
282+ . into_iter ( )
283+ . map ( |wc| wellformed_from_bound ( tcx, trait_pred, wc) ) ;
284+ tcx. mk_clauses (
285+ clauses
286+ . chain ( implied_bound_clauses)
287+ . chain ( wellformed_clauses) ,
288+ )
289+ }
265290
266- . map ( Clause :: ForAll ) ;
291+ fn wellformed_from_bound < ' a , ' tcx > (
292+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
293+ trait_pred : ty:: TraitPredicate < ' tcx > ,
294+ where_clause : & ty:: Predicate < ' tcx > ,
295+ ) -> Clause < ' tcx > {
296+ // Rule WellFormed-TraitRef
297+ //
298+ // For each where clause WC:
299+ // forall<Self, P1..Pn> {
300+ // WellFormed(Self: Trait<P1..Pn>) :- Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)
301+ // }
267302
268- tcx. mk_clauses ( clauses. chain ( implied_bound_clauses) )
303+ // WellFormed(Self: Trait<P1..Pn>)
304+ let wellformed_trait = DomainGoal :: WellFormed ( WhereClauseAtom :: Implemented ( trait_pred) ) ;
305+ // Impemented(Self: Trait<P1..Pn>)
306+ let impl_trait = ty:: Binder :: dummy ( DomainGoal :: Holds ( WhereClauseAtom :: Implemented ( trait_pred) ) ) ;
307+ // WellFormed(WC)
308+ let wellformed_wc = where_clause
309+ . lower ( )
310+ . map_bound ( |wc| wc. into_wellformed_goal ( ) ) ;
311+ // Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)
312+ let mut where_clauses = vec ! [ impl_trait] ;
313+ where_clauses. push ( wellformed_wc) ;
314+ Clause :: ForAll ( where_clause. lower ( ) . map_bound ( |_| {
315+ ProgramClause {
316+ goal : wellformed_trait,
317+ hypotheses : tcx. mk_goals (
318+ where_clauses
319+ . into_iter ( )
320+ . map ( |wc| Goal :: from_poly_domain_goal ( wc, tcx) ) ,
321+ ) ,
322+ }
323+ } ) )
269324}
270325
271326fn program_clauses_for_impl < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> Clauses < ' tcx > {
@@ -307,7 +362,6 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
307362 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
308363 def_id : DefId ,
309364) -> Clauses < ' tcx > {
310-
311365 // Rule WellFormed-Type
312366 //
313367 // `struct Ty<P1..Pn> where WC1, ..., WCm`
@@ -328,7 +382,10 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
328382 let well_formed = ProgramClause {
329383 goal : DomainGoal :: WellFormed ( WellFormed :: Ty ( ty) ) ,
330384 hypotheses : tcx. mk_goals (
331- where_clauses. iter ( ) . cloned ( ) . map ( |wc| Goal :: from_poly_domain_goal ( wc, tcx) )
385+ where_clauses
386+ . iter ( )
387+ . cloned ( )
388+ . map ( |wc| Goal :: from_poly_domain_goal ( wc, tcx) ) ,
332389 ) ,
333390 } ;
334391
@@ -459,7 +516,8 @@ impl<'a, 'tcx> ClauseDumper<'a, 'tcx> {
459516 }
460517
461518 if let Some ( clauses) = clauses {
462- let mut err = self . tcx
519+ let mut err = self
520+ . tcx
463521 . sess
464522 . struct_span_err ( attr. span , "program clause dump" ) ;
465523
0 commit comments