@@ -4983,115 +4983,82 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
4983
4983
// variables. If the user provided some types, we may still need
4984
4984
// to add defaults. If the user provided *too many* types, that's
4985
4985
// a problem.
4986
+ let mut infer_lifetimes = FxHashMap ( ) ;
4986
4987
let supress_mismatch = self . check_impl_trait ( span, fn_segment) ;
4987
4988
for & PathSeg ( def_id, index) in & path_segs {
4988
4989
let generics = self . tcx . generics_of ( def_id) ;
4989
- self . check_generic_arg_count ( span, & segments[ index] , & generics, false , supress_mismatch) ;
4990
+ let seg = & segments[ index] ;
4991
+ self . check_generic_arg_count ( span, seg, & generics, false , supress_mismatch) ;
4992
+ infer_lifetimes. insert ( index, if let Some ( ref data) = seg. args {
4993
+ !data. args . iter ( ) . any ( |arg| match arg {
4994
+ GenericArg :: Lifetime ( _) => true ,
4995
+ _ => false ,
4996
+ } )
4997
+ } else {
4998
+ true
4999
+ } ) ;
4990
5000
}
4991
5001
4992
5002
let has_self = path_segs. last ( ) . map ( |PathSeg ( def_id, _) | {
4993
5003
self . tcx . generics_of ( * def_id) . has_self
4994
5004
} ) . unwrap_or ( false ) ;
4995
5005
4996
- let fn_start = match ( type_segment, fn_segment) {
4997
- ( _, Some ( ( _, generics) ) ) => generics. parent_count ,
4998
- ( Some ( ( _, generics) ) , None ) => generics. params . len ( ) ,
4999
- ( None , None ) => 0 ,
5000
- } ;
5001
- // FIXME(varkor): Separating out the parameters is messy.
5002
- let mut lifetimes_type_seg = vec ! [ ] ;
5003
- let mut types_type_seg = vec ! [ ] ;
5004
- let mut _infer_types_type_seg = true ;
5005
- if let Some ( ( seg, _) ) = type_segment {
5006
- if let Some ( ref data) = seg. args {
5007
- for ( i, arg) in data. args . iter ( ) . enumerate ( ) {
5008
- match arg {
5009
- GenericArg :: Lifetime ( lt) => lifetimes_type_seg. push ( ( i, lt) ) ,
5010
- GenericArg :: Type ( ty) => types_type_seg. push ( ( i, ty) ) ,
5011
- }
5012
- }
5013
- }
5014
- _infer_types_type_seg = seg. infer_types ;
5015
- }
5016
-
5017
- let mut lifetimes_fn_seg = vec ! [ ] ;
5018
- let mut types_fn_seg = vec ! [ ] ;
5019
- let mut _infer_types_fn_seg = true ;
5020
- if let Some ( ( seg, _) ) = fn_segment {
5021
- if let Some ( ref data) = seg. args {
5022
- for ( i, arg) in data. args . iter ( ) . enumerate ( ) {
5023
- match arg {
5024
- GenericArg :: Lifetime ( lt) => lifetimes_fn_seg. push ( ( i, lt) ) ,
5025
- GenericArg :: Type ( ty) => types_fn_seg. push ( ( i, ty) ) ,
5026
- }
5027
- }
5028
- }
5029
- _infer_types_fn_seg = seg. infer_types ;
5030
- }
5031
-
5032
- let defs = self . tcx . generics_of ( def. def_id ( ) ) ;
5006
+ let def_id = def. def_id ( ) ;
5007
+ let defs = self . tcx . generics_of ( def_id) ;
5033
5008
let count = defs. count ( ) ;
5034
5009
let mut substs = if count <= 8 {
5035
5010
AccumulateVec :: Array ( ArrayVec :: new ( ) )
5036
5011
} else {
5037
5012
AccumulateVec :: Heap ( Vec :: with_capacity ( count) )
5038
5013
} ;
5039
- let mut stack = vec ! [ def. def_id( ) ] ;
5040
5014
let mut parent_defs = defs;
5015
+ let mut stack = vec ! [ ( def_id, parent_defs) ] ;
5041
5016
while let Some ( def_id) = parent_defs. parent {
5042
5017
parent_defs = self . tcx . generics_of ( def_id) ;
5043
- stack. push ( def_id) ;
5018
+ stack. push ( ( def_id, parent_defs ) ) ;
5044
5019
}
5045
- while let Some ( def_id) = stack. pop ( ) {
5046
- let defs = self . tcx . generics_of ( def_id) ;
5020
+ while let Some ( ( def_id, defs) ) = stack. pop ( ) {
5047
5021
Substs :: fill_single ( & mut substs, defs, & mut |param : & ty:: GenericParamDef , substs| {
5048
- let lifetimes = if ( param. index as usize ) < fn_start {
5022
+ if param. index == 0 && has_self {
5049
5023
if let GenericParamDefKind :: Type { .. } = param. kind {
5050
5024
// Handle Self first, so we can adjust the index to match the AST.
5051
- if has_self && param. index == 0 {
5052
- return opt_self_ty. map ( |ty| ty. into ( ) ) . unwrap_or_else ( || {
5053
- self . var_for_def ( span, param)
5054
- } ) ;
5055
- }
5025
+ return opt_self_ty. map ( |ty| ty. into ( ) ) . unwrap_or_else ( || {
5026
+ self . var_for_def ( span, param)
5027
+ } ) ;
5056
5028
}
5057
- & lifetimes_type_seg
5058
- } else {
5059
- & lifetimes_fn_seg
5060
- } ;
5061
-
5062
- let mut pi = param. index as usize - has_self as usize ;
5029
+ }
5063
5030
5064
- let ( _segment, infer_types) = if let Some ( & PathSeg ( _, ind) ) = path_segs. iter ( ) . find ( |& PathSeg ( di, _) | * di == def_id) {
5065
- let seg = & segments[ ind] ;
5066
- if lifetimes. len ( ) == 0 {
5067
- pi -= defs. own_counts ( ) . lifetimes ;
5068
- }
5031
+ let infer_types = if let Some ( & PathSeg ( _, index) ) = path_segs
5032
+ . iter ( )
5033
+ . find ( |& PathSeg ( di, _) | * di == def_id) {
5069
5034
5070
- if let Some ( ref data) = seg. args {
5071
- if let Some ( arg) = data. args . get ( pi) {
5035
+ if let Some ( ref data) = segments[ index] . args {
5036
+ let lifetime_offset = if infer_lifetimes[ & index] {
5037
+ defs. own_counts ( ) . lifetimes
5038
+ } else {
5039
+ 0
5040
+ } ;
5041
+ let param_idx = param. index as usize - has_self as usize - lifetime_offset;
5042
+ if let Some ( arg) = data. args . get ( param_idx) {
5072
5043
return match param. kind {
5073
- GenericParamDefKind :: Lifetime => {
5074
- let lt = match arg {
5075
- GenericArg :: Lifetime ( lt) => lt,
5076
- _ => bug ! ( "should be a lifetime" ) ,
5077
- } ;
5078
- AstConv :: ast_region_to_region ( self , lt, Some ( param) ) . into ( )
5044
+ GenericParamDefKind :: Lifetime => match arg {
5045
+ GenericArg :: Lifetime ( lt) => {
5046
+ AstConv :: ast_region_to_region ( self , lt, Some ( param) ) . into ( )
5047
+ }
5048
+ _ => bug ! ( "expected a lifetime arg" ) ,
5079
5049
}
5080
- GenericParamDefKind :: Type { .. } => {
5050
+ GenericParamDefKind :: Type { .. } => match arg {
5081
5051
// A provided type parameter.
5082
- let ty = match arg {
5083
- GenericArg :: Type ( ty) => ty,
5084
- _ => bug ! ( "should be a type" ) ,
5085
- } ;
5086
- self . to_ty ( ty) . into ( )
5052
+ GenericArg :: Type ( ty) => self . to_ty ( ty) . into ( ) ,
5053
+ _ => bug ! ( "expected a type arg" ) ,
5087
5054
}
5088
- } ;
5055
+ }
5089
5056
}
5090
5057
}
5091
5058
5092
- ( Some ( ( seg , defs ) ) , seg . infer_types )
5059
+ segments [ index ] . infer_types
5093
5060
} else {
5094
- ( None , true )
5061
+ true
5095
5062
} ;
5096
5063
5097
5064
match param. kind {
0 commit comments