@@ -94,11 +94,12 @@ struct ConvertedBinding<'tcx> {
9494
9595#[ derive( PartialEq ) ]
9696enum GenericArgPosition {
97- Datatype ,
98- Function ,
99- Method ,
97+ Type ,
98+ Value , // e.g. functions
99+ MethodCall ,
100100}
101101
102+ // FIXME(#53525): these error codes should all be unified.
102103struct GenericArgMismatchErrorCode {
103104 lifetimes : ( & ' static str , & ' static str ) ,
104105 types : ( & ' static str , & ' static str ) ,
@@ -255,9 +256,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
255256 & empty_args
256257 } ,
257258 if is_method_call {
258- GenericArgPosition :: Method
259+ GenericArgPosition :: MethodCall
259260 } else {
260- GenericArgPosition :: Function
261+ GenericArgPosition :: Value
261262 } ,
262263 def. parent . is_none ( ) && def. has_self , // `has_self`
263264 seg. infer_types || suppress_mismatch, // `infer_types`
@@ -285,7 +286,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
285286 // arguments in order to validate them with respect to the generic parameters.
286287 let param_counts = def. own_counts ( ) ;
287288 let arg_counts = args. own_counts ( ) ;
288- let infer_lifetimes = position != GenericArgPosition :: Datatype && arg_counts. lifetimes == 0 ;
289+ let infer_lifetimes = position != GenericArgPosition :: Type && arg_counts. lifetimes == 0 ;
289290
290291 let mut defaults: ty:: GenericParamCount = Default :: default ( ) ;
291292 for param in & def. params {
@@ -297,7 +298,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
297298 } ;
298299 }
299300
300- if position != GenericArgPosition :: Datatype && !args. bindings . is_empty ( ) {
301+ if position != GenericArgPosition :: Type && !args. bindings . is_empty ( ) {
301302 AstConv :: prohibit_assoc_ty_binding ( tcx, args. bindings [ 0 ] . span ) ;
302303 }
303304
@@ -308,7 +309,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
308309 if late bound lifetime parameters are present";
309310 let note = "the late bound lifetime parameter is introduced here" ;
310311 let span = args. args [ 0 ] . span ( ) ;
311- if position == GenericArgPosition :: Function
312+ if position == GenericArgPosition :: Value
312313 && arg_counts. lifetimes != param_counts. lifetimes {
313314 let mut err = tcx. sess . struct_span_err ( span, msg) ;
314315 err. span_note ( span_late, note) ;
@@ -328,7 +329,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
328329 kind,
329330 required,
330331 permitted,
331- provided| {
332+ provided,
333+ offset| {
332334 // We enforce the following: `required` <= `provided` <= `permitted`.
333335 // For kinds without defaults (i.e. lifetimes), `required == permitted`.
334336 // For other kinds (i.e. types), `permitted` may be greater than `required`.
@@ -348,8 +350,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
348350 ( required, "" )
349351 } ;
350352
353+ let mut span = span;
351354 let label = if required == permitted && provided > permitted {
352355 let diff = provided - permitted;
356+ if diff == 1 {
357+ // In the case when the user has provided too many arguments,
358+ // we want to point to the first unexpected argument.
359+ let first_superfluous_arg: & GenericArg = & args. args [ offset + permitted] ;
360+ span = first_superfluous_arg. span ( ) ;
361+ }
353362 format ! (
354363 "{}unexpected {} argument{}" ,
355364 if diff != 1 { format!( "{} " , diff) } else { String :: new( ) } ,
@@ -394,6 +403,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
394403 param_counts. lifetimes ,
395404 param_counts. lifetimes ,
396405 arg_counts. lifetimes ,
406+ 0 ,
397407 ) ;
398408 }
399409 if !infer_types
@@ -404,6 +414,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
404414 param_counts. types - defaults. types - has_self as usize ,
405415 param_counts. types - has_self as usize ,
406416 arg_counts. types ,
417+ arg_counts. lifetimes ,
407418 )
408419 } else {
409420 false
@@ -491,59 +502,50 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
491502 // provided, matching them with the generic parameters we expect.
492503 // Mismatches can occur as a result of elided lifetimes, or for malformed
493504 // input. We try to handle both sensibly.
494- let mut progress_arg = true ;
495505 match ( args. peek ( ) , params. peek ( ) ) {
496506 ( Some ( & arg) , Some ( & param) ) => {
497507 match ( arg, & param. kind ) {
498- ( GenericArg :: Lifetime ( _) , GenericParamDefKind :: Lifetime ) => {
508+ ( GenericArg :: Lifetime ( _) , GenericParamDefKind :: Lifetime )
509+ | ( GenericArg :: Type ( _) , GenericParamDefKind :: Type { .. } ) => {
499510 push_kind ( & mut substs, provided_kind ( param, arg) ) ;
511+ args. next ( ) ;
500512 params. next ( ) ;
501513 }
502514 ( GenericArg :: Lifetime ( _) , GenericParamDefKind :: Type { .. } ) => {
503515 // We expected a type argument, but got a lifetime
504516 // argument. This is an error, but we need to handle it
505517 // gracefully so we can report sensible errors. In this
506- // case, we're simply going to infer the remaining
507- // arguments.
508- args. by_ref ( ) . for_each ( drop) ; // Exhaust the iterator.
509- }
510- ( GenericArg :: Type ( _) , GenericParamDefKind :: Type { .. } ) => {
511- push_kind ( & mut substs, provided_kind ( param, arg) ) ;
512- params. next ( ) ;
518+ // case, we're simply going to infer this argument.
519+ args. next ( ) ;
513520 }
514521 ( GenericArg :: Type ( _) , GenericParamDefKind :: Lifetime ) => {
515522 // We expected a lifetime argument, but got a type
516523 // argument. That means we're inferring the lifetimes.
517524 push_kind ( & mut substs, inferred_kind ( None , param, infer_types) ) ;
518525 params. next ( ) ;
519- progress_arg = false ;
520526 }
521527 }
522528 }
523529 ( Some ( _) , None ) => {
524530 // We should never be able to reach this point with well-formed input.
525531 // Getting to this point means the user supplied more arguments than
526532 // there are parameters.
533+ args. next ( ) ;
527534 }
528535 ( None , Some ( & param) ) => {
529536 // If there are fewer arguments than parameters, it means
530537 // we're inferring the remaining arguments.
531538 match param. kind {
532- GenericParamDefKind :: Lifetime => {
533- push_kind ( & mut substs, inferred_kind ( None , param, infer_types) ) ;
534- }
535- GenericParamDefKind :: Type { .. } => {
539+ GenericParamDefKind :: Lifetime | GenericParamDefKind :: Type { .. } => {
536540 let kind = inferred_kind ( Some ( & substs) , param, infer_types) ;
537541 push_kind ( & mut substs, kind) ;
538542 }
539543 }
544+ args. next ( ) ;
540545 params. next ( ) ;
541546 }
542547 ( None , None ) => break ,
543548 }
544- if progress_arg {
545- args. next ( ) ;
546- }
547549 }
548550 }
549551
@@ -582,12 +584,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
582584 span,
583585 & generic_params,
584586 & generic_args,
585- GenericArgPosition :: Datatype ,
587+ GenericArgPosition :: Type ,
586588 has_self,
587589 infer_types,
588590 GenericArgMismatchErrorCode {
589591 lifetimes : ( "E0107" , "E0107" ) ,
590- types : ( "E0243" , "E0244" ) , // FIXME: E0243 and E0244 should be unified.
592+ types : ( "E0243" , "E0244" ) ,
591593 } ,
592594 ) ;
593595
@@ -616,17 +618,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
616618 |_| ( Some ( generic_args) , infer_types) ,
617619 // Provide substitutions for parameters for which (valid) arguments have been provided.
618620 |param, arg| {
619- match param. kind {
620- GenericParamDefKind :: Lifetime => match arg {
621- GenericArg :: Lifetime ( lt) => {
622- self . ast_region_to_region ( & lt, Some ( param) ) . into ( )
623- }
624- _ => unreachable ! ( ) ,
621+ match ( & param. kind , arg) {
622+ ( GenericParamDefKind :: Lifetime , GenericArg :: Lifetime ( lt) ) => {
623+ self . ast_region_to_region ( & lt, Some ( param) ) . into ( )
625624 }
626- GenericParamDefKind :: Type { .. } => match arg {
627- GenericArg :: Type ( ty) => self . ast_ty_to_ty ( & ty) . into ( ) ,
628- _ => unreachable ! ( ) ,
625+ ( GenericParamDefKind :: Type { .. } , GenericArg :: Type ( ty) ) => {
626+ self . ast_ty_to_ty ( & ty) . into ( )
629627 }
628+ _ => unreachable ! ( ) ,
630629 }
631630 } ,
632631 // Provide substitutions for parameters for which arguments are inferred.
0 commit comments