@@ -376,16 +376,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
376376 }
377377 }
378378
379- fn suggest_missing_writer ( & self , rcvr_ty : Ty < ' tcx > , rcvr_expr : & hir:: Expr < ' tcx > ) -> Diag < ' _ > {
380- let mut file = None ;
379+ fn suggest_missing_writer (
380+ & self ,
381+ rcvr_ty : Ty < ' tcx > ,
382+ rcvr_expr : & hir:: Expr < ' tcx > ,
383+ mut long_ty_path : Option < PathBuf > ,
384+ ) -> Diag < ' _ > {
381385 let mut err = struct_span_code_err ! (
382386 self . dcx( ) ,
383387 rcvr_expr. span,
384388 E0599 ,
385389 "cannot write into `{}`" ,
386- self . tcx. short_string( rcvr_ty, & mut file ) ,
390+ self . tcx. short_string( rcvr_ty, & mut long_ty_path ) ,
387391 ) ;
388- * err. long_ty_path ( ) = file ;
392+ * err. long_ty_path ( ) = long_ty_path ;
389393 err. span_note (
390394 rcvr_expr. span ,
391395 "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method" ,
@@ -403,7 +407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
403407 & self ,
404408 self_source : SelfSource < ' tcx > ,
405409 method_name : Ident ,
406- ty_str_reported : & str ,
410+ ty : Ty < ' tcx > ,
407411 err : & mut Diag < ' _ > ,
408412 ) {
409413 #[ derive( Debug ) ]
@@ -478,7 +482,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
478482 }
479483
480484 // If the shadowed binding has an itializer expression,
481- // use the initializer expression'ty to try to find the method again.
485+ // use the initializer expression's ty to try to find the method again.
482486 // For example like: `let mut x = Vec::new();`,
483487 // `Vec::new()` is the itializer expression.
484488 if let Some ( self_ty) = self . fcx . node_ty_opt ( binding. init_hir_id )
@@ -566,17 +570,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
566570 let mut span = MultiSpan :: from_span ( sugg_let. span ) ;
567571 span. push_span_label ( sugg_let. span ,
568572 format ! ( "`{rcvr_name}` of type `{self_ty}` that has method `{method_name}` defined earlier here" ) ) ;
573+
574+ let ty = self . tcx . short_string ( ty, err. long_ty_path ( ) ) ;
569575 span. push_span_label (
570576 self . tcx . hir_span ( recv_id) ,
571- format ! (
572- "earlier `{rcvr_name}` shadowed here with type `{ty_str_reported}`"
573- ) ,
577+ format ! ( "earlier `{rcvr_name}` shadowed here with type `{ty}`" ) ,
574578 ) ;
575579 err. span_note (
576580 span,
577581 format ! (
578582 "there's an earlier shadowed binding `{rcvr_name}` of type `{self_ty}` \
579- that has method `{method_name}` available"
583+ that has method `{method_name}` available"
580584 ) ,
581585 ) ;
582586 }
@@ -602,15 +606,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
602606 let tcx = self . tcx ;
603607 let rcvr_ty = self . resolve_vars_if_possible ( rcvr_ty) ;
604608 let mut ty_file = None ;
605- let ( ty_str, short_ty_str) =
606- if trait_missing_method && let ty:: Dynamic ( predicates, _, _) = rcvr_ty. kind ( ) {
607- ( predicates. to_string ( ) , with_forced_trimmed_paths ! ( predicates. to_string( ) ) )
608- } else {
609- (
610- tcx. short_string ( rcvr_ty, & mut ty_file) ,
611- with_forced_trimmed_paths ! ( rcvr_ty. to_string( ) ) ,
612- )
613- } ;
614609 let is_method = mode == Mode :: MethodCall ;
615610 let unsatisfied_predicates = & no_match_data. unsatisfied_predicates ;
616611 let similar_candidate = no_match_data. similar_candidate ;
@@ -629,15 +624,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
629624
630625 // We could pass the file for long types into these two, but it isn't strictly necessary
631626 // given how targeted they are.
632- if let Err ( guar) = self . report_failed_method_call_on_range_end (
633- tcx,
634- rcvr_ty,
635- source,
636- span,
637- item_ident,
638- & short_ty_str,
639- & mut ty_file,
640- ) {
627+ if let Err ( guar) =
628+ self . report_failed_method_call_on_range_end ( tcx, rcvr_ty, source, span, item_ident)
629+ {
641630 return guar;
642631 }
643632 if let Err ( guar) = self . report_failed_method_call_on_numerical_infer_var (
@@ -647,44 +636,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
647636 span,
648637 item_kind,
649638 item_ident,
650- & short_ty_str,
651639 & mut ty_file,
652640 ) {
653641 return guar;
654642 }
655643 span = item_ident. span ;
656644
657- // Don't show generic arguments when the method can't be found in any implementation (#81576).
658- let mut ty_str_reported = ty_str. clone ( ) ;
659- if let ty:: Adt ( _, generics) = rcvr_ty. kind ( ) {
660- if generics. len ( ) > 0 {
661- let mut autoderef = self . autoderef ( span, rcvr_ty) . silence_errors ( ) ;
662- let candidate_found = autoderef. any ( |( ty, _) | {
663- if let ty:: Adt ( adt_def, _) = ty. kind ( ) {
664- self . tcx
665- . inherent_impls ( adt_def. did ( ) )
666- . into_iter ( )
667- . any ( |def_id| self . associated_value ( * def_id, item_ident) . is_some ( ) )
668- } else {
669- false
670- }
671- } ) ;
672- let has_deref = autoderef. step_count ( ) > 0 ;
673- if !candidate_found && !has_deref && unsatisfied_predicates. is_empty ( ) {
674- if let Some ( ( path_string, _) ) = ty_str. split_once ( '<' ) {
675- ty_str_reported = path_string. to_string ( ) ;
676- }
677- }
678- }
679- }
680-
681645 let is_write = sugg_span. ctxt ( ) . outer_expn_data ( ) . macro_def_id . is_some_and ( |def_id| {
682646 tcx. is_diagnostic_item ( sym:: write_macro, def_id)
683647 || tcx. is_diagnostic_item ( sym:: writeln_macro, def_id)
684648 } ) && item_ident. name == sym:: write_fmt;
685649 let mut err = if is_write && let SelfSource :: MethodCall ( rcvr_expr) = source {
686- self . suggest_missing_writer ( rcvr_ty, rcvr_expr)
650+ self . suggest_missing_writer ( rcvr_ty, rcvr_expr, ty_file )
687651 } else {
652+ // Don't show expanded generic arguments when the method can't be found in any
653+ // implementation (#81576).
654+ let mut ty = rcvr_ty;
655+ if let ty:: Adt ( def, generics) = rcvr_ty. kind ( ) {
656+ if generics. len ( ) > 0 {
657+ let mut autoderef = self . autoderef ( span, rcvr_ty) . silence_errors ( ) ;
658+ let candidate_found = autoderef. any ( |( ty, _) | {
659+ if let ty:: Adt ( adt_def, _) = ty. kind ( ) {
660+ self . tcx
661+ . inherent_impls ( adt_def. did ( ) )
662+ . into_iter ( )
663+ . any ( |def_id| self . associated_value ( * def_id, item_ident) . is_some ( ) )
664+ } else {
665+ false
666+ }
667+ } ) ;
668+ let has_deref = autoderef. step_count ( ) > 0 ;
669+ if !candidate_found && !has_deref && unsatisfied_predicates. is_empty ( ) {
670+ ty = self . tcx . at ( span) . type_of ( def. did ( ) ) . instantiate_identity ( ) ;
671+ }
672+ }
673+ }
674+
688675 let mut err = self . dcx ( ) . create_err ( NoAssociatedItem {
689676 span,
690677 item_kind,
@@ -695,16 +682,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695682 } else {
696683 rcvr_ty. prefix_string ( self . tcx )
697684 } ,
698- ty_str : ty_str_reported . clone ( ) ,
685+ ty ,
699686 trait_missing_method,
700687 } ) ;
701688
702689 if is_method {
703690 self . suggest_use_shadowed_binding_with_method (
704- source,
705- item_ident,
706- & ty_str_reported,
707- & mut err,
691+ source, item_ident, rcvr_ty, & mut err,
708692 ) ;
709693 }
710694
@@ -734,6 +718,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
734718
735719 err
736720 } ;
721+
737722 if tcx. sess . source_map ( ) . is_multiline ( sugg_span) {
738723 err. span_label ( sugg_span. with_hi ( span. lo ( ) ) , "" ) ;
739724 }
@@ -750,6 +735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
750735 }
751736
752737 if tcx. ty_is_opaque_future ( rcvr_ty) && item_ident. name == sym:: poll {
738+ let ty_str = self . tcx . short_string ( rcvr_ty, err. long_ty_path ( ) ) ;
753739 err. help ( format ! (
754740 "method `poll` found on `Pin<&mut {ty_str}>`, \
755741 see documentation for `std::pin::Pin`"
@@ -1339,14 +1325,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13391325 }
13401326 let OnUnimplementedNote { message, label, notes, .. } = self
13411327 . err_ctxt ( )
1342- . on_unimplemented_note ( trait_ref, & obligation, & mut ty_file ) ;
1328+ . on_unimplemented_note ( trait_ref, & obligation, err . long_ty_path ( ) ) ;
13431329 ( message, label, notes)
13441330 } )
13451331 . unwrap ( )
13461332 } else {
13471333 ( None , None , Vec :: new ( ) )
13481334 } ;
13491335 let primary_message = primary_message. unwrap_or_else ( || {
1336+ let ty_str = self . tcx . short_string ( rcvr_ty, err. long_ty_path ( ) ) ;
13501337 format ! (
13511338 "the {item_kind} `{item_ident}` exists for {actual_prefix} `{ty_str}`, \
13521339 but its trait bounds were not satisfied"
@@ -1409,6 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14091396 let mut find_candidate_for_method = false ;
14101397
14111398 let mut label_span_not_found = |err : & mut Diag < ' _ > | {
1399+ let ty_str = self . tcx . short_string ( rcvr_ty, err. long_ty_path ( ) ) ;
14121400 if unsatisfied_predicates. is_empty ( ) {
14131401 err. span_label ( span, format ! ( "{item_kind} not found in `{ty_str}`" ) ) ;
14141402 let is_string_or_ref_str = match rcvr_ty. kind ( ) {
@@ -2520,8 +2508,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25202508 source : SelfSource < ' tcx > ,
25212509 span : Span ,
25222510 item_name : Ident ,
2523- ty_str : & str ,
2524- long_ty_path : & mut Option < PathBuf > ,
25252511 ) -> Result < ( ) , ErrorGuaranteed > {
25262512 if let SelfSource :: MethodCall ( expr) = source {
25272513 for ( _, parent) in tcx. hir_parent_iter ( expr. hir_id ) . take ( 5 ) {
@@ -2583,18 +2569,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25832569 ) ;
25842570 if pick. is_ok ( ) {
25852571 let range_span = parent_expr. span . with_hi ( expr. span . hi ( ) ) ;
2586- let mut err = self . dcx ( ) . create_err ( errors:: MissingParenthesesInRange {
2572+ return Err ( self . dcx ( ) . emit_err ( errors:: MissingParenthesesInRange {
25872573 span,
2588- ty_str : ty_str . to_string ( ) ,
2574+ ty : actual ,
25892575 method_name : item_name. as_str ( ) . to_string ( ) ,
25902576 add_missing_parentheses : Some ( errors:: AddMissingParenthesesInRange {
25912577 func_name : item_name. name . as_str ( ) . to_string ( ) ,
25922578 left : range_span. shrink_to_lo ( ) ,
25932579 right : range_span. shrink_to_hi ( ) ,
25942580 } ) ,
2595- } ) ;
2596- * err. long_ty_path ( ) = long_ty_path. take ( ) ;
2597- return Err ( err. emit ( ) ) ;
2581+ } ) ) ;
25982582 }
25992583 }
26002584 }
@@ -2610,7 +2594,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26102594 span : Span ,
26112595 item_kind : & str ,
26122596 item_name : Ident ,
2613- ty_str : & str ,
26142597 long_ty_path : & mut Option < PathBuf > ,
26152598 ) -> Result < ( ) , ErrorGuaranteed > {
26162599 let found_candidate = all_traits ( self . tcx )
@@ -2643,14 +2626,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26432626 && !actual. has_concrete_skeleton ( )
26442627 && let SelfSource :: MethodCall ( expr) = source
26452628 {
2629+ let ty_str = self . tcx . short_string ( actual, long_ty_path) ;
26462630 let mut err = struct_span_code_err ! (
26472631 self . dcx( ) ,
26482632 span,
26492633 E0689 ,
2650- "can't call {} `{}` on ambiguous numeric type `{}`" ,
2651- item_kind,
2652- item_name,
2653- ty_str
2634+ "can't call {item_kind} `{item_name}` on ambiguous numeric type `{ty_str}`"
26542635 ) ;
26552636 * err. long_ty_path ( ) = long_ty_path. take ( ) ;
26562637 let concrete_type = if actual. is_integral ( ) { "i32" } else { "f32" } ;
0 commit comments