@@ -23,13 +23,15 @@ use rustc::traits::{
2323 Goal ,
2424 GoalKind ,
2525 Clause ,
26+ ProgramClauseCategory ,
2627 QuantifierKind ,
2728 Environment ,
2829 InEnvironment ,
2930} ;
3031use rustc:: ty:: fold:: { TypeFoldable , TypeFolder , TypeVisitor } ;
3132use rustc:: ty:: subst:: Kind ;
3233use rustc:: ty:: { self , TyCtxt } ;
34+ use rustc:: hir:: def_id:: DefId ;
3335
3436use std:: fmt:: { self , Debug } ;
3537use std:: marker:: PhantomData ;
@@ -330,46 +332,230 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
330332{
331333 fn program_clauses (
332334 & self ,
333- _environment : & Environment < ' tcx > ,
335+ environment : & Environment < ' tcx > ,
334336 goal : & DomainGoal < ' tcx > ,
335337 ) -> Vec < Clause < ' tcx > > {
336338 use rustc:: traits:: WhereClause :: * ;
337339
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 ( ..) ) => {
340419 // 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 ! [ ]
345425 }
346426
347- DomainGoal :: Holds ( ProjectionEq ( _projection_predicate ) ) => {
427+ DomainGoal :: Holds ( TypeOutlives ( .. ) ) => {
348428 // 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 ! [ ]
350434 }
351435
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 ( )
354446 }
355447
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 ( )
358518 }
359519
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 ! [ ]
363529 }
364530
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+ }
366536
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 ! [ ] ;
368540
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+ ) ;
370546
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
373559 }
374560
375561 fn instantiate_binders_universally (
0 commit comments