22//! found or is otherwise invalid. 
33
44use  crate :: errors; 
5+ use  crate :: errors:: CandidateTraitNote ; 
6+ use  crate :: errors:: NoAssociatedItem ; 
57use  crate :: Expectation ; 
68use  crate :: FnCtxt ; 
79use  rustc_ast:: ast:: Mutability ; 
@@ -38,6 +40,7 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _
3840use  rustc_trait_selection:: traits:: { 
3941    FulfillmentError ,  Obligation ,  ObligationCause ,  ObligationCauseCode , 
4042} ; 
43+ use  std:: borrow:: Cow ; 
4144
4245use  super :: probe:: { AutorefOrPtrAdjustment ,  IsSuggestion ,  Mode ,  ProbeScope } ; 
4346use  super :: { CandidateSource ,  MethodError ,  NoMatchData } ; 
@@ -112,6 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
112115        error :  MethodError < ' tcx > , 
113116        args :  Option < ( & ' tcx  hir:: Expr < ' tcx > ,  & ' tcx  [ hir:: Expr < ' tcx > ] ) > , 
114117        expected :  Expectation < ' tcx > , 
118+         trait_missing_method :  bool , 
115119    )  -> Option < DiagnosticBuilder < ' _ ,  ErrorGuaranteed > >  { 
116120        // Avoid suggestions when we don't know what's going on. 
117121        if  rcvr_ty. references_error ( )  { 
@@ -136,6 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
136140                    sugg_span, 
137141                    & mut  no_match_data, 
138142                    expected, 
143+                     trait_missing_method, 
139144                ) ; 
140145            } 
141146
@@ -278,6 +283,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
278283        sugg_span :  Span , 
279284        no_match_data :  & mut  NoMatchData < ' tcx > , 
280285        expected :  Expectation < ' tcx > , 
286+         trait_missing_method :  bool , 
281287    )  -> Option < DiagnosticBuilder < ' _ ,  ErrorGuaranteed > >  { 
282288        let  mode = no_match_data. mode ; 
283289        let  tcx = self . tcx ; 
@@ -323,7 +329,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
323329        span = item_name. span ; 
324330
325331        // Don't show generic arguments when the method can't be found in any implementation (#81576). 
326-         let  mut  ty_str_reported = ty_str. clone ( ) ; 
332+         let  mut  ty_str_reported = if  trait_missing_method { 
333+             ty_str. strip_prefix ( "dyn " ) . expect ( "Failed to remove the prefix dyn" ) . to_owned ( ) 
334+         }  else  { 
335+             ty_str. clone ( ) 
336+         } ; 
337+ 
327338        if  let  ty:: Adt ( _,  generics)  = rcvr_ty. kind ( )  { 
328339            if  generics. len ( )  > 0  { 
329340                let  mut  autoderef = self . autoderef ( span,  rcvr_ty) ; 
@@ -355,25 +366,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
355366        { 
356367            self . suggest_missing_writer ( rcvr_ty,  args) 
357368        }  else  { 
358-             struct_span_err ! ( 
359-                 tcx. sess, 
369+             tcx. sess . create_err ( NoAssociatedItem  { 
360370                span, 
361-                 E0599 , 
362-                 "no {} named `{}` found for {} `{}` in the current scope" , 
363371                item_kind, 
364372                item_name, 
365-                 rcvr_ty. prefix_string( self . tcx) , 
366-                 ty_str_reported, 
367-             ) 
373+                 ty_prefix :  if  trait_missing_method { 
374+                     // FIXME(mu001999) E0599 maybe not suitable here because it is for types 
375+                     Cow :: from ( "trait" ) 
376+                 }  else  { 
377+                     rcvr_ty. prefix_string ( self . tcx ) 
378+                 } , 
379+                 ty_str :  ty_str_reported, 
380+                 trait_missing_method, 
381+             } ) 
368382        } ; 
369383        if  tcx. sess . source_map ( ) . is_multiline ( sugg_span)  { 
370384            err. span_label ( sugg_span. with_hi ( span. lo ( ) ) ,  "" ) ; 
371385        } 
372-         let  ty_str = if  short_ty_str. len ( )  < ty_str. len ( )  && ty_str. len ( )  > 10  { 
386+         let  mut   ty_str = if  short_ty_str. len ( )  < ty_str. len ( )  && ty_str. len ( )  > 10  { 
373387            short_ty_str
374388        }  else  { 
375389            ty_str
376390        } ; 
391+         if  trait_missing_method { 
392+             ty_str =
393+                 ty_str. strip_prefix ( "dyn " ) . expect ( "Failed to remove the prefix dyn" ) . to_owned ( ) ; 
394+         } 
395+ 
377396        if  let  Some ( file)  = ty_file { 
378397            err. note ( format ! ( "the full type name has been written to '{}'" ,  file. display( ) , ) ) ; 
379398        } 
@@ -1067,6 +1086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10671086                & static_candidates, 
10681087                unsatisfied_bounds, 
10691088                expected. only_has_type ( self ) , 
1089+                 trait_missing_method, 
10701090            ) ; 
10711091        } 
10721092
@@ -2375,6 +2395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23752395        static_candidates :  & [ CandidateSource ] , 
23762396        unsatisfied_bounds :  bool , 
23772397        return_type :  Option < Ty < ' tcx > > , 
2398+         trait_missing_method :  bool , 
23782399    )  { 
23792400        let  mut  alt_rcvr_sugg = false ; 
23802401        if  let  ( SelfSource :: MethodCall ( rcvr) ,  false )  = ( source,  unsatisfied_bounds)  { 
@@ -2598,11 +2619,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25982619                } , 
25992620                _ => None , 
26002621            } ; 
2601-             err. help ( if  param_type. is_some ( )  { 
2602-                 "items from traits can only be used if the type parameter is bounded by the trait" 
2603-             }  else  { 
2604-                 "items from traits can only be used if the trait is implemented and in scope" 
2605-             } ) ; 
2622+             if  !trait_missing_method { 
2623+                 err. help ( if  param_type. is_some ( )  { 
2624+                     "items from traits can only be used if the type parameter is bounded by the trait" 
2625+                 }  else  { 
2626+                     "items from traits can only be used if the trait is implemented and in scope" 
2627+                 } ) ; 
2628+             } 
2629+ 
26062630            let  candidates_len = candidates. len ( ) ; 
26072631            let  message = |action| { 
26082632                format ! ( 
@@ -2751,27 +2775,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27512775                ( candidates,  Vec :: new ( ) ) 
27522776            } ; 
27532777
2754-             let  action = if  let  Some ( param)  = param_type { 
2755-                 format ! ( "restrict type parameter `{}` with" ,  param) 
2756-             }  else  { 
2757-                 // FIXME: it might only need to be imported into scope, not implemented. 
2758-                 "implement" . to_string ( ) 
2759-             } ; 
27602778            match  & potential_candidates[ ..]  { 
27612779                [ ]  => { } 
27622780                [ trait_info]  if  trait_info. def_id . is_local ( )  => { 
2763-                     err. span_note ( 
2764-                         self . tcx . def_span ( trait_info. def_id ) , 
2765-                         format ! ( 
2766-                             "`{}` defines an item `{}`, perhaps you need to {} it" , 
2767-                             self . tcx. def_path_str( trait_info. def_id) , 
2768-                             item_name, 
2769-                             action
2770-                         ) , 
2771-                     ) ; 
2781+                     err. subdiagnostic ( CandidateTraitNote  { 
2782+                         span :  self . tcx . def_span ( trait_info. def_id ) , 
2783+                         trait_name :  self . tcx . def_path_str ( trait_info. def_id ) , 
2784+                         item_name, 
2785+                         action_or_ty :  if  trait_missing_method { 
2786+                             "NONE" . to_string ( ) 
2787+                         }  else  { 
2788+                             param_type. map_or_else ( 
2789+                                 || "implement" . to_string ( ) ,  // FIXME: it might only need to be imported into scope, not implemented. 
2790+                                 ToString :: to_string, 
2791+                             ) 
2792+                         } , 
2793+                     } ) ; 
27722794                } 
27732795                trait_infos => { 
2774-                     let  mut  msg = message ( action) ; 
2796+                     let  mut  msg = message ( param_type. map_or_else ( 
2797+                         || "implement" . to_string ( ) ,  // FIXME: it might only need to be imported into scope, not implemented. 
2798+                         |param| format ! ( "restrict type parameter `{}` with" ,  param) , 
2799+                     ) ) ; 
27752800                    for  ( i,  trait_info)  in  trait_infos. iter ( ) . enumerate ( )  { 
27762801                        msg. push_str ( & format ! ( 
27772802                            "\n candidate #{}: `{}`" , 
0 commit comments