@@ -191,6 +191,7 @@ impl LowerProgram for Program {
191191 id : info. id ,
192192 name : defn. name . str ,
193193 parameter_kinds : parameter_kinds,
194+ bounds : defn. bounds . lower ( & env) ?,
194195 where_clauses : defn. where_clauses . lower ( & env) ?,
195196 } ,
196197 ) ;
@@ -441,32 +442,37 @@ trait LowerWhereClause<T> {
441442/// type in Rust and well-formedness checks.
442443impl LowerWhereClause < ir:: DomainGoal > for WhereClause {
443444 fn lower ( & self , env : & Env ) -> Result < Vec < ir:: DomainGoal > > {
444- let goal = match self {
445+ let goals = match self {
445446 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) ?) ) ]
447448 }
448449 WhereClause :: ProjectionEq {
449450 projection,
450451 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+ ] ,
455461 WhereClause :: Normalize {
456462 projection,
457463 ty,
458- } => ir:: DomainGoal :: Normalize ( ir:: Normalize {
464+ } => vec ! [ ir:: DomainGoal :: Normalize ( ir:: Normalize {
459465 projection: projection. lower( env) ?,
460466 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 ! [
464470 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 ! [
468474 ir:: DomainGoal :: FromEnv ( ir:: WhereClauseAtom :: Implemented ( trait_ref. lower( env) ?) )
469- }
475+ ] ,
470476 WhereClause :: UnifyTys { .. } | WhereClause :: UnifyLifetimes { .. } => {
471477 bail ! ( "this form of where-clause not allowed here" )
472478 }
@@ -480,19 +486,19 @@ impl LowerWhereClause<ir::DomainGoal> for WhereClause {
480486 bail ! ( ErrorKind :: NotTrait ( trait_name) ) ;
481487 }
482488
483- ir:: DomainGoal :: InScope ( id)
489+ vec ! [ ir:: DomainGoal :: InScope ( id) ]
484490 }
485- WhereClause :: Derefs { source, target } => {
491+ WhereClause :: Derefs { source, target } => vec ! [
486492 ir:: DomainGoal :: Derefs ( ir:: Derefs {
487493 source: source. lower( env) ?,
488494 target: target. lower( env) ?
489495 } )
490- }
491- WhereClause :: TyIsLocal { ty } => {
496+ ] ,
497+ WhereClause :: TyIsLocal { ty } => vec ! [
492498 ir:: DomainGoal :: IsLocalTy ( ty. lower( env) ?)
493- }
499+ ] ,
494500 } ;
495- Ok ( vec ! [ goal ] )
501+ Ok ( goals )
496502 }
497503}
498504
@@ -638,6 +644,107 @@ impl LowerTraitRef for TraitRef {
638644 }
639645}
640646
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+
641748trait LowerPolarizedTraitRef {
642749 fn lower ( & self , env : & Env ) -> Result < ir:: PolarizedTraitRef > ;
643750}
0 commit comments