@@ -23,13 +23,15 @@ use rustc::traits::{
23
23
Goal ,
24
24
GoalKind ,
25
25
Clause ,
26
+ ProgramClauseCategory ,
26
27
QuantifierKind ,
27
28
Environment ,
28
29
InEnvironment ,
29
30
} ;
30
31
use rustc:: ty:: fold:: { TypeFoldable , TypeFolder , TypeVisitor } ;
31
32
use rustc:: ty:: subst:: Kind ;
32
33
use rustc:: ty:: { self , TyCtxt } ;
34
+ use rustc:: hir:: def_id:: DefId ;
33
35
34
36
use std:: fmt:: { self , Debug } ;
35
37
use std:: marker:: PhantomData ;
@@ -330,46 +332,230 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
330
332
{
331
333
fn program_clauses (
332
334
& self ,
333
- _environment : & Environment < ' tcx > ,
335
+ environment : & Environment < ' tcx > ,
334
336
goal : & DomainGoal < ' tcx > ,
335
337
) -> Vec < Clause < ' tcx > > {
336
338
use rustc:: traits:: WhereClause :: * ;
337
339
338
- match goal {
339
- DomainGoal :: Holds ( Implemented ( _trait_predicate) ) => {
340
+ fn assemble_clauses_from_impls < ' tcx > (
341
+ tcx : ty:: TyCtxt < ' _ , ' _ , ' tcx > ,
342
+ trait_def_id : DefId ,
343
+ clauses : & mut Vec < Clause < ' tcx > >
344
+ ) {
345
+ tcx. for_each_impl ( trait_def_id, |impl_def_id| {
346
+ clauses. extend (
347
+ tcx. program_clauses_for ( impl_def_id)
348
+ . into_iter ( )
349
+ . cloned ( )
350
+ ) ;
351
+ } ) ;
352
+ }
353
+
354
+ fn assemble_clauses_from_assoc_ty_values < ' tcx > (
355
+ tcx : ty:: TyCtxt < ' _ , ' _ , ' tcx > ,
356
+ trait_def_id : DefId ,
357
+ clauses : & mut Vec < Clause < ' tcx > >
358
+ ) {
359
+ tcx. for_each_impl ( trait_def_id, |impl_def_id| {
360
+ for def_id in tcx. associated_item_def_ids ( impl_def_id) . iter ( ) {
361
+ clauses. extend (
362
+ tcx. program_clauses_for ( * def_id)
363
+ . into_iter ( )
364
+ . cloned ( )
365
+ ) ;
366
+ }
367
+ } ) ;
368
+ }
369
+
370
+ let mut clauses = match goal {
371
+ DomainGoal :: Holds ( Implemented ( trait_predicate) ) => {
372
+ // These come from:
373
+ // * implementations of the trait itself (rule `Implemented-From-Impl`)
374
+ // * the trait decl (rule `Implemented-From-Env`)
375
+
376
+ let mut clauses = vec ! [ ] ;
377
+ assemble_clauses_from_impls (
378
+ self . infcx . tcx ,
379
+ trait_predicate. def_id ( ) ,
380
+ & mut clauses
381
+ ) ;
382
+
383
+ // FIXME: we need to add special rules for builtin impls:
384
+ // * `Copy` / `Clone`
385
+ // * `Sized`
386
+ // * `Unsize`
387
+ // * `Generator`
388
+ // * `FnOnce` / `FnMut` / `Fn`
389
+ // * trait objects
390
+ // * auto traits
391
+
392
+ // Rule `Implemented-From-Env` will be computed from the environment.
393
+ clauses
394
+ }
395
+
396
+ DomainGoal :: Holds ( ProjectionEq ( projection_predicate) ) => {
397
+ // These come from:
398
+ // * the assoc type definition (rule `ProjectionEq-Placeholder`)
399
+ // * normalization of the assoc ty values (rule `ProjectionEq-Normalize`)
400
+ // * implied bounds from trait definitions (rule `Implied-Bound-From-Trait`)
401
+ // * implied bounds from type definitions (rule `Implied-Bound-From-Type`)
402
+
403
+ let clauses = self . infcx . tcx . program_clauses_for (
404
+ projection_predicate. projection_ty . item_def_id
405
+ ) . into_iter ( )
406
+
407
+ // only select `ProjectionEq-Placeholder` and `ProjectionEq-Normalize`
408
+ . filter ( |clause| clause. category ( ) == ProgramClauseCategory :: Other )
409
+
410
+ . cloned ( )
411
+ . collect :: < Vec < _ > > ( ) ;
412
+
413
+ // Rules `Implied-Bound-From-Trait` and `Implied-Bound-From-Type` will be computed
414
+ // from the environment.
415
+ clauses
416
+ }
417
+
418
+ DomainGoal :: Holds ( RegionOutlives ( ..) ) => {
340
419
// These come from:
341
- //
342
- // - Trait definitions (implied bounds)
343
- // - Implementations of the trait itself
344
- panic ! ( )
420
+ // * implied bounds from trait definitions (rule `Implied-Bound-From-Trait`)
421
+ // * implied bounds from type definitions (rule `Implied-Bound-From-Type`)
422
+
423
+ // All of these rules are computed in the environment.
424
+ vec ! [ ]
345
425
}
346
426
347
- DomainGoal :: Holds ( ProjectionEq ( _projection_predicate ) ) => {
427
+ DomainGoal :: Holds ( TypeOutlives ( .. ) ) => {
348
428
// These come from:
349
- panic ! ( )
429
+ // * implied bounds from trait definitions (rule `Implied-Bound-From-Trait`)
430
+ // * implied bounds from type definitions (rule `Implied-Bound-From-Type`)
431
+
432
+ // All of these rules are computed in the environment.
433
+ vec ! [ ]
350
434
}
351
435
352
- DomainGoal :: Holds ( RegionOutlives ( _region_outlives) ) => {
353
- panic ! ( )
436
+ DomainGoal :: WellFormed ( WellFormed :: Trait ( trait_predicate) ) => {
437
+ // These come from -- the trait decl (rule `WellFormed-TraitRef`).
438
+ self . infcx . tcx . program_clauses_for ( trait_predicate. def_id ( ) )
439
+ . into_iter ( )
440
+
441
+ // only select `WellFormed-TraitRef`
442
+ . filter ( |clause| clause. category ( ) == ProgramClauseCategory :: WellFormed )
443
+
444
+ . cloned ( )
445
+ . collect ( )
354
446
}
355
447
356
- DomainGoal :: Holds ( TypeOutlives ( _type_outlives) ) => {
357
- panic ! ( )
448
+ DomainGoal :: WellFormed ( WellFormed :: Ty ( ty) ) => {
449
+ // These come from:
450
+ // * the associated type definition if `ty` refers to an unnormalized
451
+ // associated type (rule `WellFormed-AssocTy`)
452
+ // * custom rules for built-in types
453
+ // * the type definition otherwise (rule `WellFormed-Type`)
454
+ let clauses = match ty. sty {
455
+ ty:: Projection ( data) => {
456
+ self . infcx . tcx . program_clauses_for ( data. item_def_id )
457
+ }
458
+
459
+ // These types are always WF (recall that we do not check
460
+ // for parameters to be WF)
461
+ ty:: Bool |
462
+ ty:: Char |
463
+ ty:: Int ( ..) |
464
+ ty:: Uint ( ..) |
465
+ ty:: Float ( ..) |
466
+ ty:: Str |
467
+ ty:: RawPtr ( ..) |
468
+ ty:: FnPtr ( ..) |
469
+ ty:: Param ( ..) |
470
+ ty:: Never => {
471
+ ty:: List :: empty ( )
472
+ }
473
+
474
+ // WF if inner type is `Sized`
475
+ ty:: Slice ( ..) |
476
+ ty:: Array ( ..) => {
477
+ ty:: List :: empty ( )
478
+ }
479
+
480
+ ty:: Tuple ( ..) => {
481
+ ty:: List :: empty ( )
482
+ }
483
+
484
+ // WF if `sub_ty` outlives `region`
485
+ ty:: Ref ( ..) => {
486
+ ty:: List :: empty ( )
487
+ }
488
+
489
+ ty:: Dynamic ( ..) => {
490
+ // FIXME: no rules yet for trait objects
491
+ ty:: List :: empty ( )
492
+ }
493
+
494
+ ty:: Adt ( def, ..) => {
495
+ self . infcx . tcx . program_clauses_for ( def. did )
496
+ }
497
+
498
+ ty:: Foreign ( def_id) |
499
+ ty:: FnDef ( def_id, ..) |
500
+ ty:: Closure ( def_id, ..) |
501
+ ty:: Generator ( def_id, ..) |
502
+ ty:: Opaque ( def_id, ..) => {
503
+ self . infcx . tcx . program_clauses_for ( def_id)
504
+ }
505
+
506
+ ty:: GeneratorWitness ( ..) |
507
+ ty:: UnnormalizedProjection ( ..) |
508
+ ty:: Infer ( ..) |
509
+ ty:: Error => {
510
+ bug ! ( "unexpected type {:?}" , ty)
511
+ }
512
+ } ;
513
+
514
+ clauses. into_iter ( )
515
+ . filter ( |clause| clause. category ( ) == ProgramClauseCategory :: WellFormed )
516
+ . cloned ( )
517
+ . collect ( )
358
518
}
359
519
360
- DomainGoal :: WellFormed ( WellFormed :: Trait ( _trait_predicate) ) => {
361
- // These come from -- the trait decl.
362
- panic ! ( )
520
+ DomainGoal :: FromEnv ( FromEnv :: Trait ( ..) ) => {
521
+ // These come from:
522
+ // * implied bounds from trait definitions (rule `Implied-Bound-From-Trait`)
523
+ // * implied bounds from type definitions (rule `Implied-Bound-From-Type`)
524
+ // * implied bounds from assoc type defs (rules `Implied-Trait-From-AssocTy`,
525
+ // `Implied-Bound-From-AssocTy` and `Implied-WC-From-AssocTy`)
526
+
527
+ // All of these rules are computed in the environment.
528
+ vec ! [ ]
363
529
}
364
530
365
- DomainGoal :: WellFormed ( WellFormed :: Ty ( _ty) ) => panic ! ( ) ,
531
+ DomainGoal :: FromEnv ( FromEnv :: Ty ( ..) ) => {
532
+ // There are no `FromEnv::Ty(..) :- ...` rules (this predicate only
533
+ // comes from the environment).
534
+ vec ! [ ]
535
+ }
366
536
367
- DomainGoal :: FromEnv ( FromEnv :: Trait ( _trait_predicate) ) => panic ! ( ) ,
537
+ DomainGoal :: Normalize ( projection_predicate) => {
538
+ // These come from -- assoc ty values (rule `Normalize-From-Impl`).
539
+ let mut clauses = vec ! [ ] ;
368
540
369
- DomainGoal :: FromEnv ( FromEnv :: Ty ( _ty) ) => panic ! ( ) ,
541
+ assemble_clauses_from_assoc_ty_values (
542
+ self . infcx . tcx ,
543
+ projection_predicate. projection_ty . trait_ref ( self . infcx . tcx ) . def_id ,
544
+ & mut clauses
545
+ ) ;
370
546
371
- DomainGoal :: Normalize ( _) => panic ! ( ) ,
372
- }
547
+ clauses
548
+ }
549
+ } ;
550
+
551
+ let environment = self . infcx . tcx . lift_to_global ( environment)
552
+ . expect ( "environment is not global" ) ;
553
+ clauses. extend (
554
+ self . infcx . tcx . program_clauses_for_env ( environment)
555
+ . into_iter ( )
556
+ . cloned ( )
557
+ ) ;
558
+ clauses
373
559
}
374
560
375
561
fn instantiate_binders_universally (
0 commit comments