@@ -287,7 +287,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
287
287
position : GenericArgPosition ,
288
288
has_self : bool ,
289
289
infer_args : bool ,
290
- ) -> ( bool , Option < Vec < Span > > ) {
290
+ ) -> ( bool , Vec < Span > ) {
291
291
// At this stage we are guaranteed that the generic arguments are in the correct order, e.g.
292
292
// that lifetimes will proceed types. So it suffices to check the number of each generic
293
293
// arguments in order to validate them with respect to the generic parameters.
@@ -341,104 +341,110 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
341
341
}
342
342
}
343
343
344
- let check_kind_count = |kind, required, permitted, provided, offset| {
345
- debug ! (
346
- "check_kind_count: kind: {} required: {} permitted: {} provided: {} offset: {}" ,
347
- kind, required, permitted, provided, offset
348
- ) ;
349
- // We enforce the following: `required` <= `provided` <= `permitted`.
350
- // For kinds without defaults (e.g.., lifetimes), `required == permitted`.
351
- // For other kinds (i.e., types), `permitted` may be greater than `required`.
352
- if required <= provided && provided <= permitted {
353
- return ( reported_late_bound_region_err. unwrap_or ( false ) , None ) ;
354
- }
355
-
356
- // Unfortunately lifetime and type parameter mismatches are typically styled
357
- // differently in diagnostics, which means we have a few cases to consider here.
358
- let ( bound, quantifier) = if required != permitted {
359
- if provided < required {
360
- ( required, "at least " )
361
- } else {
362
- // provided > permitted
363
- ( permitted, "at most " )
344
+ let check_kind_count =
345
+ |kind, required, permitted, provided, offset, unexpected_spans : & mut Vec < Span > | {
346
+ debug ! (
347
+ "check_kind_count: kind: {} required: {} permitted: {} provided: {} offset: {}" ,
348
+ kind, required, permitted, provided, offset
349
+ ) ;
350
+ // We enforce the following: `required` <= `provided` <= `permitted`.
351
+ // For kinds without defaults (e.g.., lifetimes), `required == permitted`.
352
+ // For other kinds (i.e., types), `permitted` may be greater than `required`.
353
+ if required <= provided && provided <= permitted {
354
+ return false ;
364
355
}
365
- } else {
366
- ( required, "" )
367
- } ;
368
356
369
- let mut potential_assoc_types: Option < Vec < Span > > = None ;
370
- let ( spans, label) = if required == permitted && provided > permitted {
371
- // In the case when the user has provided too many arguments,
372
- // we want to point to the unexpected arguments.
373
- let spans: Vec < Span > = args. args [ offset + permitted..offset + provided]
374
- . iter ( )
375
- . map ( |arg| arg. span ( ) )
376
- . collect ( ) ;
377
- potential_assoc_types = Some ( spans. clone ( ) ) ;
378
- ( spans, format ! ( "unexpected {} argument" , kind) )
379
- } else {
380
- (
381
- vec ! [ span] ,
382
- format ! (
383
- "expected {}{} {} argument{}" ,
384
- quantifier,
385
- bound,
386
- kind,
387
- pluralize!( bound) ,
357
+ // Unfortunately lifetime and type parameter mismatches are typically styled
358
+ // differently in diagnostics, which means we have a few cases to consider here.
359
+ let ( bound, quantifier) = if required != permitted {
360
+ if provided < required {
361
+ ( required, "at least " )
362
+ } else {
363
+ // provided > permitted
364
+ ( permitted, "at most " )
365
+ }
366
+ } else {
367
+ ( required, "" )
368
+ } ;
369
+
370
+ let ( spans, label) = if required == permitted && provided > permitted {
371
+ // In the case when the user has provided too many arguments,
372
+ // we want to point to the unexpected arguments.
373
+ let spans: Vec < Span > = args. args [ offset + permitted..offset + provided]
374
+ . iter ( )
375
+ . map ( |arg| arg. span ( ) )
376
+ . collect ( ) ;
377
+ unexpected_spans. extend ( spans. clone ( ) ) ;
378
+ ( spans, format ! ( "unexpected {} argument" , kind) )
379
+ } else {
380
+ (
381
+ vec ! [ span] ,
382
+ format ! (
383
+ "expected {}{} {} argument{}" ,
384
+ quantifier,
385
+ bound,
386
+ kind,
387
+ pluralize!( bound) ,
388
+ ) ,
389
+ )
390
+ } ;
391
+
392
+ let mut err = tcx. sess . struct_span_err_with_code (
393
+ spans. clone ( ) ,
394
+ & format ! (
395
+ "wrong number of {} arguments: expected {}{}, found {}" ,
396
+ kind, quantifier, bound, provided,
388
397
) ,
389
- )
390
- } ;
398
+ DiagnosticId :: Error ( "E0107" . into ( ) ) ,
399
+ ) ;
400
+ for span in spans {
401
+ err. span_label ( span, label. as_str ( ) ) ;
402
+ }
403
+ err. emit ( ) ;
391
404
392
- let mut err = tcx. sess . struct_span_err_with_code (
393
- spans. clone ( ) ,
394
- & format ! (
395
- "wrong number of {} arguments: expected {}{}, found {}" ,
396
- kind, quantifier, bound, provided,
397
- ) ,
398
- DiagnosticId :: Error ( "E0107" . into ( ) ) ,
399
- ) ;
400
- for span in spans {
401
- err. span_label ( span, label. as_str ( ) ) ;
402
- }
403
- err. emit ( ) ;
405
+ true
406
+ } ;
404
407
405
- ( true , potential_assoc_types )
406
- } ;
408
+ let mut arg_count_mismatch = reported_late_bound_region_err . unwrap_or ( false ) ;
409
+ let mut unexpected_spans = vec ! [ ] ;
407
410
408
411
if reported_late_bound_region_err. is_none ( )
409
412
&& ( !infer_lifetimes || arg_counts. lifetimes > param_counts. lifetimes )
410
413
{
411
- check_kind_count (
414
+ arg_count_mismatch |= check_kind_count (
412
415
"lifetime" ,
413
416
param_counts. lifetimes ,
414
417
param_counts. lifetimes ,
415
418
arg_counts. lifetimes ,
416
419
0 ,
420
+ & mut unexpected_spans,
417
421
) ;
418
422
}
419
423
// FIXME(const_generics:defaults)
420
424
if !infer_args || arg_counts. consts > param_counts. consts {
421
- check_kind_count (
425
+ arg_count_mismatch |= check_kind_count (
422
426
"const" ,
423
427
param_counts. consts ,
424
428
param_counts. consts ,
425
429
arg_counts. consts ,
426
430
arg_counts. lifetimes + arg_counts. types ,
431
+ & mut unexpected_spans,
427
432
) ;
428
433
}
429
434
// Note that type errors are currently be emitted *after* const errors.
430
435
if !infer_args || arg_counts. types > param_counts. types - defaults. types - has_self as usize
431
436
{
432
- check_kind_count (
437
+ arg_count_mismatch |= check_kind_count (
433
438
"type" ,
434
439
param_counts. types - defaults. types - has_self as usize ,
435
440
param_counts. types - has_self as usize ,
436
441
arg_counts. types ,
437
442
arg_counts. lifetimes ,
438
- )
439
- } else {
440
- ( reported_late_bound_region_err. unwrap_or ( false ) , None )
443
+ & mut unexpected_spans,
444
+ ) ;
441
445
}
446
+
447
+ ( arg_count_mismatch, unexpected_spans)
442
448
}
443
449
444
450
/// Creates the relevant generic argument substitutions
@@ -627,7 +633,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
627
633
generic_args : & ' a hir:: GenericArgs < ' _ > ,
628
634
infer_args : bool ,
629
635
self_ty : Option < Ty < ' tcx > > ,
630
- ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Option < Vec < Span > > ) {
636
+ ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Vec < Span > ) {
631
637
// If the type is parameterized by this region, then replace this
632
638
// region with the current anon region binding (in other words,
633
639
// whatever & would get replaced with).
@@ -922,7 +928,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
922
928
self_ty : Ty < ' tcx > ,
923
929
bounds : & mut Bounds < ' tcx > ,
924
930
speculative : bool ,
925
- ) -> Option < Vec < Span > > {
931
+ ) -> Vec < Span > {
926
932
let trait_def_id = trait_ref. trait_def_id ( ) ;
927
933
928
934
debug ! ( "instantiate_poly_trait_ref({:?}, def_id={:?})" , trait_ref, trait_def_id) ;
@@ -968,6 +974,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
968
974
"instantiate_poly_trait_ref({:?}, bounds={:?}) -> {:?}" ,
969
975
trait_ref, bounds, poly_trait_ref
970
976
) ;
977
+
971
978
potential_assoc_types
972
979
}
973
980
@@ -996,7 +1003,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
996
1003
constness : Constness ,
997
1004
self_ty : Ty < ' tcx > ,
998
1005
bounds : & mut Bounds < ' tcx > ,
999
- ) -> Option < Vec < Span > > {
1006
+ ) -> Vec < Span > {
1000
1007
self . instantiate_poly_trait_ref_inner (
1001
1008
& poly_trait_ref. trait_ref ,
1002
1009
poly_trait_ref. span ,
@@ -1085,7 +1092,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1085
1092
trait_def_id : DefId ,
1086
1093
self_ty : Ty < ' tcx > ,
1087
1094
trait_segment : & ' a hir:: PathSegment < ' a > ,
1088
- ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Option < Vec < Span > > ) {
1095
+ ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Vec < Span > ) {
1089
1096
debug ! ( "create_substs_for_ast_trait_ref(trait_segment={:?})" , trait_segment) ;
1090
1097
1091
1098
self . complain_about_internal_fn_trait ( span, trait_def_id, trait_segment) ;
@@ -1436,7 +1443,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1436
1443
dummy_self,
1437
1444
& mut bounds,
1438
1445
) ;
1439
- potential_assoc_types. extend ( cur_potential_assoc_types. into_iter ( ) . flatten ( ) ) ;
1446
+ potential_assoc_types. extend ( cur_potential_assoc_types. into_iter ( ) ) ;
1440
1447
}
1441
1448
1442
1449
// Expand trait aliases recursively and check that only one regular (non-auto) trait
0 commit comments