@@ -385,7 +385,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
385
385
// the moment, give a kind of vague error message.
386
386
if trait_params != impl_params {
387
387
let def_span = tcx. sess . source_map ( ) . def_span ( span) ;
388
- let span = tcx. hir ( ) . get_generics_span ( impl_m. def_id ) . unwrap_or ( def_span) ;
388
+ let span = tcx. hir ( ) . get_generics ( impl_m. def_id ) . map ( |g| g . span ) . unwrap_or ( def_span) ;
389
389
let mut err = struct_span_err ! (
390
390
tcx. sess,
391
391
span,
@@ -396,7 +396,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
396
396
err. span_label ( span, "lifetimes do not match method in trait" ) ;
397
397
if let Some ( sp) = tcx. hir ( ) . span_if_local ( trait_m. def_id ) {
398
398
let def_sp = tcx. sess . source_map ( ) . def_span ( sp) ;
399
- let sp = tcx. hir ( ) . get_generics_span ( trait_m. def_id ) . unwrap_or ( def_sp) ;
399
+ let sp = tcx. hir ( ) . get_generics ( trait_m. def_id ) . map ( |g| g . span ) . unwrap_or ( def_sp) ;
400
400
err. span_label ( sp, "lifetimes in impl do not match this method in trait" ) ;
401
401
}
402
402
err. emit ( ) ;
@@ -583,7 +583,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
583
583
fn compare_number_of_generics < ' a , ' tcx > (
584
584
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
585
585
impl_ : & ty:: AssocItem ,
586
- impl_span : Span ,
586
+ _impl_span : Span ,
587
587
trait_ : & ty:: AssocItem ,
588
588
trait_span : Option < Span > ,
589
589
) -> Result < ( ) , ErrorReported > {
@@ -600,17 +600,44 @@ fn compare_number_of_generics<'a, 'tcx>(
600
600
if impl_count != trait_count {
601
601
err_occurred = true ;
602
602
603
- let impl_hir_id = tcx. hir ( ) . as_local_hir_id ( impl_. def_id ) . unwrap ( ) ;
604
- let impl_item = tcx. hir ( ) . expect_impl_item ( impl_hir_id) ;
605
- let span = if impl_item. generics . params . is_empty ( )
606
- || impl_item. generics . span . is_dummy ( ) { // argument position impl Trait (#55374)
607
- impl_span
603
+ let (
604
+ trait_spans,
605
+ impl_trait_spans,
606
+ ) = if let Some ( trait_hir_id) = tcx. hir ( ) . as_local_hir_id ( trait_. def_id ) {
607
+ let trait_item = tcx. hir ( ) . expect_trait_item ( trait_hir_id) ;
608
+ if trait_item. generics . params . is_empty ( ) {
609
+ ( Some ( vec ! [ trait_item. generics. span] ) , vec ! [ ] )
610
+ } else {
611
+ let arg_spans: Vec < Span > = trait_item. generics . params . iter ( )
612
+ . map ( |p| p. span )
613
+ . collect ( ) ;
614
+ let impl_trait_spans: Vec < Span > = trait_item. generics . params . iter ( )
615
+ . filter_map ( |p| match p. kind {
616
+ GenericParamKind :: Type {
617
+ synthetic : Some ( hir:: SyntheticTyParamKind :: ImplTrait ) , ..
618
+ } => Some ( p. span ) ,
619
+ _ => None ,
620
+ } ) . collect ( ) ;
621
+ ( Some ( arg_spans) , impl_trait_spans)
622
+ }
608
623
} else {
609
- impl_item . generics . span
624
+ ( trait_span . map ( |s| vec ! [ s ] ) , vec ! [ ] )
610
625
} ;
611
626
627
+ let impl_hir_id = tcx. hir ( ) . as_local_hir_id ( impl_. def_id ) . unwrap ( ) ;
628
+ let impl_item = tcx. hir ( ) . expect_impl_item ( impl_hir_id) ;
629
+ let impl_item_impl_trait_spans: Vec < Span > = impl_item. generics . params . iter ( )
630
+ . filter_map ( |p| match p. kind {
631
+ GenericParamKind :: Type {
632
+ synthetic : Some ( hir:: SyntheticTyParamKind :: ImplTrait ) , ..
633
+ } => Some ( p. span ) ,
634
+ _ => None ,
635
+ } ) . collect ( ) ;
636
+ let spans = impl_item. generics . spans ( ) ;
637
+ let span = spans. primary_span ( ) ;
638
+
612
639
let mut err = tcx. sess . struct_span_err_with_code (
613
- span ,
640
+ spans ,
614
641
& format ! (
615
642
"method `{}` has {} {kind} parameter{} but its trait \
616
643
declaration has {} {kind} parameter{}",
@@ -626,22 +653,36 @@ fn compare_number_of_generics<'a, 'tcx>(
626
653
627
654
let mut suffix = None ;
628
655
629
- if let Some ( span) = trait_span {
630
- err. span_label (
631
- span,
632
- format ! ( "expected {} {} parameter{}" , trait_count, kind,
633
- if trait_count != 1 { "s" } else { "" } )
634
- ) ;
656
+ if let Some ( spans) = trait_spans {
657
+ let mut spans = spans. iter ( ) ;
658
+ if let Some ( span) = spans. next ( ) {
659
+ err. span_label ( * span, format ! (
660
+ "expected {} {} parameter{}" ,
661
+ trait_count,
662
+ kind,
663
+ if trait_count != 1 { "s" } else { "" } ,
664
+ ) ) ;
665
+ }
666
+ for span in spans {
667
+ err. span_label ( * span, "" ) ;
668
+ }
635
669
} else {
636
670
suffix = Some ( format ! ( ", expected {}" , trait_count) ) ;
637
671
}
638
672
639
- err. span_label (
640
- span,
641
- format ! ( "found {} {} parameter{}{}" , impl_count, kind,
673
+ if let Some ( span) = span {
674
+ err. span_label ( span, format ! (
675
+ "found {} {} parameter{}{}" ,
676
+ impl_count,
677
+ kind,
642
678
if impl_count != 1 { "s" } else { "" } ,
643
- suffix. unwrap_or_else( || String :: new( ) ) ) ,
644
- ) ;
679
+ suffix. unwrap_or_else( || String :: new( ) ) ,
680
+ ) ) ;
681
+ }
682
+
683
+ for span in impl_trait_spans. iter ( ) . chain ( impl_item_impl_trait_spans. iter ( ) ) {
684
+ err. span_label ( * span, "`impl Trait` introduces an implicit type parameter" ) ;
685
+ }
645
686
646
687
err. emit ( ) ;
647
688
}
0 commit comments