@@ -385,7 +385,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
385385 // the moment, give a kind of vague error message.
386386 if trait_params != impl_params {
387387 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) ;
389389 let mut err = struct_span_err ! (
390390 tcx. sess,
391391 span,
@@ -396,7 +396,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
396396 err. span_label ( span, "lifetimes do not match method in trait" ) ;
397397 if let Some ( sp) = tcx. hir ( ) . span_if_local ( trait_m. def_id ) {
398398 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) ;
400400 err. span_label ( sp, "lifetimes in impl do not match this method in trait" ) ;
401401 }
402402 err. emit ( ) ;
@@ -583,7 +583,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
583583fn compare_number_of_generics < ' a , ' tcx > (
584584 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
585585 impl_ : & ty:: AssocItem ,
586- impl_span : Span ,
586+ _impl_span : Span ,
587587 trait_ : & ty:: AssocItem ,
588588 trait_span : Option < Span > ,
589589) -> Result < ( ) , ErrorReported > {
@@ -600,17 +600,44 @@ fn compare_number_of_generics<'a, 'tcx>(
600600 if impl_count != trait_count {
601601 err_occurred = true ;
602602
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+ }
608623 } else {
609- impl_item . generics . span
624+ ( trait_span . map ( |s| vec ! [ s ] ) , vec ! [ ] )
610625 } ;
611626
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+
612639 let mut err = tcx. sess . struct_span_err_with_code (
613- span ,
640+ spans ,
614641 & format ! (
615642 "method `{}` has {} {kind} parameter{} but its trait \
616643 declaration has {} {kind} parameter{}",
@@ -626,22 +653,36 @@ fn compare_number_of_generics<'a, 'tcx>(
626653
627654 let mut suffix = None ;
628655
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+ }
635669 } else {
636670 suffix = Some ( format ! ( ", expected {}" , trait_count) ) ;
637671 }
638672
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,
642678 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+ }
645686
646687 err. emit ( ) ;
647688 }
0 commit comments