@@ -175,8 +175,9 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
175175 let code = source. error_code ( res. is_some ( ) ) ;
176176 let mut err = self . r . session . struct_span_err_with_code ( base_span, & base_msg, code) ;
177177
178+ let is_assoc_fn = self . self_type_is_available ( span) ;
178179 // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
179- if [ "this" , "my" ] . contains ( & & * item_str. as_str ( ) ) && self . self_type_is_available ( span ) {
180+ if [ "this" , "my" ] . contains ( & & * item_str. as_str ( ) ) && is_assoc_fn {
180181 err. span_suggestion_short (
181182 span,
182183 "you might have meant to use `self` here instead" ,
@@ -187,25 +188,24 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
187188 if let Some ( ( FnKind :: Fn ( _, _, sig, ..) , fn_span) ) =
188189 & self . diagnostic_metadata . current_function
189190 {
190- if let Some ( param) = sig. decl . inputs . get ( 0 ) {
191- err. span_suggestion_verbose (
192- param. span . shrink_to_lo ( ) ,
193- "you are also missing a `self` receiver argument" ,
194- "&self, " . to_string ( ) ,
195- Applicability :: MaybeIncorrect ,
196- ) ;
191+ let ( span, sugg) = if let Some ( param) = sig. decl . inputs . get ( 0 ) {
192+ ( param. span . shrink_to_lo ( ) , "&self, " )
197193 } else {
198- err . span_suggestion_verbose (
194+ (
199195 self . r
200196 . session
201197 . source_map ( )
202198 . span_through_char ( * fn_span, '(' )
203199 . shrink_to_hi ( ) ,
204- "you are also missing a `self` receiver argument" ,
205- "&self" . to_string ( ) ,
206- Applicability :: MaybeIncorrect ,
207- ) ;
208- }
200+ "&self" ,
201+ )
202+ } ;
203+ err. span_suggestion_verbose (
204+ span,
205+ "you are also missing a `self` receiver argument" ,
206+ sugg. to_string ( ) ,
207+ Applicability :: MaybeIncorrect ,
208+ ) ;
209209 }
210210 }
211211 }
@@ -236,7 +236,38 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
236236 if fn_kind. decl ( ) . inputs . get ( 0 ) . map ( |p| p. is_self ( ) ) . unwrap_or ( false ) {
237237 err. span_label ( * span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters" ) ;
238238 } else {
239- err. span_label ( * span, "this function doesn't have a `self` parameter" ) ;
239+ let doesnt = if is_assoc_fn {
240+ let ( span, sugg) = fn_kind
241+ . decl ( )
242+ . inputs
243+ . get ( 0 )
244+ . map ( |p| ( p. span . shrink_to_lo ( ) , "&self, " ) )
245+ . unwrap_or_else ( || {
246+ (
247+ self . r
248+ . session
249+ . source_map ( )
250+ . span_through_char ( * span, '(' )
251+ . shrink_to_hi ( ) ,
252+ "&self" ,
253+ )
254+ } ) ;
255+ err. span_suggestion_verbose (
256+ span,
257+ "add a `self` receiver parameter to make the associated `fn` a method" ,
258+ sugg. to_string ( ) ,
259+ Applicability :: MaybeIncorrect ,
260+ ) ;
261+ "doesn't"
262+ } else {
263+ "can't"
264+ } ;
265+ if let Some ( ident) = fn_kind. ident ( ) {
266+ err. span_label (
267+ ident. span ,
268+ & format ! ( "this function {} have a `self` parameter" , doesnt) ,
269+ ) ;
270+ }
240271 }
241272 }
242273 return ( err, Vec :: new ( ) ) ;
0 commit comments