@@ -287,7 +287,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
287287 position : GenericArgPosition ,
288288 has_self : bool ,
289289 infer_args : bool ,
290- ) -> ( bool , Option < Vec < Span > > ) {
290+ ) -> ( bool , Vec < Span > ) {
291291 // At this stage we are guaranteed that the generic arguments are in the correct order, e.g.
292292 // that lifetimes will proceed types. So it suffices to check the number of each generic
293293 // arguments in order to validate them with respect to the generic parameters.
@@ -341,104 +341,110 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
341341 }
342342 }
343343
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 ;
364355 }
365- } else {
366- ( required, "" )
367- } ;
368356
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,
388397 ) ,
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 ( ) ;
391404
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+ } ;
404407
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 ! [ ] ;
407410
408411 if reported_late_bound_region_err. is_none ( )
409412 && ( !infer_lifetimes || arg_counts. lifetimes > param_counts. lifetimes )
410413 {
411- check_kind_count (
414+ arg_count_mismatch |= check_kind_count (
412415 "lifetime" ,
413416 param_counts. lifetimes ,
414417 param_counts. lifetimes ,
415418 arg_counts. lifetimes ,
416419 0 ,
420+ & mut unexpected_spans,
417421 ) ;
418422 }
419423 // FIXME(const_generics:defaults)
420424 if !infer_args || arg_counts. consts > param_counts. consts {
421- check_kind_count (
425+ arg_count_mismatch |= check_kind_count (
422426 "const" ,
423427 param_counts. consts ,
424428 param_counts. consts ,
425429 arg_counts. consts ,
426430 arg_counts. lifetimes + arg_counts. types ,
431+ & mut unexpected_spans,
427432 ) ;
428433 }
429434 // Note that type errors are currently be emitted *after* const errors.
430435 if !infer_args || arg_counts. types > param_counts. types - defaults. types - has_self as usize
431436 {
432- check_kind_count (
437+ arg_count_mismatch |= check_kind_count (
433438 "type" ,
434439 param_counts. types - defaults. types - has_self as usize ,
435440 param_counts. types - has_self as usize ,
436441 arg_counts. types ,
437442 arg_counts. lifetimes ,
438- )
439- } else {
440- ( reported_late_bound_region_err. unwrap_or ( false ) , None )
443+ & mut unexpected_spans,
444+ ) ;
441445 }
446+
447+ ( arg_count_mismatch, unexpected_spans)
442448 }
443449
444450 /// Creates the relevant generic argument substitutions
@@ -627,7 +633,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
627633 generic_args : & ' a hir:: GenericArgs < ' _ > ,
628634 infer_args : bool ,
629635 self_ty : Option < Ty < ' tcx > > ,
630- ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Option < Vec < Span > > ) {
636+ ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Vec < Span > ) {
631637 // If the type is parameterized by this region, then replace this
632638 // region with the current anon region binding (in other words,
633639 // whatever & would get replaced with).
@@ -922,7 +928,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
922928 self_ty : Ty < ' tcx > ,
923929 bounds : & mut Bounds < ' tcx > ,
924930 speculative : bool ,
925- ) -> Option < Vec < Span > > {
931+ ) -> Vec < Span > {
926932 let trait_def_id = trait_ref. trait_def_id ( ) ;
927933
928934 debug ! ( "instantiate_poly_trait_ref({:?}, def_id={:?})" , trait_ref, trait_def_id) ;
@@ -968,6 +974,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
968974 "instantiate_poly_trait_ref({:?}, bounds={:?}) -> {:?}" ,
969975 trait_ref, bounds, poly_trait_ref
970976 ) ;
977+
971978 potential_assoc_types
972979 }
973980
@@ -996,7 +1003,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
9961003 constness : Constness ,
9971004 self_ty : Ty < ' tcx > ,
9981005 bounds : & mut Bounds < ' tcx > ,
999- ) -> Option < Vec < Span > > {
1006+ ) -> Vec < Span > {
10001007 self . instantiate_poly_trait_ref_inner (
10011008 & poly_trait_ref. trait_ref ,
10021009 poly_trait_ref. span ,
@@ -1085,7 +1092,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10851092 trait_def_id : DefId ,
10861093 self_ty : Ty < ' tcx > ,
10871094 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 > ) {
10891096 debug ! ( "create_substs_for_ast_trait_ref(trait_segment={:?})" , trait_segment) ;
10901097
10911098 self . complain_about_internal_fn_trait ( span, trait_def_id, trait_segment) ;
@@ -1436,7 +1443,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14361443 dummy_self,
14371444 & mut bounds,
14381445 ) ;
1439- potential_assoc_types. extend ( cur_potential_assoc_types. into_iter ( ) . flatten ( ) ) ;
1446+ potential_assoc_types. extend ( cur_potential_assoc_types. into_iter ( ) ) ;
14401447 }
14411448
14421449 // Expand trait aliases recursively and check that only one regular (non-auto) trait
0 commit comments