@@ -80,6 +80,7 @@ use syntax::ast;
80
80
use syntax:: ast_map;
81
81
use syntax:: ast_util;
82
82
use syntax:: ast_util:: name_to_dummy_lifetime;
83
+ use syntax:: owned_slice:: OwnedSlice ;
83
84
use syntax:: parse:: token;
84
85
use syntax:: print:: pprust;
85
86
use util:: ppaux:: UserString ;
@@ -678,6 +679,17 @@ impl<'a> ErrorReporting for InferCtxt<'a> {
678
679
}
679
680
}
680
681
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
+
681
693
struct Rebuilder < ' a > {
682
694
tcx : & ' a ty:: ctxt ,
683
695
fn_decl : ast:: P < ast:: FnDecl > ,
@@ -708,6 +720,7 @@ impl<'a> Rebuilder<'a> {
708
720
fn rebuild ( & self ) -> ( Vec < ast:: Arg > , ast:: P < ast:: Ty > , ast:: Generics ) {
709
721
let mut inputs = self . fn_decl . inputs . clone ( ) ;
710
722
let mut output = self . fn_decl . output ;
723
+ let mut ty_params = self . generics . ty_params . clone ( ) ;
711
724
for sr in self . same_regions . iter ( ) {
712
725
self . cur_anon . set ( 0 ) ;
713
726
self . offset_cur_anon ( ) ;
@@ -718,12 +731,14 @@ impl<'a> Rebuilder<'a> {
718
731
& anon_nums, & region_names) ;
719
732
output = self . rebuild_arg_ty_or_output ( output, lifetime,
720
733
& anon_nums, & region_names) ;
734
+ ty_params = self . rebuild_ty_params ( ty_params, lifetime,
735
+ & region_names) ;
721
736
}
722
737
let generated_lifetimes = self . life_giver . get_generated_lifetimes ( ) ;
723
738
let all_region_names = self . extract_all_region_names ( ) ;
724
739
let generics = self . rebuild_generics ( self . generics ,
725
740
generated_lifetimes,
726
- & all_region_names) ;
741
+ & all_region_names, ty_params ) ;
727
742
( inputs, output, generics)
728
743
}
729
744
@@ -782,10 +797,62 @@ impl<'a> Rebuilder<'a> {
782
797
self . inserted_anons . borrow_mut ( ) . insert ( anon) ;
783
798
}
784
799
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
+
785
851
fn rebuild_generics ( & self ,
786
852
generics : & ast:: Generics ,
787
853
add : Vec < ast:: Lifetime > ,
788
- remove : & HashSet < ast:: Name > )
854
+ remove : & HashSet < ast:: Name > ,
855
+ ty_params : OwnedSlice < ast:: TyParam > )
789
856
-> ast:: Generics {
790
857
let mut lifetimes = Vec :: new ( ) ;
791
858
for lt in add. iter ( ) {
@@ -798,7 +865,7 @@ impl<'a> Rebuilder<'a> {
798
865
}
799
866
ast:: Generics {
800
867
lifetimes : lifetimes,
801
- ty_params : generics . ty_params . clone ( )
868
+ ty_params : ty_params
802
869
}
803
870
}
804
871
@@ -886,11 +953,16 @@ impl<'a> Rebuilder<'a> {
886
953
}
887
954
}
888
955
}
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) ) ;
894
966
}
895
967
_ => ( )
896
968
}
@@ -906,7 +978,7 @@ impl<'a> Rebuilder<'a> {
906
978
from : ast:: P < ast:: Ty > ,
907
979
to : ast:: P < ast:: Ty > ,
908
980
lifetime : ast:: Lifetime ,
909
- index_opt : Option < ( uint , uint ) > )
981
+ rebuild_path_info : Option < RebuildPathInfo > )
910
982
-> ast:: P < ast:: Ty > {
911
983
912
984
fn build_to ( from : ast:: P < ast:: Ty > ,
@@ -950,13 +1022,12 @@ impl<'a> Rebuilder<'a> {
950
1022
951
1023
let new_ty_node = match to. node {
952
1024
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 ,
956
1028
None => fail ! ( "expect index_opt in rebuild_ty/ast::TyPath" )
957
1029
} ;
958
- let new_path = self . rebuild_path ( path, index,
959
- expected, lifetime) ;
1030
+ let new_path = self . rebuild_path ( rebuild_info, lifetime) ;
960
1031
ast:: TyPath ( new_path, bounds. clone ( ) , id)
961
1032
}
962
1033
_ => fail ! ( "expect ast::TyRptr or ast::TyPath" )
@@ -970,34 +1041,49 @@ impl<'a> Rebuilder<'a> {
970
1041
}
971
1042
972
1043
fn rebuild_path ( & self ,
973
- path : & ast:: Path ,
974
- index : uint ,
975
- expected : uint ,
1044
+ rebuild_info : RebuildPathInfo ,
976
1045
lifetime : ast:: Lifetime )
977
1046
-> 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
+
978
1055
let last_seg = path. segments . last ( ) . unwrap ( ) ;
979
1056
let mut new_lts = Vec :: new ( ) ;
980
1057
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
+ }
986
1069
}
987
1070
}
988
1071
} else {
989
1072
for ( i, lt) in last_seg. lifetimes . iter ( ) . enumerate ( ) {
990
- if i == index {
1073
+ if indexes . contains ( & i ) {
991
1074
new_lts. push ( lifetime) ;
992
1075
} else {
993
1076
new_lts. push ( * lt) ;
994
1077
}
995
1078
}
996
1079
}
1080
+ let new_types = last_seg. types . map ( |& t| {
1081
+ self . rebuild_arg_ty_or_output ( t, lifetime, anon_nums, region_names)
1082
+ } ) ;
997
1083
let new_seg = ast:: PathSegment {
998
1084
identifier : last_seg. identifier ,
999
1085
lifetimes : new_lts,
1000
- types : last_seg . types . clone ( ) ,
1086
+ types : new_types ,
1001
1087
} ;
1002
1088
let mut new_segs = Vec :: new ( ) ;
1003
1089
new_segs. push_all ( path. segments . init ( ) ) ;
0 commit comments