@@ -191,6 +191,7 @@ impl LowerProgram for Program {
191
191
id : info. id ,
192
192
name : defn. name . str ,
193
193
parameter_kinds : parameter_kinds,
194
+ bounds : defn. bounds . lower ( & env) ?,
194
195
where_clauses : defn. where_clauses . lower ( & env) ?,
195
196
} ,
196
197
) ;
@@ -441,32 +442,37 @@ trait LowerWhereClause<T> {
441
442
/// type in Rust and well-formedness checks.
442
443
impl LowerWhereClause < ir:: DomainGoal > for WhereClause {
443
444
fn lower ( & self , env : & Env ) -> Result < Vec < ir:: DomainGoal > > {
444
- let goal = match self {
445
+ let goals = match self {
445
446
WhereClause :: Implemented { trait_ref } => {
446
- ir:: DomainGoal :: Holds ( ir:: WhereClauseAtom :: Implemented ( trait_ref. lower ( env) ?) )
447
+ vec ! [ ir:: DomainGoal :: Holds ( ir:: WhereClauseAtom :: Implemented ( trait_ref. lower( env) ?) ) ]
447
448
}
448
449
WhereClause :: ProjectionEq {
449
450
projection,
450
451
ty,
451
- } => ir:: DomainGoal :: Holds ( ir:: WhereClauseAtom :: ProjectionEq ( ir:: ProjectionEq {
452
- projection : projection. lower ( env) ?,
453
- ty : ty. lower ( env) ?,
454
- } ) ) ,
452
+ } => vec ! [
453
+ ir:: DomainGoal :: Holds ( ir:: WhereClauseAtom :: ProjectionEq ( ir:: ProjectionEq {
454
+ projection: projection. lower( env) ?,
455
+ ty: ty. lower( env) ?,
456
+ } ) ) ,
457
+ ir:: DomainGoal :: Holds ( ir:: WhereClauseAtom :: Implemented (
458
+ projection. trait_ref. lower( env) ?
459
+ ) ) ,
460
+ ] ,
455
461
WhereClause :: Normalize {
456
462
projection,
457
463
ty,
458
- } => ir:: DomainGoal :: Normalize ( ir:: Normalize {
464
+ } => vec ! [ ir:: DomainGoal :: Normalize ( ir:: Normalize {
459
465
projection: projection. lower( env) ?,
460
466
ty: ty. lower( env) ?,
461
- } ) ,
462
- WhereClause :: TyWellFormed { ty } => ir:: DomainGoal :: WellFormedTy ( ty. lower ( env) ?) ,
463
- WhereClause :: TraitRefWellFormed { trait_ref } => {
467
+ } ) ] ,
468
+ WhereClause :: TyWellFormed { ty } => vec ! [ ir:: DomainGoal :: WellFormedTy ( ty. lower( env) ?) ] ,
469
+ WhereClause :: TraitRefWellFormed { trait_ref } => vec ! [
464
470
ir:: DomainGoal :: WellFormed ( ir:: WhereClauseAtom :: Implemented ( trait_ref. lower( env) ?) )
465
- }
466
- WhereClause :: TyFromEnv { ty } => ir:: DomainGoal :: FromEnvTy ( ty. lower ( env) ?) ,
467
- WhereClause :: TraitRefFromEnv { trait_ref } => {
471
+ ] ,
472
+ WhereClause :: TyFromEnv { ty } => vec ! [ ir:: DomainGoal :: FromEnvTy ( ty. lower( env) ?) ] ,
473
+ WhereClause :: TraitRefFromEnv { trait_ref } => vec ! [
468
474
ir:: DomainGoal :: FromEnv ( ir:: WhereClauseAtom :: Implemented ( trait_ref. lower( env) ?) )
469
- }
475
+ ] ,
470
476
WhereClause :: UnifyTys { .. } | WhereClause :: UnifyLifetimes { .. } => {
471
477
bail ! ( "this form of where-clause not allowed here" )
472
478
}
@@ -480,19 +486,19 @@ impl LowerWhereClause<ir::DomainGoal> for WhereClause {
480
486
bail ! ( ErrorKind :: NotTrait ( trait_name) ) ;
481
487
}
482
488
483
- ir:: DomainGoal :: InScope ( id)
489
+ vec ! [ ir:: DomainGoal :: InScope ( id) ]
484
490
}
485
- WhereClause :: Derefs { source, target } => {
491
+ WhereClause :: Derefs { source, target } => vec ! [
486
492
ir:: DomainGoal :: Derefs ( ir:: Derefs {
487
493
source: source. lower( env) ?,
488
494
target: target. lower( env) ?
489
495
} )
490
- }
491
- WhereClause :: TyIsLocal { ty } => {
496
+ ] ,
497
+ WhereClause :: TyIsLocal { ty } => vec ! [
492
498
ir:: DomainGoal :: IsLocalTy ( ty. lower( env) ?)
493
- }
499
+ ] ,
494
500
} ;
495
- Ok ( vec ! [ goal ] )
501
+ Ok ( goals )
496
502
}
497
503
}
498
504
@@ -638,6 +644,107 @@ impl LowerTraitRef for TraitRef {
638
644
}
639
645
}
640
646
647
+ trait LowerTraitBound {
648
+ fn lower_trait_bound ( & self , env : & Env ) -> Result < ir:: TraitBound > ;
649
+ }
650
+
651
+ impl LowerTraitBound for TraitBound {
652
+ fn lower_trait_bound ( & self , env : & Env ) -> Result < ir:: TraitBound > {
653
+ let id = match env. lookup ( self . trait_name ) ? {
654
+ NameLookup :: Type ( id) => id,
655
+ NameLookup :: Parameter ( _) => bail ! ( ErrorKind :: NotTrait ( self . trait_name) ) ,
656
+ } ;
657
+
658
+ let k = env. type_kind ( id) ;
659
+ if k. sort != ir:: TypeSort :: Trait {
660
+ bail ! ( ErrorKind :: NotTrait ( self . trait_name) ) ;
661
+ }
662
+
663
+ let parameters = self . args_no_self
664
+ . iter ( )
665
+ . map ( |a| Ok ( a. lower ( env) ?) )
666
+ . collect :: < Result < Vec < _ > > > ( ) ?;
667
+
668
+ if parameters. len ( ) != k. binders . len ( ) {
669
+ bail ! (
670
+ "wrong number of parameters, expected `{:?}`, got `{:?}`" ,
671
+ k. binders. len( ) ,
672
+ parameters. len( )
673
+ )
674
+ }
675
+
676
+ for ( binder, param) in k. binders . binders . iter ( ) . zip ( parameters. iter ( ) ) {
677
+ check_type_kinds ( "incorrect kind for trait parameter" , binder, param) ?;
678
+ }
679
+
680
+ Ok ( ir:: TraitBound {
681
+ trait_id : id,
682
+ args_no_self : parameters,
683
+ } )
684
+ }
685
+ }
686
+
687
+ trait LowerInlineBound {
688
+ fn lower ( & self , env : & Env ) -> Result < ir:: InlineBound > ;
689
+ }
690
+
691
+ impl LowerInlineBound for TraitBound {
692
+ fn lower ( & self , env : & Env ) -> Result < ir:: InlineBound > {
693
+ Ok ( ir:: InlineBound :: TraitBound ( self . lower_trait_bound ( & env) ?) )
694
+ }
695
+ }
696
+
697
+ impl LowerInlineBound for ProjectionEqBound {
698
+ fn lower ( & self , env : & Env ) -> Result < ir:: InlineBound > {
699
+ let trait_bound = self . trait_bound . lower_trait_bound ( env) ?;
700
+ let info = match env. associated_ty_infos . get ( & ( trait_bound. trait_id , self . name . str ) ) {
701
+ Some ( info) => info,
702
+ None => bail ! ( "no associated type `{}` defined in trait" , self . name. str ) ,
703
+ } ;
704
+ let args: Vec < _ > = try!( self . args . iter ( ) . map ( |a| a. lower ( env) ) . collect ( ) ) ;
705
+
706
+ if args. len ( ) != info. addl_parameter_kinds . len ( ) {
707
+ bail ! (
708
+ "wrong number of parameters for associated type (expected {}, got {})" ,
709
+ info. addl_parameter_kinds. len( ) ,
710
+ args. len( )
711
+ )
712
+ }
713
+
714
+ for ( param, arg) in info. addl_parameter_kinds . iter ( ) . zip ( args. iter ( ) ) {
715
+ check_type_kinds ( "incorrect kind for associated type parameter" , param, arg) ?;
716
+ }
717
+
718
+ Ok ( ir:: InlineBound :: ProjectionEqBound ( ir:: ProjectionEqBound {
719
+ trait_bound,
720
+ associated_ty_id : info. id ,
721
+ parameters : args,
722
+ value : self . value . lower ( env) ?,
723
+ } ) )
724
+ }
725
+ }
726
+
727
+ impl LowerInlineBound for InlineBound {
728
+ fn lower ( & self , env : & Env ) -> Result < ir:: InlineBound > {
729
+ match self {
730
+ InlineBound :: TraitBound ( b) => b. lower ( & env) ,
731
+ InlineBound :: ProjectionEqBound ( b) => b. lower ( & env) ,
732
+ }
733
+ }
734
+ }
735
+
736
+ trait LowerInlineBounds {
737
+ fn lower ( & self , env : & Env ) -> Result < Vec < ir:: InlineBound > > ;
738
+ }
739
+
740
+ impl LowerInlineBounds for Vec < InlineBound > {
741
+ fn lower ( & self , env : & Env ) -> Result < Vec < ir:: InlineBound > > {
742
+ self . iter ( )
743
+ . map ( |b| b. lower ( env) )
744
+ . collect ( )
745
+ }
746
+ }
747
+
641
748
trait LowerPolarizedTraitRef {
642
749
fn lower ( & self , env : & Env ) -> Result < ir:: PolarizedTraitRef > ;
643
750
}
0 commit comments