@@ -148,14 +148,70 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
148148 }
149149
150150 if impl_m. fty . sig . 0 . inputs . len ( ) != trait_m. fty . sig . 0 . inputs . len ( ) {
151- span_err ! ( tcx. sess, impl_m_span, E0050 ,
151+ let trait_number_args = trait_m. fty . sig . 0 . inputs . len ( ) ;
152+ let impl_number_args = impl_m. fty . sig . 0 . inputs . len ( ) ;
153+ let trait_m_node_id = tcx. map . as_local_node_id ( trait_m. def_id ) ;
154+ let trait_span = if let Some ( trait_id) = trait_m_node_id {
155+ match tcx. map . expect_trait_item ( trait_id) . node {
156+ TraitItem_ :: MethodTraitItem ( ref trait_m_sig, _) => {
157+ if let Some ( arg) = trait_m_sig. decl . inputs . get (
158+ if trait_number_args > 0 {
159+ trait_number_args - 1
160+ } else {
161+ 0
162+ } ) {
163+ Some ( arg. pat . span )
164+ } else {
165+ trait_item_span
166+ }
167+ }
168+ _ => bug ! ( "{:?} is not a method" , impl_m)
169+ }
170+ } else {
171+ trait_item_span
172+ } ;
173+ let impl_m_node_id = tcx. map . as_local_node_id ( impl_m. def_id ) . unwrap ( ) ;
174+ let impl_span = match tcx. map . expect_impl_item ( impl_m_node_id) . node {
175+ ImplItemKind :: Method ( ref impl_m_sig, _) => {
176+ if let Some ( arg) = impl_m_sig. decl . inputs . get (
177+ if impl_number_args > 0 {
178+ impl_number_args - 1
179+ } else {
180+ 0
181+ } ) {
182+ arg. pat . span
183+ } else {
184+ impl_m_span
185+ }
186+ }
187+ _ => bug ! ( "{:?} is not a method" , impl_m)
188+ } ;
189+ let mut err = struct_span_err ! ( tcx. sess, impl_span, E0050 ,
152190 "method `{}` has {} parameter{} \
153191 but the declaration in trait `{}` has {}",
154192 trait_m. name,
155- impl_m . fty . sig . 0 . inputs . len ( ) ,
156- if impl_m . fty . sig . 0 . inputs . len ( ) == 1 { "" } else { "s" } ,
193+ impl_number_args ,
194+ if impl_number_args == 1 { "" } else { "s" } ,
157195 tcx. item_path_str( trait_m. def_id) ,
158- trait_m. fty. sig. 0 . inputs. len( ) ) ;
196+ trait_number_args) ;
197+ if let Some ( trait_span) = trait_span {
198+ err. span_label ( trait_span,
199+ & format ! ( "trait requires {}" ,
200+ & if trait_number_args != 1 {
201+ format!( "{} parameters" , trait_number_args)
202+ } else {
203+ format!( "{} parameter" , trait_number_args)
204+ } ) ) ;
205+ }
206+ err. span_label ( impl_span,
207+ & format ! ( "expected {}, found {}" ,
208+ & if trait_number_args != 1 {
209+ format!( "{} parameters" , trait_number_args)
210+ } else {
211+ format!( "{} parameter" , trait_number_args)
212+ } ,
213+ impl_number_args) ) ;
214+ err. emit ( ) ;
159215 return ;
160216 }
161217
0 commit comments