@@ -6,7 +6,7 @@ use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
6
6
use rustc:: ty:: error:: { ExpectedFound , TypeError } ;
7
7
use rustc:: ty:: subst:: { Subst , InternalSubsts , SubstsRef } ;
8
8
use rustc:: util:: common:: ErrorReported ;
9
- use errors:: Applicability ;
9
+ use errors:: { Applicability , DiagnosticId } ;
10
10
11
11
use syntax_pos:: Span ;
12
12
@@ -576,55 +576,78 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
576
576
Ok ( ( ) )
577
577
}
578
578
579
- fn compare_number_of_generics < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
580
- impl_m : & ty:: AssociatedItem ,
581
- impl_m_span : Span ,
582
- trait_m : & ty:: AssociatedItem ,
583
- trait_item_span : Option < Span > )
584
- -> Result < ( ) , ErrorReported > {
585
- let impl_m_generics = tcx. generics_of ( impl_m. def_id ) ;
586
- let trait_m_generics = tcx. generics_of ( trait_m. def_id ) ;
587
- let num_impl_m_type_params = impl_m_generics. own_counts ( ) . types ;
588
- let num_trait_m_type_params = trait_m_generics. own_counts ( ) . types ;
589
-
590
- if num_impl_m_type_params != num_trait_m_type_params {
591
- let impl_m_node_id = tcx. hir ( ) . as_local_node_id ( impl_m. def_id ) . unwrap ( ) ;
592
- let impl_m_item = tcx. hir ( ) . expect_impl_item ( impl_m_node_id) ;
593
- let span = if impl_m_item. generics . params . is_empty ( )
594
- || impl_m_item. generics . span . is_dummy ( ) // impl Trait in argument position (#55374)
595
- {
596
- impl_m_span
597
- } else {
598
- impl_m_item. generics . span
599
- } ;
579
+ fn compare_number_of_generics < ' a , ' tcx > (
580
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
581
+ impl_ : & ty:: AssociatedItem ,
582
+ impl_span : Span ,
583
+ trait_ : & ty:: AssociatedItem ,
584
+ trait_span : Option < Span > ,
585
+ ) -> Result < ( ) , ErrorReported > {
586
+ let trait_own_counts = tcx. generics_of ( trait_. def_id ) . own_counts ( ) ;
587
+ let impl_own_counts = tcx. generics_of ( impl_. def_id ) . own_counts ( ) ;
588
+
589
+ let matchings = [
590
+ ( "type" , trait_own_counts. types , impl_own_counts. types ) ,
591
+ ( "const" , trait_own_counts. consts , impl_own_counts. consts ) ,
592
+ ] ;
593
+
594
+ let mut err_occurred = false ;
595
+ for & ( kind, trait_count, impl_count) in & matchings {
596
+ if impl_count != trait_count {
597
+ err_occurred = true ;
598
+
599
+ let impl_node_id = tcx. hir ( ) . as_local_node_id ( impl_. def_id ) . unwrap ( ) ;
600
+ let impl_item = tcx. hir ( ) . expect_impl_item ( impl_node_id) ;
601
+ let span = if impl_item. generics . params . is_empty ( )
602
+ || impl_item. generics . span . is_dummy ( ) { // argument position impl Trait (#55374)
603
+ impl_span
604
+ } else {
605
+ impl_item. generics . span
606
+ } ;
600
607
601
- let mut err = struct_span_err ! ( tcx. sess, span, E0049 ,
602
- "method `{}` has {} but its trait declaration has {}" ,
603
- trait_m. ident,
604
- potentially_plural_count( num_impl_m_type_params, "type parameter" ) ,
605
- potentially_plural_count( num_trait_m_type_params, "type parameter" )
606
- ) ;
608
+ let mut err = tcx. sess . struct_span_err_with_code (
609
+ span,
610
+ & format ! (
611
+ "method `{}` has {} {kind} parameter{} but its trait \
612
+ declaration has {} {kind} parameter{}",
613
+ trait_. ident,
614
+ impl_count,
615
+ if impl_count != 1 { "s" } else { "" } ,
616
+ trait_count,
617
+ if trait_count != 1 { "s" } else { "" } ,
618
+ kind = kind,
619
+ ) ,
620
+ DiagnosticId :: Error ( "E0049" . into ( ) ) ,
621
+ ) ;
607
622
608
- let mut suffix = None ;
623
+ let mut suffix = None ;
609
624
610
- if let Some ( span) = trait_item_span {
611
- err. span_label ( span, format ! ( "expected {}" ,
612
- potentially_plural_count( num_trait_m_type_params, "type parameter" ) ) ) ;
613
- } else {
614
- suffix = Some ( format ! ( ", expected {}" , num_trait_m_type_params) ) ;
615
- }
616
-
617
- err. span_label ( span,
618
- format ! ( "found {}{}" ,
619
- potentially_plural_count( num_impl_m_type_params, "type parameter" ) ,
620
- suffix. as_ref( ) . map( |s| & s[ ..] ) . unwrap_or( "" ) ) ) ;
625
+ if let Some ( span) = trait_span {
626
+ err. span_label (
627
+ span,
628
+ format ! ( "expected {} {} parameter{}" , trait_count, kind,
629
+ if trait_count != 1 { "s" } else { "" } )
630
+ ) ;
631
+ } else {
632
+ suffix = Some ( format ! ( ", expected {}" , trait_count) ) ;
633
+ }
621
634
622
- err. emit ( ) ;
635
+ err. span_label (
636
+ span,
637
+ format ! ( "found {} {} parameter{}{}" , impl_count, kind,
638
+ if impl_count != 1 { "s" } else { "" } ,
639
+ suffix. unwrap_or_else( || String :: new( ) ) ) ,
640
+ ) ;
623
641
624
- return Err ( ErrorReported ) ;
642
+ err. emit ( ) ;
643
+ }
625
644
}
626
645
627
- Ok ( ( ) )
646
+ if err_occurred {
647
+ Err ( ErrorReported )
648
+ } else {
649
+ Ok ( ( ) )
650
+ }
628
651
}
629
652
630
653
fn compare_number_of_method_arguments < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
@@ -725,12 +748,12 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
725
748
let trait_m_generics = tcx. generics_of ( trait_m. def_id ) ;
726
749
let impl_m_type_params = impl_m_generics. params . iter ( ) . filter_map ( |param| match param. kind {
727
750
GenericParamDefKind :: Type { synthetic, .. } => Some ( ( param. def_id , synthetic) ) ,
728
- GenericParamDefKind :: Lifetime => None ,
751
+ GenericParamDefKind :: Lifetime | GenericParamDefKind :: Const => None ,
729
752
} ) ;
730
753
let trait_m_type_params = trait_m_generics. params . iter ( ) . filter_map ( |param| {
731
754
match param. kind {
732
755
GenericParamDefKind :: Type { synthetic, .. } => Some ( ( param. def_id , synthetic) ) ,
733
- GenericParamDefKind :: Lifetime => None ,
756
+ GenericParamDefKind :: Lifetime | GenericParamDefKind :: Const => None ,
734
757
}
735
758
} ) ;
736
759
for ( ( impl_def_id, impl_synthetic) , ( trait_def_id, trait_synthetic) )
0 commit comments