@@ -103,6 +103,8 @@ use rustc::ty::fold::TypeFoldable;
103
103
use rustc:: ty:: query:: Providers ;
104
104
use rustc:: ty:: util:: { Representability , IntTypeExt , Discr } ;
105
105
use errors:: { DiagnosticBuilder , DiagnosticId } ;
106
+ use rustc_data_structures:: accumulate_vec:: AccumulateVec ;
107
+ use rustc_data_structures:: array_vec:: ArrayVec ;
106
108
107
109
use require_c_abi_if_variadic;
108
110
use session:: { CompileIncomplete , config, Session } ;
@@ -5002,10 +5004,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5002
5004
let mut infer_types_type_seg = true ;
5003
5005
if let Some ( ( seg, _) ) = type_segment {
5004
5006
if let Some ( ref data) = seg. args {
5005
- for arg in & data. args {
5007
+ for ( i , arg) in data. args . iter ( ) . enumerate ( ) {
5006
5008
match arg {
5007
- GenericArg :: Lifetime ( lt) => lifetimes_type_seg. push ( lt ) ,
5008
- GenericArg :: Type ( ty) => types_type_seg. push ( ty ) ,
5009
+ GenericArg :: Lifetime ( lt) => lifetimes_type_seg. push ( ( i , lt ) ) ,
5010
+ GenericArg :: Type ( ty) => types_type_seg. push ( ( i , ty ) ) ,
5009
5011
}
5010
5012
}
5011
5013
}
@@ -5017,74 +5019,118 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5017
5019
let mut infer_types_fn_seg = true ;
5018
5020
if let Some ( ( seg, _) ) = fn_segment {
5019
5021
if let Some ( ref data) = seg. args {
5020
- for arg in & data. args {
5022
+ for ( i , arg) in data. args . iter ( ) . enumerate ( ) {
5021
5023
match arg {
5022
- GenericArg :: Lifetime ( lt) => lifetimes_fn_seg. push ( lt ) ,
5023
- GenericArg :: Type ( ty) => types_fn_seg. push ( ty ) ,
5024
+ GenericArg :: Lifetime ( lt) => lifetimes_fn_seg. push ( ( i , lt ) ) ,
5025
+ GenericArg :: Type ( ty) => types_fn_seg. push ( ( i , ty ) ) ,
5024
5026
}
5025
5027
}
5026
5028
}
5027
5029
infer_types_fn_seg = seg. infer_types ;
5028
5030
}
5029
5031
5030
- let substs = Substs :: for_item ( self . tcx , def. def_id ( ) , |param, substs| {
5031
- let mut i = param. index as usize ;
5032
-
5033
- let ( segment, lifetimes, types, infer_types) = if i < fn_start {
5034
- if let GenericParamDefKind :: Type { .. } = param. kind {
5035
- // Handle Self first, so we can adjust the index to match the AST.
5036
- if has_self && i == 0 {
5037
- return opt_self_ty. map ( |ty| ty. into ( ) ) . unwrap_or_else ( || {
5038
- self . var_for_def ( span, param)
5039
- } ) ;
5032
+ let defs = self . tcx . generics_of ( def. def_id ( ) ) ;
5033
+ let count = defs. count ( ) ;
5034
+ let mut substs = if count <= 8 {
5035
+ AccumulateVec :: Array ( ArrayVec :: new ( ) )
5036
+ } else {
5037
+ AccumulateVec :: Heap ( Vec :: with_capacity ( count) )
5038
+ } ;
5039
+ let mut stack = vec ! [ def. def_id( ) ] ;
5040
+ let mut parent_defs = defs;
5041
+ while let Some ( def_id) = parent_defs. parent {
5042
+ parent_defs = self . tcx . generics_of ( def_id) ;
5043
+ stack. push ( def_id) ;
5044
+ }
5045
+ while let Some ( def_id) = stack. pop ( ) {
5046
+ let defs = self . tcx . generics_of ( def_id) ;
5047
+ Substs :: fill_single ( & mut substs, defs, & mut |param : & ty:: GenericParamDef , substs| {
5048
+ let mut i = param. index as usize ;
5049
+
5050
+ let ( lifetimes, types, infer_types) = if i < fn_start {
5051
+ if let GenericParamDefKind :: Type { .. } = param. kind {
5052
+ // Handle Self first, so we can adjust the index to match the AST.
5053
+ if has_self && i == 0 {
5054
+ return opt_self_ty. map ( |ty| ty. into ( ) ) . unwrap_or_else ( || {
5055
+ self . var_for_def ( span, param)
5056
+ } ) ;
5057
+ }
5040
5058
}
5041
- }
5042
- i -= has_self as usize ;
5043
- ( type_segment, & lifetimes_type_seg, & types_type_seg, infer_types_type_seg)
5044
- } else {
5045
- i -= fn_start;
5046
- ( fn_segment, & lifetimes_fn_seg, & types_fn_seg, infer_types_fn_seg)
5047
- } ;
5059
+ i -= has_self as usize ;
5060
+ ( & lifetimes_type_seg, & types_type_seg, infer_types_type_seg)
5061
+ } else {
5062
+ i -= fn_start;
5063
+ ( & lifetimes_fn_seg, & types_fn_seg, infer_types_fn_seg)
5064
+ } ;
5048
5065
5049
- match param. kind {
5050
- GenericParamDefKind :: Lifetime => {
5051
- if let Some ( lifetime ) = lifetimes . get ( i ) {
5052
- AstConv :: ast_region_to_region ( self , lifetime , Some ( param ) ) . into ( )
5053
- } else {
5054
- self . re_infer ( span , Some ( param ) ) . unwrap ( ) . into ( )
5066
+ let mut pi = param. index as usize - has_self as usize ;
5067
+
5068
+ let segment = if let Some ( & PathSeg ( _ , ind ) ) = path_segs . iter ( ) . find ( | & PathSeg ( di , _ ) | * di == def_id ) {
5069
+ let seg = & segments [ ind ] ;
5070
+ if lifetimes . len ( ) == 0 {
5071
+ pi -= defs . own_counts ( ) . lifetimes ;
5055
5072
}
5056
- }
5057
- GenericParamDefKind :: Type { .. } => {
5058
- // Skip over the lifetimes in the same segment.
5059
- if let Some ( ( _, generics) ) = segment {
5060
- i -= generics. own_counts ( ) . lifetimes ;
5073
+
5074
+ Some ( ( seg, defs) )
5075
+ } else {
5076
+ None
5077
+ } ;
5078
+
5079
+ // eprintln!("{:?} {:?} {:?}", param.index, i, segment);
5080
+
5081
+
5082
+
5083
+ match param. kind {
5084
+ GenericParamDefKind :: Lifetime => {
5085
+ if let Some ( ( z, lt) ) = lifetimes. get ( i) {
5086
+ eprintln ! ( "lifetime {:?} {:?} {:?}" , pi, z, has_self) ;
5087
+ if pi != * z {
5088
+ eprintln ! ( "error {:?} {:?} {:?} {:?} {:?} {:?}" , pi, z, i, segment, fn_start, has_self) ;
5089
+ bug ! ( "uh oh" )
5090
+ }
5091
+ AstConv :: ast_region_to_region ( self , lt, Some ( param) ) . into ( )
5092
+ } else {
5093
+ self . re_infer ( span, Some ( param) ) . unwrap ( ) . into ( )
5094
+ }
5061
5095
}
5096
+ GenericParamDefKind :: Type { .. } => {
5097
+ // Skip over the lifetimes in the same segment.
5098
+ if let Some ( ( _, generics) ) = segment {
5099
+ i -= generics. own_counts ( ) . lifetimes ;
5100
+ }
5062
5101
5063
- let has_default = match param. kind {
5064
- GenericParamDefKind :: Type { has_default, .. } => has_default,
5065
- _ => unreachable ! ( )
5066
- } ;
5102
+ let has_default = match param. kind {
5103
+ GenericParamDefKind :: Type { has_default, .. } => has_default,
5104
+ _ => unreachable ! ( )
5105
+ } ;
5067
5106
5068
- if let Some ( ast_ty) = types. get ( i) {
5069
- // A provided type parameter.
5070
- self . to_ty ( ast_ty) . into ( )
5071
- } else if !infer_types && has_default {
5072
- // No type parameter provided, but a default exists.
5073
- let default = self . tcx . type_of ( param. def_id ) ;
5074
- self . normalize_ty (
5075
- span,
5076
- default. subst_spanned ( self . tcx , substs, Some ( span) )
5077
- ) . into ( )
5078
- } else {
5079
- // No type parameters were provided, we can infer all.
5080
- // This can also be reached in some error cases:
5081
- // We prefer to use inference variables instead of
5082
- // TyError to let type inference recover somewhat.
5083
- self . var_for_def ( span, param)
5107
+ if let Some ( ( z, ty) ) = types. get ( i) {
5108
+ eprintln ! ( "type {:?} {:?} {:?}" , pi, z, has_self) ;
5109
+ if pi != * z {
5110
+ eprintln ! ( "error {:?} {:?} {:?} {:?} {:?} {:?}" , pi, z, i, segment, fn_start, has_self) ;
5111
+ bug ! ( "uh oh" )
5112
+ }
5113
+ // A provided type parameter.
5114
+ self . to_ty ( ty) . into ( )
5115
+ } else if !infer_types && has_default {
5116
+ // No type parameter provided, but a default exists.
5117
+ let default = self . tcx . type_of ( param. def_id ) ;
5118
+ self . normalize_ty (
5119
+ span,
5120
+ default. subst_spanned ( self . tcx , substs, Some ( span) )
5121
+ ) . into ( )
5122
+ } else {
5123
+ // No type parameters were provided, we can infer all.
5124
+ // This can also be reached in some error cases:
5125
+ // We prefer to use inference variables instead of
5126
+ // TyError to let type inference recover somewhat.
5127
+ self . var_for_def ( span, param)
5128
+ }
5084
5129
}
5085
5130
}
5086
- }
5087
- } ) ;
5131
+ } ) ;
5132
+ }
5133
+ let substs = self . tcx . intern_substs ( & substs) ;
5088
5134
5089
5135
// The things we are substituting into the type should not contain
5090
5136
// escaping late-bound regions, and nor should the base type scheme.
0 commit comments