@@ -12,8 +12,10 @@ use rustc::hir::def_id::DefId;
12
12
use rustc:: hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
13
13
use rustc:: hir:: map:: definitions:: DefPathData ;
14
14
use 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
+ } ;
17
19
use rustc:: ty:: query:: Providers ;
18
20
use rustc:: ty:: { self , Slice , TyCtxt } ;
19
21
use rustc_data_structures:: fx:: FxHashSet ;
@@ -101,39 +103,52 @@ impl<'tcx> Lower<PolyDomainGoal<'tcx>> for ty::Predicate<'tcx> {
101
103
Predicate :: RegionOutlives ( predicate) => predicate. lower ( ) ,
102
104
Predicate :: TypeOutlives ( predicate) => predicate. lower ( ) ,
103
105
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) ) )
112
108
}
109
+ Predicate :: ObjectSafe ( ..)
110
+ | Predicate :: ClosureKind ( ..)
111
+ | Predicate :: Subtype ( ..)
112
+ | Predicate :: ConstEvaluatable ( ..) => unimplemented ! ( ) ,
113
113
}
114
114
}
115
115
}
116
116
117
- /// Transforms an existing goal into a FromEnv goal.
118
- ///
119
117
/// Used for lowered where clauses (see rustc guide).
120
118
trait IntoFromEnvGoal {
119
+ // Transforms an existing goal into a FromEnv goal.
121
120
fn into_from_env_goal ( self ) -> Self ;
122
121
}
123
122
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.
125
129
fn into_from_env_goal ( self ) -> DomainGoal < ' tcx > {
126
130
use self :: WhereClause :: * ;
127
131
128
132
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
+ }
132
136
other => other,
133
137
}
134
138
}
135
139
}
136
140
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
+
137
152
crate fn program_clauses_for < ' a , ' tcx > (
138
153
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
139
154
def_id : DefId ,
@@ -230,7 +245,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
230
245
// `Implemented(Self: Trait<P1..Pn>)`
231
246
let impl_trait: DomainGoal = trait_pred. lower ( ) ;
232
247
233
- // `FromEnv(Self: Trait<P1..Pn>)`
248
+ // `FromEnv(Self: Trait<P1..Pn>)`
234
249
let from_env_goal = impl_trait. into_from_env_goal ( ) . into_goal ( ) ;
235
250
let hypotheses = tcx. intern_goals ( & [ from_env_goal] ) ;
236
251
@@ -262,10 +277,50 @@ fn program_clauses_for_trait<'a, 'tcx>(
262
277
goal : goal. into_from_env_goal ( ) ,
263
278
hypotheses,
264
279
} ) )
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
+ }
265
290
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
+ // }
267
302
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
+ } ) )
269
324
}
270
325
271
326
fn 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>(
307
362
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
308
363
def_id : DefId ,
309
364
) -> Clauses < ' tcx > {
310
-
311
365
// Rule WellFormed-Type
312
366
//
313
367
// `struct Ty<P1..Pn> where WC1, ..., WCm`
@@ -328,7 +382,10 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
328
382
let well_formed = ProgramClause {
329
383
goal : DomainGoal :: WellFormed ( WellFormed :: Ty ( ty) ) ,
330
384
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) ) ,
332
389
) ,
333
390
} ;
334
391
@@ -459,7 +516,8 @@ impl<'a, 'tcx> ClauseDumper<'a, 'tcx> {
459
516
}
460
517
461
518
if let Some ( clauses) = clauses {
462
- let mut err = self . tcx
519
+ let mut err = self
520
+ . tcx
463
521
. sess
464
522
. struct_span_err ( attr. span , "program clause dump" ) ;
465
523
0 commit comments