@@ -95,7 +95,7 @@ use rustc::infer::anon_types::AnonTypeDecl;
95
95
use rustc:: infer:: type_variable:: { TypeVariableOrigin } ;
96
96
use rustc:: middle:: region;
97
97
use rustc:: mir:: interpret:: { GlobalId } ;
98
- use rustc:: ty:: subst:: { UnpackedKind , Subst , Substs } ;
98
+ use rustc:: ty:: subst:: { Kind , UnpackedKind , Subst , Substs } ;
99
99
use rustc:: traits:: { self , ObligationCause , ObligationCauseCode , TraitEngine } ;
100
100
use rustc:: ty:: { self , Ty , TyCtxt , GenericParamDefKind , Visibility , ToPredicate , RegionKind } ;
101
101
use rustc:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability } ;
@@ -4967,7 +4967,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
4967
4967
let def_id = def. def_id ( ) ;
4968
4968
let mut parent_defs = self . tcx . generics_of ( def_id) ;
4969
4969
let count = parent_defs. count ( ) ;
4970
- let mut substs = if count <= 8 {
4970
+ let mut substs: AccumulateVec < [ Kind < ' tcx > ; 8 ] > = if count <= 8 {
4971
4971
AccumulateVec :: Array ( ArrayVec :: new ( ) )
4972
4972
} else {
4973
4973
AccumulateVec :: Heap ( Vec :: with_capacity ( count) )
@@ -4977,74 +4977,103 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
4977
4977
parent_defs = self . tcx . generics_of ( def_id) ;
4978
4978
stack. push ( ( def_id, parent_defs) ) ;
4979
4979
}
4980
+ macro_rules! push_to_substs {
4981
+ ( $kind: expr) => {
4982
+ let k = $kind;
4983
+ match substs {
4984
+ AccumulateVec :: Array ( ref mut arr) => arr. push( k) ,
4985
+ AccumulateVec :: Heap ( ref mut vec) => vec. push( k) ,
4986
+ }
4987
+ }
4988
+ } ;
4980
4989
while let Some ( ( def_id, defs) ) = stack. pop ( ) {
4981
- Substs :: fill_single ( & mut substs, defs, & mut |param : & ty:: GenericParamDef , substs| {
4982
- if param. index == 0 && has_self {
4983
- if let GenericParamDefKind :: Type { .. } = param. kind {
4984
- // Handle `Self` first, so we can adjust the index to match the AST.
4985
- return opt_self_ty. map ( |ty| ty. into ( ) ) . unwrap_or_else ( || {
4986
- self . var_for_def ( span, param)
4987
- } ) ;
4990
+ let mut params = defs. params . iter ( ) . peekable ( ) ;
4991
+ let mut remove_self = false ;
4992
+ if has_self {
4993
+ if let Some ( param) = params. peek ( ) {
4994
+ if param. index == 0 {
4995
+ if let GenericParamDefKind :: Type { .. } = param. kind {
4996
+ // Handle `Self` first, so we can adjust the index to match the AST.
4997
+ push_to_substs ! ( opt_self_ty. map( |ty| ty. into( ) ) . unwrap_or_else( || {
4998
+ self . var_for_def( span, param)
4999
+ } ) ) ;
5000
+ remove_self = true ;
5001
+ }
4988
5002
}
4989
5003
}
5004
+ }
5005
+ if remove_self {
5006
+ params. next ( ) ;
5007
+ }
4990
5008
4991
- let infer_types = if let Some ( & PathSeg ( _, index) ) = path_segs
4992
- . iter ( )
4993
- . find ( |& PathSeg ( did, _) | * did == def_id) {
4994
-
4995
- if supress_errors[ & index] {
4996
- true
4997
- } else {
4998
- if let Some ( ref data) = segments[ index] . args {
4999
- let self_offset = ( defs. parent_count == 0 && has_self) as usize ;
5000
- let param_idx =
5001
- ( param. index as usize - defs. parent_count - self_offset)
5002
- . saturating_sub ( infer_lifetimes[ & index] ) ;
5003
- if let Some ( arg) = data. args . get ( param_idx) {
5009
+ let mut infer_types = true ;
5010
+ if let Some ( & PathSeg ( _, index) ) = path_segs
5011
+ . iter ( )
5012
+ . find ( |& PathSeg ( did, _) | * did == def_id) {
5013
+ if !supress_errors[ & index] {
5014
+ infer_types = segments[ index] . infer_types ;
5015
+ if let Some ( ref data) = segments[ index] . args {
5016
+ let args = & data. args ;
5017
+ ' args: for arg in args {
5018
+ while let Some ( param) = params. next ( ) {
5004
5019
match param. kind {
5005
5020
GenericParamDefKind :: Lifetime => match arg {
5006
5021
GenericArg :: Lifetime ( lt) => {
5007
- return AstConv :: ast_region_to_region ( self ,
5008
- lt, Some ( param) ) . into ( ) ;
5022
+ push_to_substs ! ( AstConv :: ast_region_to_region( self ,
5023
+ lt, Some ( param) ) . into( ) ) ;
5024
+ continue ' args;
5025
+ }
5026
+ GenericArg :: Type ( _) => {
5027
+ // We're inferring a lifetime.
5028
+ push_to_substs ! (
5029
+ self . re_infer( span, Some ( param) ) . unwrap( ) . into( ) ) ;
5009
5030
}
5010
- _ => { }
5011
5031
}
5012
5032
GenericParamDefKind :: Type { .. } => match arg {
5013
- GenericArg :: Type ( ty) => return self . to_ty ( ty) . into ( ) ,
5014
- _ => { }
5033
+ GenericArg :: Type ( ty) => {
5034
+ push_to_substs ! ( self . to_ty( ty) . into( ) ) ;
5035
+ continue ' args;
5036
+ }
5037
+ GenericArg :: Lifetime ( _) => {
5038
+ self . tcx . sess . delay_span_bug ( span,
5039
+ "found a GenericArg::Lifetime where a \
5040
+ GenericArg::Type was expected") ;
5041
+ }
5015
5042
}
5016
5043
}
5017
5044
}
5045
+ // If we get to this point, we have a GenericArg that is not matched
5046
+ // by a GenericParamDef: i.e. the user supplied too many generic args.
5047
+ self . tcx . sess . delay_span_bug ( span,
5048
+ "GenericArg did not have matching GenericParamDef" ) ;
5018
5049
}
5019
-
5020
- segments[ index] . infer_types
5021
5050
}
5022
- } else {
5023
- true
5024
- } ;
5051
+ }
5052
+ }
5025
5053
5054
+ while let Some ( param) = params. next ( ) {
5026
5055
match param. kind {
5027
5056
GenericParamDefKind :: Lifetime => {
5028
- self . re_infer ( span, Some ( param) ) . unwrap ( ) . into ( )
5057
+ push_to_substs ! ( self . re_infer( span, Some ( param) ) . unwrap( ) . into( ) ) ;
5029
5058
}
5030
5059
GenericParamDefKind :: Type { has_default, .. } => {
5031
5060
if !infer_types && has_default {
5032
5061
// No type parameter provided, but a default exists.
5033
5062
let default = self . tcx . type_of ( param. def_id ) ;
5034
- self . normalize_ty (
5063
+ push_to_substs ! ( self . normalize_ty(
5035
5064
span,
5036
- default. subst_spanned ( self . tcx , substs, Some ( span) )
5037
- ) . into ( )
5065
+ default . subst_spanned( self . tcx, & substs, Some ( span) )
5066
+ ) . into( ) ) ;
5038
5067
} else {
5039
5068
// No type parameters were provided, we can infer all.
5040
5069
// This can also be reached in some error cases:
5041
5070
// We prefer to use inference variables instead of
5042
5071
// TyError to let type inference recover somewhat.
5043
- self . var_for_def ( span, param)
5072
+ push_to_substs ! ( self . var_for_def( span, param) ) ;
5044
5073
}
5045
5074
}
5046
5075
}
5047
- } ) ;
5076
+ }
5048
5077
}
5049
5078
let substs = self . tcx . intern_substs ( & substs) ;
5050
5079
0 commit comments