@@ -134,8 +134,12 @@ enum GenericArgPosition {
134134
135135/// A marker denoting that the generic arguments that were
136136/// provided did not match the respective generic parameters.
137- /// The field indicates whether a fatal error was reported (`Some`), or just a lint (`None`).
138- pub struct GenericArgCountMismatch ( pub Option < ErrorReported > ) ;
137+ pub struct GenericArgCountMismatch {
138+ /// Indicates whether a fatal error was reported (`Some`), or just a lint (`None`).
139+ pub reported : Option < ErrorReported > ,
140+ /// A list of spans of arguments provided that were not valid.
141+ pub invalid_args : Vec < Span > ,
142+ }
139143
140144impl < ' o , ' tcx > dyn AstConv < ' tcx > + ' o {
141145 pub fn ast_region_to_region (
@@ -279,7 +283,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
279283 def. parent . is_none ( ) && def. has_self , // `has_self`
280284 seg. infer_args || suppress_mismatch, // `infer_args`
281285 )
282- . 0
283286 }
284287
285288 /// Checks that the correct number of generic arguments have been provided.
@@ -292,7 +295,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
292295 position : GenericArgPosition ,
293296 has_self : bool ,
294297 infer_args : bool ,
295- ) -> ( Result < ( ) , GenericArgCountMismatch > , Vec < Span > ) {
298+ ) -> Result < ( ) , GenericArgCountMismatch > {
296299 // At this stage we are guaranteed that the generic arguments are in the correct order, e.g.
297300 // that lifetimes will proceed types. So it suffices to check the number of each generic
298301 // arguments in order to validate them with respect to the generic parameters.
@@ -328,12 +331,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
328331 if position == GenericArgPosition :: Value
329332 && arg_counts. lifetimes != param_counts. lifetimes
330333 {
331- explicit_lifetimes = Err ( GenericArgCountMismatch ( Some ( ErrorReported ) ) ) ;
334+ explicit_lifetimes = Err ( true ) ;
332335 let mut err = tcx. sess . struct_span_err ( span, msg) ;
333336 err. span_note ( span_late, note) ;
334337 err. emit ( ) ;
335338 } else {
336- explicit_lifetimes = Err ( GenericArgCountMismatch ( None ) ) ;
339+ explicit_lifetimes = Err ( false ) ;
337340 let mut multispan = MultiSpan :: from_span ( span) ;
338341 multispan. push_span_label ( span_late, note. to_string ( ) ) ;
339342 tcx. struct_span_lint_hir (
@@ -407,7 +410,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
407410 }
408411 err. emit ( ) ;
409412
410- Err ( GenericArgCountMismatch ( Some ( ErrorReported ) ) )
413+ Err ( true )
411414 } ;
412415
413416 let mut arg_count_correct = explicit_lifetimes;
@@ -416,40 +419,46 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
416419 if arg_count_correct. is_ok ( )
417420 && ( !infer_lifetimes || arg_counts. lifetimes > param_counts. lifetimes )
418421 {
419- arg_count_correct = arg_count_correct . and ( check_kind_count (
422+ arg_count_correct = check_kind_count (
420423 "lifetime" ,
421424 param_counts. lifetimes ,
422425 param_counts. lifetimes ,
423426 arg_counts. lifetimes ,
424427 0 ,
425428 & mut unexpected_spans,
426- ) ) ;
429+ )
430+ . and ( arg_count_correct) ;
427431 }
428432 // FIXME(const_generics:defaults)
429433 if !infer_args || arg_counts. consts > param_counts. consts {
430- arg_count_correct = arg_count_correct . and ( check_kind_count (
434+ arg_count_correct = check_kind_count (
431435 "const" ,
432436 param_counts. consts ,
433437 param_counts. consts ,
434438 arg_counts. consts ,
435439 arg_counts. lifetimes + arg_counts. types ,
436440 & mut unexpected_spans,
437- ) ) ;
441+ )
442+ . and ( arg_count_correct) ;
438443 }
439444 // Note that type errors are currently be emitted *after* const errors.
440445 if !infer_args || arg_counts. types > param_counts. types - defaults. types - has_self as usize
441446 {
442- arg_count_correct = arg_count_correct . and ( check_kind_count (
447+ arg_count_correct = check_kind_count (
443448 "type" ,
444449 param_counts. types - defaults. types - has_self as usize ,
445450 param_counts. types - has_self as usize ,
446451 arg_counts. types ,
447452 arg_counts. lifetimes ,
448453 & mut unexpected_spans,
449- ) ) ;
454+ )
455+ . and ( arg_count_correct) ;
450456 }
451457
452- ( arg_count_correct, unexpected_spans)
458+ arg_count_correct. map_err ( |reported_err| GenericArgCountMismatch {
459+ reported : if reported_err { Some ( ErrorReported ) } else { None } ,
460+ invalid_args : unexpected_spans,
461+ } )
453462 }
454463
455464 /// Report an error that a generic argument did not match the generic parameter that was
@@ -501,7 +510,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
501510 parent_substs : & [ subst:: GenericArg < ' tcx > ] ,
502511 has_self : bool ,
503512 self_ty : Option < Ty < ' tcx > > ,
504- arg_count_correct : Result < ( ) , GenericArgCountMismatch > ,
513+ arg_count_correct : bool ,
505514 args_for_def_id : impl Fn ( DefId ) -> ( Option < & ' b GenericArgs < ' b > > , bool ) ,
506515 provided_kind : impl Fn ( & GenericParamDef , & GenericArg < ' _ > ) -> subst:: GenericArg < ' tcx > ,
507516 mut inferred_kind : impl FnMut (
@@ -595,7 +604,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
595604 // another. This is an error. However, if we already know that
596605 // the arguments don't match up with the parameters, we won't issue
597606 // an additional error, as the user already knows what's wrong.
598- if arg_count_correct. is_ok ( ) {
607+ if arg_count_correct {
599608 Self :: generic_arg_mismatch_err ( tcx. sess , arg, kind. descr ( ) ) ;
600609 }
601610
@@ -621,7 +630,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
621630 // 2. We've inferred some lifetimes, which have been provided later (i.e.
622631 // after a type or const). We want to throw an error in this case.
623632
624- if arg_count_correct. is_ok ( ) {
633+ if arg_count_correct {
625634 let kind = arg. descr ( ) ;
626635 assert_eq ! ( kind, "lifetime" ) ;
627636 let provided =
@@ -686,7 +695,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
686695 generic_args : & ' a hir:: GenericArgs < ' _ > ,
687696 infer_args : bool ,
688697 self_ty : Option < Ty < ' tcx > > ,
689- ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Vec < Span > ) {
698+ ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Result < ( ) , GenericArgCountMismatch > )
699+ {
690700 // If the type is parameterized by this region, then replace this
691701 // region with the current anon region binding (in other words,
692702 // whatever & would get replaced with).
@@ -712,7 +722,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
712722 assert ! ( self_ty. is_none( ) && parent_substs. is_empty( ) ) ;
713723 }
714724
715- let ( arg_count_correct, potential_assoc_types ) = Self :: check_generic_arg_count (
725+ let arg_count_correct = Self :: check_generic_arg_count (
716726 tcx,
717727 span,
718728 & generic_params,
@@ -745,7 +755,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
745755 parent_substs,
746756 self_ty. is_some ( ) ,
747757 self_ty,
748- arg_count_correct,
758+ arg_count_correct. is_ok ( ) ,
749759 // Provide the generic args, and whether types should be inferred.
750760 |did| {
751761 if did == def_id {
@@ -858,7 +868,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
858868 generic_params, self_ty, substs
859869 ) ;
860870
861- ( substs, assoc_bindings, potential_assoc_types )
871+ ( substs, assoc_bindings, arg_count_correct )
862872 }
863873
864874 crate fn create_substs_for_associated_item (
@@ -989,7 +999,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
989999 self_ty : Ty < ' tcx > ,
9901000 bounds : & mut Bounds < ' tcx > ,
9911001 speculative : bool ,
992- ) -> Vec < Span > {
1002+ ) -> Result < ( ) , GenericArgCountMismatch > {
9931003 let trait_def_id = trait_ref. trait_def_id ( ) ;
9941004
9951005 debug ! ( "instantiate_poly_trait_ref({:?}, def_id={:?})" , trait_ref, trait_def_id) ;
@@ -1006,7 +1016,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10061016 } else {
10071017 trait_ref. path . span
10081018 } ;
1009- let ( substs, assoc_bindings, potential_assoc_types ) = self . create_substs_for_ast_trait_ref (
1019+ let ( substs, assoc_bindings, arg_count_correct ) = self . create_substs_for_ast_trait_ref (
10101020 path_span,
10111021 trait_def_id,
10121022 self_ty,
@@ -1036,7 +1046,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10361046 trait_ref, bounds, poly_trait_ref
10371047 ) ;
10381048
1039- potential_assoc_types
1049+ arg_count_correct
10401050 }
10411051
10421052 /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
@@ -1064,7 +1074,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10641074 constness : Constness ,
10651075 self_ty : Ty < ' tcx > ,
10661076 bounds : & mut Bounds < ' tcx > ,
1067- ) -> Vec < Span > {
1077+ ) -> Result < ( ) , GenericArgCountMismatch > {
10681078 self . instantiate_poly_trait_ref_inner (
10691079 & poly_trait_ref. trait_ref ,
10701080 poly_trait_ref. span ,
@@ -1153,7 +1163,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11531163 trait_def_id : DefId ,
11541164 self_ty : Ty < ' tcx > ,
11551165 trait_segment : & ' a hir:: PathSegment < ' a > ,
1156- ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Vec < Span > ) {
1166+ ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Result < ( ) , GenericArgCountMismatch > )
1167+ {
11571168 debug ! ( "create_substs_for_ast_trait_ref(trait_segment={:?})" , trait_segment) ;
11581169
11591170 self . complain_about_internal_fn_trait ( span, trait_def_id, trait_segment) ;
@@ -1498,13 +1509,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14981509 let mut potential_assoc_types = Vec :: new ( ) ;
14991510 let dummy_self = self . tcx ( ) . types . trait_object_dummy_self ;
15001511 for trait_bound in trait_bounds. iter ( ) . rev ( ) {
1501- let cur_potential_assoc_types = self . instantiate_poly_trait_ref (
1512+ if let Err ( GenericArgCountMismatch {
1513+ invalid_args : cur_potential_assoc_types, ..
1514+ } ) = self . instantiate_poly_trait_ref (
15021515 trait_bound,
15031516 Constness :: NotConst ,
15041517 dummy_self,
15051518 & mut bounds,
1506- ) ;
1507- potential_assoc_types. extend ( cur_potential_assoc_types. into_iter ( ) ) ;
1519+ ) {
1520+ potential_assoc_types. extend ( cur_potential_assoc_types. into_iter ( ) ) ;
1521+ }
15081522 }
15091523
15101524 // Expand trait aliases recursively and check that only one regular (non-auto) trait
0 commit comments