@@ -134,8 +134,12 @@ enum GenericArgPosition {
134
134
135
135
/// A marker denoting that the generic arguments that were
136
136
/// 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
+ }
139
143
140
144
impl < ' o , ' tcx > dyn AstConv < ' tcx > + ' o {
141
145
pub fn ast_region_to_region (
@@ -279,7 +283,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
279
283
def. parent . is_none ( ) && def. has_self , // `has_self`
280
284
seg. infer_args || suppress_mismatch, // `infer_args`
281
285
)
282
- . 0
283
286
}
284
287
285
288
/// Checks that the correct number of generic arguments have been provided.
@@ -292,7 +295,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
292
295
position : GenericArgPosition ,
293
296
has_self : bool ,
294
297
infer_args : bool ,
295
- ) -> ( Result < ( ) , GenericArgCountMismatch > , Vec < Span > ) {
298
+ ) -> Result < ( ) , GenericArgCountMismatch > {
296
299
// At this stage we are guaranteed that the generic arguments are in the correct order, e.g.
297
300
// that lifetimes will proceed types. So it suffices to check the number of each generic
298
301
// arguments in order to validate them with respect to the generic parameters.
@@ -328,12 +331,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
328
331
if position == GenericArgPosition :: Value
329
332
&& arg_counts. lifetimes != param_counts. lifetimes
330
333
{
331
- explicit_lifetimes = Err ( GenericArgCountMismatch ( Some ( ErrorReported ) ) ) ;
334
+ explicit_lifetimes = Err ( true ) ;
332
335
let mut err = tcx. sess . struct_span_err ( span, msg) ;
333
336
err. span_note ( span_late, note) ;
334
337
err. emit ( ) ;
335
338
} else {
336
- explicit_lifetimes = Err ( GenericArgCountMismatch ( None ) ) ;
339
+ explicit_lifetimes = Err ( false ) ;
337
340
let mut multispan = MultiSpan :: from_span ( span) ;
338
341
multispan. push_span_label ( span_late, note. to_string ( ) ) ;
339
342
tcx. struct_span_lint_hir (
@@ -407,7 +410,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
407
410
}
408
411
err. emit ( ) ;
409
412
410
- Err ( GenericArgCountMismatch ( Some ( ErrorReported ) ) )
413
+ Err ( true )
411
414
} ;
412
415
413
416
let mut arg_count_correct = explicit_lifetimes;
@@ -416,40 +419,46 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
416
419
if arg_count_correct. is_ok ( )
417
420
&& ( !infer_lifetimes || arg_counts. lifetimes > param_counts. lifetimes )
418
421
{
419
- arg_count_correct = arg_count_correct . and ( check_kind_count (
422
+ arg_count_correct = check_kind_count (
420
423
"lifetime" ,
421
424
param_counts. lifetimes ,
422
425
param_counts. lifetimes ,
423
426
arg_counts. lifetimes ,
424
427
0 ,
425
428
& mut unexpected_spans,
426
- ) ) ;
429
+ )
430
+ . and ( arg_count_correct) ;
427
431
}
428
432
// FIXME(const_generics:defaults)
429
433
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 (
431
435
"const" ,
432
436
param_counts. consts ,
433
437
param_counts. consts ,
434
438
arg_counts. consts ,
435
439
arg_counts. lifetimes + arg_counts. types ,
436
440
& mut unexpected_spans,
437
- ) ) ;
441
+ )
442
+ . and ( arg_count_correct) ;
438
443
}
439
444
// Note that type errors are currently be emitted *after* const errors.
440
445
if !infer_args || arg_counts. types > param_counts. types - defaults. types - has_self as usize
441
446
{
442
- arg_count_correct = arg_count_correct . and ( check_kind_count (
447
+ arg_count_correct = check_kind_count (
443
448
"type" ,
444
449
param_counts. types - defaults. types - has_self as usize ,
445
450
param_counts. types - has_self as usize ,
446
451
arg_counts. types ,
447
452
arg_counts. lifetimes ,
448
453
& mut unexpected_spans,
449
- ) ) ;
454
+ )
455
+ . and ( arg_count_correct) ;
450
456
}
451
457
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
+ } )
453
462
}
454
463
455
464
/// 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 {
501
510
parent_substs : & [ subst:: GenericArg < ' tcx > ] ,
502
511
has_self : bool ,
503
512
self_ty : Option < Ty < ' tcx > > ,
504
- arg_count_correct : Result < ( ) , GenericArgCountMismatch > ,
513
+ arg_count_correct : bool ,
505
514
args_for_def_id : impl Fn ( DefId ) -> ( Option < & ' b GenericArgs < ' b > > , bool ) ,
506
515
provided_kind : impl Fn ( & GenericParamDef , & GenericArg < ' _ > ) -> subst:: GenericArg < ' tcx > ,
507
516
mut inferred_kind : impl FnMut (
@@ -595,7 +604,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
595
604
// another. This is an error. However, if we already know that
596
605
// the arguments don't match up with the parameters, we won't issue
597
606
// an additional error, as the user already knows what's wrong.
598
- if arg_count_correct. is_ok ( ) {
607
+ if arg_count_correct {
599
608
Self :: generic_arg_mismatch_err ( tcx. sess , arg, kind. descr ( ) ) ;
600
609
}
601
610
@@ -621,7 +630,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
621
630
// 2. We've inferred some lifetimes, which have been provided later (i.e.
622
631
// after a type or const). We want to throw an error in this case.
623
632
624
- if arg_count_correct. is_ok ( ) {
633
+ if arg_count_correct {
625
634
let kind = arg. descr ( ) ;
626
635
assert_eq ! ( kind, "lifetime" ) ;
627
636
let provided =
@@ -686,7 +695,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
686
695
generic_args : & ' a hir:: GenericArgs < ' _ > ,
687
696
infer_args : bool ,
688
697
self_ty : Option < Ty < ' tcx > > ,
689
- ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Vec < Span > ) {
698
+ ) -> ( SubstsRef < ' tcx > , Vec < ConvertedBinding < ' a , ' tcx > > , Result < ( ) , GenericArgCountMismatch > )
699
+ {
690
700
// If the type is parameterized by this region, then replace this
691
701
// region with the current anon region binding (in other words,
692
702
// whatever & would get replaced with).
@@ -712,7 +722,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
712
722
assert ! ( self_ty. is_none( ) && parent_substs. is_empty( ) ) ;
713
723
}
714
724
715
- let ( arg_count_correct, potential_assoc_types ) = Self :: check_generic_arg_count (
725
+ let arg_count_correct = Self :: check_generic_arg_count (
716
726
tcx,
717
727
span,
718
728
& generic_params,
@@ -745,7 +755,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
745
755
parent_substs,
746
756
self_ty. is_some ( ) ,
747
757
self_ty,
748
- arg_count_correct,
758
+ arg_count_correct. is_ok ( ) ,
749
759
// Provide the generic args, and whether types should be inferred.
750
760
|did| {
751
761
if did == def_id {
@@ -858,7 +868,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
858
868
generic_params, self_ty, substs
859
869
) ;
860
870
861
- ( substs, assoc_bindings, potential_assoc_types )
871
+ ( substs, assoc_bindings, arg_count_correct )
862
872
}
863
873
864
874
crate fn create_substs_for_associated_item (
@@ -989,7 +999,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
989
999
self_ty : Ty < ' tcx > ,
990
1000
bounds : & mut Bounds < ' tcx > ,
991
1001
speculative : bool ,
992
- ) -> Vec < Span > {
1002
+ ) -> Result < ( ) , GenericArgCountMismatch > {
993
1003
let trait_def_id = trait_ref. trait_def_id ( ) ;
994
1004
995
1005
debug ! ( "instantiate_poly_trait_ref({:?}, def_id={:?})" , trait_ref, trait_def_id) ;
@@ -1006,7 +1016,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1006
1016
} else {
1007
1017
trait_ref. path . span
1008
1018
} ;
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 (
1010
1020
path_span,
1011
1021
trait_def_id,
1012
1022
self_ty,
@@ -1036,7 +1046,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1036
1046
trait_ref, bounds, poly_trait_ref
1037
1047
) ;
1038
1048
1039
- potential_assoc_types
1049
+ arg_count_correct
1040
1050
}
1041
1051
1042
1052
/// 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 {
1064
1074
constness : Constness ,
1065
1075
self_ty : Ty < ' tcx > ,
1066
1076
bounds : & mut Bounds < ' tcx > ,
1067
- ) -> Vec < Span > {
1077
+ ) -> Result < ( ) , GenericArgCountMismatch > {
1068
1078
self . instantiate_poly_trait_ref_inner (
1069
1079
& poly_trait_ref. trait_ref ,
1070
1080
poly_trait_ref. span ,
@@ -1153,7 +1163,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1153
1163
trait_def_id : DefId ,
1154
1164
self_ty : Ty < ' tcx > ,
1155
1165
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
+ {
1157
1168
debug ! ( "create_substs_for_ast_trait_ref(trait_segment={:?})" , trait_segment) ;
1158
1169
1159
1170
self . complain_about_internal_fn_trait ( span, trait_def_id, trait_segment) ;
@@ -1498,13 +1509,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1498
1509
let mut potential_assoc_types = Vec :: new ( ) ;
1499
1510
let dummy_self = self . tcx ( ) . types . trait_object_dummy_self ;
1500
1511
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 (
1502
1515
trait_bound,
1503
1516
Constness :: NotConst ,
1504
1517
dummy_self,
1505
1518
& 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
+ }
1508
1522
}
1509
1523
1510
1524
// Expand trait aliases recursively and check that only one regular (non-auto) trait
0 commit comments