@@ -138,14 +138,70 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
138138 }
139139
140140 if impl_m. fty . sig . 0 . inputs . len ( ) != trait_m. fty . sig . 0 . inputs . len ( ) {
141- span_err ! ( tcx. sess, impl_m_span, E0050 ,
141+ let trait_number_args = trait_m. fty . sig . 0 . inputs . len ( ) ;
142+ let impl_number_args = impl_m. fty . sig . 0 . inputs . len ( ) ;
143+ let trait_m_node_id = tcx. map . as_local_node_id ( trait_m. def_id ) ;
144+ let trait_span = if let Some ( trait_id) = trait_m_node_id {
145+ match tcx. map . expect_trait_item ( trait_id) . node {
146+ TraitItem_ :: MethodTraitItem ( ref trait_m_sig, _) => {
147+ if let Some ( arg) = trait_m_sig. decl . inputs . get (
148+ if trait_number_args > 0 {
149+ trait_number_args - 1
150+ } else {
151+ 0
152+ } ) {
153+ Some ( arg. pat . span )
154+ } else {
155+ trait_item_span
156+ }
157+ }
158+ _ => bug ! ( "{:?} is not a method" , impl_m)
159+ }
160+ } else {
161+ trait_item_span
162+ } ;
163+ let impl_m_node_id = tcx. map . as_local_node_id ( impl_m. def_id ) . unwrap ( ) ;
164+ let impl_span = match tcx. map . expect_impl_item ( impl_m_node_id) . node {
165+ ImplItemKind :: Method ( ref impl_m_sig, _) => {
166+ if let Some ( arg) = impl_m_sig. decl . inputs . get (
167+ if impl_number_args > 0 {
168+ impl_number_args - 1
169+ } else {
170+ 0
171+ } ) {
172+ arg. pat . span
173+ } else {
174+ impl_m_span
175+ }
176+ }
177+ _ => bug ! ( "{:?} is not a method" , impl_m)
178+ } ;
179+ let mut err = struct_span_err ! ( tcx. sess, impl_span, E0050 ,
142180 "method `{}` has {} parameter{} \
143181 but the declaration in trait `{}` has {}",
144182 trait_m. name,
145- impl_m . fty . sig . 0 . inputs . len ( ) ,
146- if impl_m . fty . sig . 0 . inputs . len ( ) == 1 { "" } else { "s" } ,
183+ impl_number_args ,
184+ if impl_number_args == 1 { "" } else { "s" } ,
147185 tcx. item_path_str( trait_m. def_id) ,
148- trait_m. fty. sig. 0 . inputs. len( ) ) ;
186+ trait_number_args) ;
187+ if let Some ( trait_span) = trait_span {
188+ err. span_label ( trait_span,
189+ & format ! ( "trait requires {}" ,
190+ & if trait_number_args != 1 {
191+ format!( "{} parameters" , trait_number_args)
192+ } else {
193+ format!( "{} parameter" , trait_number_args)
194+ } ) ) ;
195+ }
196+ err. span_label ( impl_span,
197+ & format ! ( "expected {}, found {}" ,
198+ & if trait_number_args != 1 {
199+ format!( "{} parameters" , trait_number_args)
200+ } else {
201+ format!( "{} parameter" , trait_number_args)
202+ } ,
203+ impl_number_args) ) ;
204+ err. emit ( ) ;
149205 return ;
150206 }
151207
0 commit comments