@@ -94,11 +94,12 @@ struct ConvertedBinding<'tcx> {
94
94
95
95
#[ derive( PartialEq ) ]
96
96
enum GenericArgPosition {
97
- Datatype ,
98
- Function ,
99
- Method ,
97
+ Type ,
98
+ Value , // e.g. functions
99
+ MethodCall ,
100
100
}
101
101
102
+ // FIXME(#53525): these error codes should all be unified.
102
103
struct GenericArgMismatchErrorCode {
103
104
lifetimes : ( & ' static str , & ' static str ) ,
104
105
types : ( & ' static str , & ' static str ) ,
@@ -255,9 +256,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
255
256
& empty_args
256
257
} ,
257
258
if is_method_call {
258
- GenericArgPosition :: Method
259
+ GenericArgPosition :: MethodCall
259
260
} else {
260
- GenericArgPosition :: Function
261
+ GenericArgPosition :: Value
261
262
} ,
262
263
def. parent . is_none ( ) && def. has_self , // `has_self`
263
264
seg. infer_types || suppress_mismatch, // `infer_types`
@@ -285,7 +286,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
285
286
// arguments in order to validate them with respect to the generic parameters.
286
287
let param_counts = def. own_counts ( ) ;
287
288
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 ;
289
290
290
291
let mut defaults: ty:: GenericParamCount = Default :: default ( ) ;
291
292
for param in & def. params {
@@ -297,7 +298,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
297
298
} ;
298
299
}
299
300
300
- if position != GenericArgPosition :: Datatype && !args. bindings . is_empty ( ) {
301
+ if position != GenericArgPosition :: Type && !args. bindings . is_empty ( ) {
301
302
AstConv :: prohibit_assoc_ty_binding ( tcx, args. bindings [ 0 ] . span ) ;
302
303
}
303
304
@@ -308,7 +309,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
308
309
if late bound lifetime parameters are present";
309
310
let note = "the late bound lifetime parameter is introduced here" ;
310
311
let span = args. args [ 0 ] . span ( ) ;
311
- if position == GenericArgPosition :: Function
312
+ if position == GenericArgPosition :: Value
312
313
&& arg_counts. lifetimes != param_counts. lifetimes {
313
314
let mut err = tcx. sess . struct_span_err ( span, msg) ;
314
315
err. span_note ( span_late, note) ;
@@ -328,7 +329,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
328
329
kind,
329
330
required,
330
331
permitted,
331
- provided| {
332
+ provided,
333
+ offset| {
332
334
// We enforce the following: `required` <= `provided` <= `permitted`.
333
335
// For kinds without defaults (i.e. lifetimes), `required == permitted`.
334
336
// 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 {
348
350
( required, "" )
349
351
} ;
350
352
353
+ let mut span = span;
351
354
let label = if required == permitted && provided > permitted {
352
355
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
+ }
353
362
format ! (
354
363
"{}unexpected {} argument{}" ,
355
364
if diff != 1 { format!( "{} " , diff) } else { String :: new( ) } ,
@@ -394,6 +403,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
394
403
param_counts. lifetimes ,
395
404
param_counts. lifetimes ,
396
405
arg_counts. lifetimes ,
406
+ 0 ,
397
407
) ;
398
408
}
399
409
if !infer_types
@@ -404,6 +414,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
404
414
param_counts. types - defaults. types - has_self as usize ,
405
415
param_counts. types - has_self as usize ,
406
416
arg_counts. types ,
417
+ arg_counts. lifetimes ,
407
418
)
408
419
} else {
409
420
false
@@ -491,59 +502,50 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
491
502
// provided, matching them with the generic parameters we expect.
492
503
// Mismatches can occur as a result of elided lifetimes, or for malformed
493
504
// input. We try to handle both sensibly.
494
- let mut progress_arg = true ;
495
505
match ( args. peek ( ) , params. peek ( ) ) {
496
506
( Some ( & arg) , Some ( & param) ) => {
497
507
match ( arg, & param. kind ) {
498
- ( GenericArg :: Lifetime ( _) , GenericParamDefKind :: Lifetime ) => {
508
+ ( GenericArg :: Lifetime ( _) , GenericParamDefKind :: Lifetime )
509
+ | ( GenericArg :: Type ( _) , GenericParamDefKind :: Type { .. } ) => {
499
510
push_kind ( & mut substs, provided_kind ( param, arg) ) ;
511
+ args. next ( ) ;
500
512
params. next ( ) ;
501
513
}
502
514
( GenericArg :: Lifetime ( _) , GenericParamDefKind :: Type { .. } ) => {
503
515
// We expected a type argument, but got a lifetime
504
516
// argument. This is an error, but we need to handle it
505
517
// 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 ( ) ;
513
520
}
514
521
( GenericArg :: Type ( _) , GenericParamDefKind :: Lifetime ) => {
515
522
// We expected a lifetime argument, but got a type
516
523
// argument. That means we're inferring the lifetimes.
517
524
push_kind ( & mut substs, inferred_kind ( None , param, infer_types) ) ;
518
525
params. next ( ) ;
519
- progress_arg = false ;
520
526
}
521
527
}
522
528
}
523
529
( Some ( _) , None ) => {
524
530
// We should never be able to reach this point with well-formed input.
525
531
// Getting to this point means the user supplied more arguments than
526
532
// there are parameters.
533
+ args. next ( ) ;
527
534
}
528
535
( None , Some ( & param) ) => {
529
536
// If there are fewer arguments than parameters, it means
530
537
// we're inferring the remaining arguments.
531
538
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 { .. } => {
536
540
let kind = inferred_kind ( Some ( & substs) , param, infer_types) ;
537
541
push_kind ( & mut substs, kind) ;
538
542
}
539
543
}
544
+ args. next ( ) ;
540
545
params. next ( ) ;
541
546
}
542
547
( None , None ) => break ,
543
548
}
544
- if progress_arg {
545
- args. next ( ) ;
546
- }
547
549
}
548
550
}
549
551
@@ -582,12 +584,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
582
584
span,
583
585
& generic_params,
584
586
& generic_args,
585
- GenericArgPosition :: Datatype ,
587
+ GenericArgPosition :: Type ,
586
588
has_self,
587
589
infer_types,
588
590
GenericArgMismatchErrorCode {
589
591
lifetimes : ( "E0107" , "E0107" ) ,
590
- types : ( "E0243" , "E0244" ) , // FIXME: E0243 and E0244 should be unified.
592
+ types : ( "E0243" , "E0244" ) ,
591
593
} ,
592
594
) ;
593
595
@@ -616,17 +618,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
616
618
|_| ( Some ( generic_args) , infer_types) ,
617
619
// Provide substitutions for parameters for which (valid) arguments have been provided.
618
620
|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 ( )
625
624
}
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 ( )
629
627
}
628
+ _ => unreachable ! ( ) ,
630
629
}
631
630
} ,
632
631
// Provide substitutions for parameters for which arguments are inferred.
0 commit comments