@@ -84,9 +84,10 @@ pub use self::compare_method::{compare_impl_method, compare_const_impl};
84
84
use self :: method:: MethodCallee ;
85
85
use self :: TupleArgumentsFlag :: * ;
86
86
87
- use astconv:: AstConv ;
87
+ use astconv:: { AstConv , GenericArgMismatchErrorCode } ;
88
88
use hir:: GenericArg ;
89
89
use hir:: def:: Def ;
90
+ use hir:: HirVec ;
90
91
use hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE } ;
91
92
use std:: slice;
92
93
use namespace:: Namespace ;
@@ -4937,16 +4938,30 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
4937
4938
// to add defaults. If the user provided *too many* types, that's
4938
4939
// a problem.
4939
4940
4940
- let mut supress_errors = FxHashMap ( ) ;
4941
+ let mut suppress_errors = FxHashMap ( ) ;
4941
4942
for & PathSeg ( def_id, index) in & path_segs {
4942
4943
let seg = & segments[ index] ;
4943
4944
let generics = self . tcx . generics_of ( def_id) ;
4944
4945
// `impl Trait` is treated as a normal generic parameter internally,
4945
4946
// but we don't allow users to specify the parameter's value
4946
4947
// explicitly, so we have to do some error-checking here.
4947
- let supress_mismatch = self . check_impl_trait ( span, seg, & generics) ;
4948
- supress_errors. insert ( index,
4949
- self . check_generic_arg_count ( span, seg, & generics, false , supress_mismatch) ) ;
4948
+ let suppress_mismatch = self . check_impl_trait ( span, seg, & generics) ;
4949
+ suppress_errors. insert ( index, AstConv :: check_generic_arg_count (
4950
+ self . tcx ,
4951
+ span,
4952
+ & generics,
4953
+ & seg. args . clone ( ) . unwrap_or_else ( || P ( hir:: GenericArgs {
4954
+ args : HirVec :: new ( ) , bindings : HirVec :: new ( ) , parenthesized : false ,
4955
+ } ) ) ,
4956
+ false , // `is_declaration`
4957
+ false , // `is_method_call`
4958
+ generics. parent . is_none ( ) && generics. has_self ,
4959
+ seg. infer_types || suppress_mismatch,
4960
+ GenericArgMismatchErrorCode {
4961
+ lifetimes : ( "E0090" , "E0088" ) , // FIXME: E0090 and E0088 should be unified.
4962
+ types : ( "E0089" , "E0087" ) , // FIXME: E0089 and E0087 should be unified.
4963
+ } ,
4964
+ ) ) ;
4950
4965
}
4951
4966
4952
4967
let has_self = path_segs. last ( ) . map ( |PathSeg ( def_id, _) | {
@@ -4968,7 +4983,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
4968
4983
} ) {
4969
4984
// If we've encountered an `impl Trait`-related error, we're just
4970
4985
// going to infer the arguments for better error messages.
4971
- if !supress_errors [ & index] {
4986
+ if !suppress_errors [ & index] {
4972
4987
// Check whether the user has provided generic arguments.
4973
4988
if let Some ( ref data) = segments[ index] . args {
4974
4989
return ( Some ( data) , segments[ index] . infer_types ) ;
@@ -5097,128 +5112,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5097
5112
directly, not through a function pointer") ;
5098
5113
}
5099
5114
5100
- /// Report errors if the provided parameters are too few or too many.
5101
- fn check_generic_arg_count ( & self ,
5102
- span : Span ,
5103
- segment : & hir:: PathSegment ,
5104
- generics : & ty:: Generics ,
5105
- is_method_call : bool ,
5106
- supress_mismatch_error : bool )
5107
- -> bool {
5108
- let mut supress_errors = false ;
5109
- let ( mut lifetimes, mut types) = ( vec ! [ ] , vec ! [ ] ) ;
5110
- let infer_types = segment. infer_types ;
5111
- let mut bindings = vec ! [ ] ;
5112
- if let Some ( ref data) = segment. args {
5113
- data. args . iter ( ) . for_each ( |arg| match arg {
5114
- GenericArg :: Lifetime ( lt) => lifetimes. push ( lt. clone ( ) ) ,
5115
- GenericArg :: Type ( ty) => types. push ( ty. clone ( ) ) ,
5116
- } ) ;
5117
- bindings = data. bindings . clone ( ) . to_vec ( ) ;
5118
- }
5119
-
5120
- struct ParamRange {
5121
- required : usize ,
5122
- accepted : usize
5123
- } ;
5124
-
5125
- let mut lt_accepted = 0 ;
5126
- let mut ty_params = ParamRange { required : 0 , accepted : 0 } ;
5127
- for param in & generics. params {
5128
- match param. kind {
5129
- GenericParamDefKind :: Lifetime => lt_accepted += 1 ,
5130
- GenericParamDefKind :: Type { has_default, .. } => {
5131
- ty_params. accepted += 1 ;
5132
- if !has_default {
5133
- ty_params. required += 1 ;
5134
- }
5135
- }
5136
- } ;
5137
- }
5138
- if generics. parent . is_none ( ) && generics. has_self {
5139
- ty_params. required -= 1 ;
5140
- ty_params. accepted -= 1 ;
5141
- }
5142
- let ty_accepted = ty_params. accepted ;
5143
- let ty_required = ty_params. required ;
5144
-
5145
- let count_ty_params = |n| format ! ( "{} type parameter{}" , n, if n == 1 { "" } else { "s" } ) ;
5146
- let expected_text = count_ty_params ( ty_accepted) ;
5147
- let actual_text = count_ty_params ( types. len ( ) ) ;
5148
- if let Some ( ( mut err, span) ) = if types. len ( ) > ty_accepted {
5149
- // To prevent derived errors to accumulate due to extra
5150
- // type parameters, we force instantiate_value_path to
5151
- // use inference variables instead of the provided types.
5152
- supress_errors = true ;
5153
- let span = types[ ty_accepted] . span ;
5154
- Some ( ( struct_span_err ! ( self . tcx. sess, span, E0087 ,
5155
- "too many type parameters provided: \
5156
- expected at most {}, found {}",
5157
- expected_text, actual_text) , span) )
5158
- } else if types. len ( ) < ty_required && !infer_types && !supress_mismatch_error {
5159
- Some ( ( struct_span_err ! ( self . tcx. sess, span, E0089 ,
5160
- "too few type parameters provided: \
5161
- expected {}, found {}",
5162
- expected_text, actual_text) , span) )
5163
- } else {
5164
- None
5165
- } {
5166
- self . set_tainted_by_errors ( ) ; // #53251
5167
- err. span_label ( span, format ! ( "expected {}" , expected_text) ) . emit ( ) ;
5168
- }
5169
-
5170
- if !bindings. is_empty ( ) {
5171
- AstConv :: prohibit_assoc_ty_binding ( self . tcx , bindings[ 0 ] . span ) ;
5172
- }
5173
-
5174
- let infer_lifetimes = lifetimes. len ( ) == 0 ;
5175
- // Prohibit explicit lifetime arguments if late bound lifetime parameters are present.
5176
- let has_late_bound_lifetime_defs = generics. has_late_bound_regions ;
5177
- if let ( Some ( span_late) , false ) = ( has_late_bound_lifetime_defs, lifetimes. is_empty ( ) ) {
5178
- // Report this as a lint only if no error was reported previously.
5179
- let primary_msg = "cannot specify lifetime arguments explicitly \
5180
- if late bound lifetime parameters are present";
5181
- let note_msg = "the late bound lifetime parameter is introduced here" ;
5182
- if !is_method_call && ( lifetimes. len ( ) > lt_accepted ||
5183
- lifetimes. len ( ) < lt_accepted && !infer_lifetimes) {
5184
- supress_errors = true ;
5185
- let mut err = self . tcx . sess . struct_span_err ( lifetimes[ 0 ] . span , primary_msg) ;
5186
- err. span_note ( span_late, note_msg) ;
5187
- err. emit ( ) ;
5188
- } else {
5189
- let mut multispan = MultiSpan :: from_span ( lifetimes[ 0 ] . span ) ;
5190
- multispan. push_span_label ( span_late, note_msg. to_string ( ) ) ;
5191
- self . tcx . lint_node ( lint:: builtin:: LATE_BOUND_LIFETIME_ARGUMENTS ,
5192
- lifetimes[ 0 ] . id , multispan, primary_msg) ;
5193
- }
5194
- return supress_errors;
5195
- }
5196
-
5197
- let count_lifetime_params = |n| {
5198
- format ! ( "{} lifetime parameter{}" , n, if n == 1 { "" } else { "s" } )
5199
- } ;
5200
- let expected_text = count_lifetime_params ( lt_accepted) ;
5201
- let actual_text = count_lifetime_params ( lifetimes. len ( ) ) ;
5202
- if let Some ( ( mut err, span) ) = if lifetimes. len ( ) > lt_accepted {
5203
- let span = lifetimes[ lt_accepted] . span ;
5204
- Some ( ( struct_span_err ! ( self . tcx. sess, span, E0088 ,
5205
- "too many lifetime parameters provided: \
5206
- expected at most {}, found {}",
5207
- expected_text, actual_text) , span) )
5208
- } else if lifetimes. len ( ) < lt_accepted && !infer_lifetimes {
5209
- Some ( ( struct_span_err ! ( self . tcx. sess, span, E0090 ,
5210
- "too few lifetime parameters provided: \
5211
- expected {}, found {}",
5212
- expected_text, actual_text) , span) )
5213
- } else {
5214
- None
5215
- } {
5216
- err. span_label ( span, format ! ( "expected {}" , expected_text) ) . emit ( ) ;
5217
- }
5218
-
5219
- supress_errors
5220
- }
5221
-
5222
5115
/// Report error if there is an explicit type parameter when using `impl Trait`.
5223
5116
fn check_impl_trait ( & self ,
5224
5117
span : Span ,
0 commit comments