@@ -138,14 +138,70 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
138
138
}
139
139
140
140
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 ,
142
180
"method `{}` has {} parameter{} \
143
181
but the declaration in trait `{}` has {}",
144
182
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" } ,
147
185
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 ( ) ;
149
205
return ;
150
206
}
151
207
0 commit comments