@@ -80,6 +80,7 @@ use syntax::ast;
8080use syntax:: ast_map;
8181use syntax:: ast_util;
8282use syntax:: ast_util:: name_to_dummy_lifetime;
83+ use syntax:: owned_slice:: OwnedSlice ;
8384use syntax:: parse:: token;
8485use syntax:: print:: pprust;
8586use util:: ppaux:: UserString ;
@@ -678,6 +679,17 @@ impl<'a> ErrorReporting for InferCtxt<'a> {
678679 }
679680}
680681
682+ struct RebuildPathInfo < ' a > {
683+ path : & ' a ast:: Path ,
684+ // indexes to insert lifetime on path.lifetimes
685+ indexes : Vec < uint > ,
686+ // number of lifetimes we expect to see on the type referred by `path`
687+ // (e.g., expected=1 for struct Foo<'a>)
688+ expected : uint ,
689+ anon_nums : & ' a HashSet < uint > ,
690+ region_names : & ' a HashSet < ast:: Name >
691+ }
692+
681693struct Rebuilder < ' a > {
682694 tcx : & ' a ty:: ctxt ,
683695 fn_decl : ast:: P < ast:: FnDecl > ,
@@ -708,6 +720,7 @@ impl<'a> Rebuilder<'a> {
708720 fn rebuild ( & self ) -> ( Vec < ast:: Arg > , ast:: P < ast:: Ty > , ast:: Generics ) {
709721 let mut inputs = self . fn_decl . inputs . clone ( ) ;
710722 let mut output = self . fn_decl . output ;
723+ let mut ty_params = self . generics . ty_params . clone ( ) ;
711724 for sr in self . same_regions . iter ( ) {
712725 self . cur_anon . set ( 0 ) ;
713726 self . offset_cur_anon ( ) ;
@@ -718,12 +731,14 @@ impl<'a> Rebuilder<'a> {
718731 & anon_nums, & region_names) ;
719732 output = self . rebuild_arg_ty_or_output ( output, lifetime,
720733 & anon_nums, & region_names) ;
734+ ty_params = self . rebuild_ty_params ( ty_params, lifetime,
735+ & region_names) ;
721736 }
722737 let generated_lifetimes = self . life_giver . get_generated_lifetimes ( ) ;
723738 let all_region_names = self . extract_all_region_names ( ) ;
724739 let generics = self . rebuild_generics ( self . generics ,
725740 generated_lifetimes,
726- & all_region_names) ;
741+ & all_region_names, ty_params ) ;
727742 ( inputs, output, generics)
728743 }
729744
@@ -782,10 +797,62 @@ impl<'a> Rebuilder<'a> {
782797 self . inserted_anons . borrow_mut ( ) . insert ( anon) ;
783798 }
784799
800+ fn rebuild_ty_params ( & self ,
801+ ty_params : OwnedSlice < ast:: TyParam > ,
802+ lifetime : ast:: Lifetime ,
803+ region_names : & HashSet < ast:: Name > )
804+ -> OwnedSlice < ast:: TyParam > {
805+ ty_params. map ( |ty_param| {
806+ let bounds = self . rebuild_ty_param_bounds ( ty_param. bounds . clone ( ) ,
807+ lifetime,
808+ region_names) ;
809+ ast:: TyParam {
810+ ident : ty_param. ident ,
811+ id : ty_param. id ,
812+ bounds : bounds,
813+ default : ty_param. default ,
814+ }
815+ } )
816+ }
817+
818+ fn rebuild_ty_param_bounds ( & self ,
819+ ty_param_bounds : OwnedSlice < ast:: TyParamBound > ,
820+ lifetime : ast:: Lifetime ,
821+ region_names : & HashSet < ast:: Name > )
822+ -> OwnedSlice < ast:: TyParamBound > {
823+ ty_param_bounds. map ( |tpb| {
824+ match tpb {
825+ & ast:: RegionTyParamBound => ast:: RegionTyParamBound ,
826+ & ast:: TraitTyParamBound ( ref tr) => {
827+ let last_seg = tr. path . segments . last ( ) . unwrap ( ) ;
828+ let mut insert = Vec :: new ( ) ;
829+ for ( i, lt) in last_seg. lifetimes . iter ( ) . enumerate ( ) {
830+ if region_names. contains ( & lt. name ) {
831+ insert. push ( i) ;
832+ }
833+ }
834+ let rebuild_info = RebuildPathInfo {
835+ path : & tr. path ,
836+ indexes : insert,
837+ expected : last_seg. lifetimes . len ( ) ,
838+ anon_nums : & HashSet :: new ( ) ,
839+ region_names : region_names
840+ } ;
841+ let new_path = self . rebuild_path ( rebuild_info, lifetime) ;
842+ ast:: TraitTyParamBound ( ast:: TraitRef {
843+ path : new_path,
844+ ref_id : tr. ref_id ,
845+ } )
846+ }
847+ }
848+ } )
849+ }
850+
785851 fn rebuild_generics ( & self ,
786852 generics : & ast:: Generics ,
787853 add : Vec < ast:: Lifetime > ,
788- remove : & HashSet < ast:: Name > )
854+ remove : & HashSet < ast:: Name > ,
855+ ty_params : OwnedSlice < ast:: TyParam > )
789856 -> ast:: Generics {
790857 let mut lifetimes = Vec :: new ( ) ;
791858 for lt in add. iter ( ) {
@@ -798,7 +865,7 @@ impl<'a> Rebuilder<'a> {
798865 }
799866 ast:: Generics {
800867 lifetimes : lifetimes,
801- ty_params : generics . ty_params . clone ( )
868+ ty_params : ty_params
802869 }
803870 }
804871
@@ -886,11 +953,16 @@ impl<'a> Rebuilder<'a> {
886953 }
887954 }
888955 }
889- for i in insert. iter ( ) {
890- new_ty = self . rebuild_ty ( new_ty, cur_ty,
891- lifetime,
892- Some ( ( * i, expected) ) ) ;
893- }
956+ let rebuild_info = RebuildPathInfo {
957+ path : path,
958+ indexes : insert,
959+ expected : expected,
960+ anon_nums : anon_nums,
961+ region_names : region_names
962+ } ;
963+ new_ty = self . rebuild_ty ( new_ty, cur_ty,
964+ lifetime,
965+ Some ( rebuild_info) ) ;
894966 }
895967 _ => ( )
896968 }
@@ -906,7 +978,7 @@ impl<'a> Rebuilder<'a> {
906978 from : ast:: P < ast:: Ty > ,
907979 to : ast:: P < ast:: Ty > ,
908980 lifetime : ast:: Lifetime ,
909- index_opt : Option < ( uint , uint ) > )
981+ rebuild_path_info : Option < RebuildPathInfo > )
910982 -> ast:: P < ast:: Ty > {
911983
912984 fn build_to ( from : ast:: P < ast:: Ty > ,
@@ -950,13 +1022,12 @@ impl<'a> Rebuilder<'a> {
9501022
9511023 let new_ty_node = match to. node {
9521024 ast:: TyRptr ( _, mut_ty) => ast:: TyRptr ( Some ( lifetime) , mut_ty) ,
953- ast:: TyPath ( ref path , ref bounds, id) => {
954- let ( index , expected ) = match index_opt {
955- Some ( ( i , e ) ) => ( i , e ) ,
1025+ ast:: TyPath ( _ , ref bounds, id) => {
1026+ let rebuild_info = match rebuild_path_info {
1027+ Some ( ri ) => ri ,
9561028 None => fail ! ( "expect index_opt in rebuild_ty/ast::TyPath" )
9571029 } ;
958- let new_path = self . rebuild_path ( path, index,
959- expected, lifetime) ;
1030+ let new_path = self . rebuild_path ( rebuild_info, lifetime) ;
9601031 ast:: TyPath ( new_path, bounds. clone ( ) , id)
9611032 }
9621033 _ => fail ! ( "expect ast::TyRptr or ast::TyPath" )
@@ -970,34 +1041,49 @@ impl<'a> Rebuilder<'a> {
9701041 }
9711042
9721043 fn rebuild_path ( & self ,
973- path : & ast:: Path ,
974- index : uint ,
975- expected : uint ,
1044+ rebuild_info : RebuildPathInfo ,
9761045 lifetime : ast:: Lifetime )
9771046 -> ast:: Path {
1047+ let RebuildPathInfo {
1048+ path : path,
1049+ indexes : indexes,
1050+ expected : expected,
1051+ anon_nums : anon_nums,
1052+ region_names : region_names,
1053+ } = rebuild_info;
1054+
9781055 let last_seg = path. segments . last ( ) . unwrap ( ) ;
9791056 let mut new_lts = Vec :: new ( ) ;
9801057 if last_seg. lifetimes . len ( ) == 0 {
981- for i in range ( 0 , expected) {
982- if i == index {
983- new_lts. push ( lifetime) ;
984- } else {
985- new_lts. push ( self . life_giver . give_lifetime ( ) ) ;
1058+ // traverse once to see if there's a need to insert lifetime
1059+ let need_insert = range ( 0 , expected) . any ( |i| {
1060+ indexes. contains ( & i)
1061+ } ) ;
1062+ if need_insert {
1063+ for i in range ( 0 , expected) {
1064+ if indexes. contains ( & i) {
1065+ new_lts. push ( lifetime) ;
1066+ } else {
1067+ new_lts. push ( self . life_giver . give_lifetime ( ) ) ;
1068+ }
9861069 }
9871070 }
9881071 } else {
9891072 for ( i, lt) in last_seg. lifetimes . iter ( ) . enumerate ( ) {
990- if i == index {
1073+ if indexes . contains ( & i ) {
9911074 new_lts. push ( lifetime) ;
9921075 } else {
9931076 new_lts. push ( * lt) ;
9941077 }
9951078 }
9961079 }
1080+ let new_types = last_seg. types . map ( |& t| {
1081+ self . rebuild_arg_ty_or_output ( t, lifetime, anon_nums, region_names)
1082+ } ) ;
9971083 let new_seg = ast:: PathSegment {
9981084 identifier : last_seg. identifier ,
9991085 lifetimes : new_lts,
1000- types : last_seg . types . clone ( ) ,
1086+ types : new_types ,
10011087 } ;
10021088 let mut new_segs = Vec :: new ( ) ;
10031089 new_segs. push_all ( path. segments . init ( ) ) ;
0 commit comments