@@ -119,11 +119,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
119119 }
120120 } ;
121121
122- let note_str = format ! ( "candidate #{} is defined in an impl{} \
123- for the type `{}`",
124- idx + 1 ,
125- insertion,
126- impl_ty) ;
122+ let note_str = if sources. len ( ) > 1 {
123+ format ! ( "candidate #{} is defined in an impl{} for the type `{}`" ,
124+ idx + 1 ,
125+ insertion,
126+ impl_ty)
127+ } else {
128+ format ! ( "the candidate is defined in an impl{} for the type `{}`" ,
129+ insertion,
130+ impl_ty)
131+ } ;
127132 if let Some ( note_span) = note_span {
128133 // We have a span pointing to the method. Show note with snippet.
129134 err. span_note ( self . tcx . sess . codemap ( ) . def_span ( note_span) , & note_str) ;
@@ -137,11 +142,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
137142 . unwrap ( ) ;
138143 let item_span = self . tcx . sess . codemap ( )
139144 . def_span ( self . tcx . def_span ( item. def_id ) ) ;
140- span_note ! ( err,
141- item_span,
142- "candidate #{} is defined in the trait `{}`" ,
143- idx + 1 ,
144- self . tcx. item_path_str( trait_did) ) ;
145+ if sources. len ( ) > 1 {
146+ span_note ! ( err,
147+ item_span,
148+ "candidate #{} is defined in the trait `{}`" ,
149+ idx + 1 ,
150+ self . tcx. item_path_str( trait_did) ) ;
151+ } else {
152+ span_note ! ( err,
153+ item_span,
154+ "the candidate is defined in the trait `{}`" ,
155+ self . tcx. item_path_str( trait_did) ) ;
156+ }
145157 err. help ( & format ! ( "to disambiguate the method call, write `{}::{}({}{})` \
146158 instead",
147159 self . tcx. item_path_str( trait_did) ,
@@ -285,7 +297,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
285297 tcx. sess . diagnostic ( ) . struct_dummy ( )
286298 } ;
287299
288- if let Some ( def) = actual. ty_adt_def ( ) {
300+ if let Some ( def) = actual. ty_adt_def ( ) {
289301 if let Some ( full_sp) = tcx. hir . span_if_local ( def. did ) {
290302 let def_sp = tcx. sess . codemap ( ) . def_span ( full_sp) ;
291303 err. span_label ( def_sp, format ! ( "{} `{}` not found {}" ,
@@ -368,7 +380,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
368380 if !static_sources. is_empty ( ) {
369381 err. note ( "found the following associated functions; to be used as methods, \
370382 functions must have a `self` parameter") ;
371- err. help ( & format ! ( "try with `{}::{}`" , self . ty_to_string( actual) , item_name) ) ;
383+ err. span_label ( span, "this is an associated function, not a method" ) ;
384+ }
385+ if static_sources. len ( ) == 1 {
386+ if let Some ( expr) = rcvr_expr {
387+ err. span_suggestion ( expr. span . to ( span) ,
388+ "use associated function syntax instead" ,
389+ format ! ( "{}::{}" ,
390+ self . ty_to_string( actual) ,
391+ item_name) ) ;
392+ } else {
393+ err. help ( & format ! ( "try with `{}::{}`" ,
394+ self . ty_to_string( actual) , item_name) ) ;
395+ }
396+
397+ report_candidates ( & mut err, static_sources) ;
398+ } else if static_sources. len ( ) > 1 {
372399
373400 report_candidates ( & mut err, static_sources) ;
374401 }
@@ -468,9 +495,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
468495 } else {
469496 let limit = if candidates. len ( ) == 5 { 5 } else { 4 } ;
470497 for ( i, trait_did) in candidates. iter ( ) . take ( limit) . enumerate ( ) {
471- msg. push_str ( & format ! ( "\n candidate #{}: `use {};`" ,
472- i + 1 ,
473- self . tcx. item_path_str( * trait_did) ) ) ;
498+ if candidates. len ( ) > 1 {
499+ msg. push_str ( & format ! ( "\n candidate #{}: `use {};`" ,
500+ i + 1 ,
501+ self . tcx. item_path_str( * trait_did) ) ) ;
502+ } else {
503+ msg. push_str ( & format ! ( "\n `use {};`" ,
504+ self . tcx. item_path_str( * trait_did) ) ) ;
505+ }
474506 }
475507 if candidates. len ( ) > limit {
476508 msg. push_str ( & format ! ( "\n and {} others" , candidates. len( ) - limit) ) ;
0 commit comments