@@ -6,7 +6,7 @@ use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
66use rustc:: ty:: error:: { ExpectedFound , TypeError } ;
77use rustc:: ty:: subst:: { Subst , InternalSubsts , SubstsRef } ;
88use rustc:: util:: common:: ErrorReported ;
9- use errors:: Applicability ;
9+ use errors:: { Applicability , DiagnosticId } ;
1010
1111use syntax_pos:: Span ;
1212
@@ -576,55 +576,78 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
576576 Ok ( ( ) )
577577}
578578
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+ } ;
600607
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+ ) ;
607622
608- let mut suffix = None ;
623+ let mut suffix = None ;
609624
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+ }
621634
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+ ) ;
623641
624- return Err ( ErrorReported ) ;
642+ err. emit ( ) ;
643+ }
625644 }
626645
627- Ok ( ( ) )
646+ if err_occurred {
647+ Err ( ErrorReported )
648+ } else {
649+ Ok ( ( ) )
650+ }
628651}
629652
630653fn 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>,
725748 let trait_m_generics = tcx. generics_of ( trait_m. def_id ) ;
726749 let impl_m_type_params = impl_m_generics. params . iter ( ) . filter_map ( |param| match param. kind {
727750 GenericParamDefKind :: Type { synthetic, .. } => Some ( ( param. def_id , synthetic) ) ,
728- GenericParamDefKind :: Lifetime => None ,
751+ GenericParamDefKind :: Lifetime | GenericParamDefKind :: Const => None ,
729752 } ) ;
730753 let trait_m_type_params = trait_m_generics. params . iter ( ) . filter_map ( |param| {
731754 match param. kind {
732755 GenericParamDefKind :: Type { synthetic, .. } => Some ( ( param. def_id , synthetic) ) ,
733- GenericParamDefKind :: Lifetime => None ,
756+ GenericParamDefKind :: Lifetime | GenericParamDefKind :: Const => None ,
734757 }
735758 } ) ;
736759 for ( ( impl_def_id, impl_synthetic) , ( trait_def_id, trait_synthetic) )
0 commit comments