@@ -406,7 +406,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
406
406
& self ,
407
407
self_source : SelfSource < ' tcx > ,
408
408
method_name : Ident ,
409
- ty_str_reported : & str ,
409
+ unsatisfied_predicates : & [ (
410
+ ty:: Predicate < ' tcx > ,
411
+ Option < ty:: Predicate < ' tcx > > ,
412
+ Option < ObligationCause < ' tcx > > ,
413
+ ) ] ,
414
+ ty : Ty < ' tcx > ,
410
415
err : & mut Diag < ' _ > ,
411
416
) {
412
417
#[ derive( Debug ) ]
@@ -569,17 +574,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
569
574
let mut span = MultiSpan :: from_span ( sugg_let. span ) ;
570
575
span. push_span_label ( sugg_let. span ,
571
576
format ! ( "`{rcvr_name}` of type `{self_ty}` that has method `{method_name}` defined earlier here" ) ) ;
577
+
578
+ // Don't show generic arguments when the method can't be found in any implementation (#81576).
579
+ let mut ty_str = None ;
580
+ if let ty:: Adt ( _, generics) = ty. kind ( ) {
581
+ if generics. len ( ) > 0 {
582
+ let mut autoderef = self . autoderef ( DUMMY_SP , ty) . silence_errors ( ) ;
583
+ let candidate_found = autoderef. any ( |( ty, _) | {
584
+ if let ty:: Adt ( adt_def, _) = ty. kind ( ) {
585
+ self . tcx . inherent_impls ( adt_def. did ( ) ) . into_iter ( ) . any (
586
+ |def_id| {
587
+ self . associated_value ( * def_id, method_name) . is_some ( )
588
+ } ,
589
+ )
590
+ } else {
591
+ false
592
+ }
593
+ } ) ;
594
+ let has_deref = autoderef. step_count ( ) > 0 ;
595
+ if !candidate_found && !has_deref && unsatisfied_predicates. is_empty ( ) {
596
+ let t = with_forced_trimmed_paths ! ( ty. to_string( ) ) ;
597
+ if let Some ( ( path_string, _) ) = t. split_once ( '<' ) {
598
+ ty_str = Some ( path_string. to_string ( ) ) ;
599
+ }
600
+ }
601
+ }
602
+ }
603
+
604
+ let ty =
605
+ ty_str. unwrap_or_else ( || self . tcx . short_string ( ty, err. long_ty_path ( ) ) ) ;
572
606
span. push_span_label (
573
607
self . tcx . hir_span ( recv_id) ,
574
- format ! (
575
- "earlier `{rcvr_name}` shadowed here with type `{ty_str_reported}`"
576
- ) ,
608
+ format ! ( "earlier `{rcvr_name}` shadowed here with type `{ty}`" ) ,
577
609
) ;
578
610
err. span_note (
579
611
span,
580
612
format ! (
581
613
"there's an earlier shadowed binding `{rcvr_name}` of type `{self_ty}` \
582
- that has method `{method_name}` available"
614
+ that has method `{method_name}` available"
583
615
) ,
584
616
) ;
585
617
}
@@ -605,15 +637,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
605
637
let tcx = self . tcx ;
606
638
let rcvr_ty = self . resolve_vars_if_possible ( rcvr_ty) ;
607
639
let mut ty_file = None ;
608
- let ( ty_str, short_ty_str) =
609
- if trait_missing_method && let ty:: Dynamic ( predicates, _, _) = rcvr_ty. kind ( ) {
610
- ( predicates. to_string ( ) , with_forced_trimmed_paths ! ( predicates. to_string( ) ) )
611
- } else {
612
- (
613
- tcx. short_string ( rcvr_ty, & mut ty_file) ,
614
- with_forced_trimmed_paths ! ( rcvr_ty. to_string( ) ) ,
615
- )
616
- } ;
617
640
let is_method = mode == Mode :: MethodCall ;
618
641
let unsatisfied_predicates = & no_match_data. unsatisfied_predicates ;
619
642
let similar_candidate = no_match_data. similar_candidate ;
@@ -632,15 +655,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
632
655
633
656
// We could pass the file for long types into these two, but it isn't strictly necessary
634
657
// given how targeted they are.
635
- if let Err ( guar) = self . report_failed_method_call_on_range_end (
636
- tcx,
637
- rcvr_ty,
638
- source,
639
- span,
640
- item_ident,
641
- & short_ty_str,
642
- & mut ty_file,
643
- ) {
658
+ if let Err ( guar) =
659
+ self . report_failed_method_call_on_range_end ( tcx, rcvr_ty, source, span, item_ident)
660
+ {
644
661
return guar;
645
662
}
646
663
if let Err ( guar) = self . report_failed_method_call_on_numerical_infer_var (
@@ -650,37 +667,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
650
667
span,
651
668
item_kind,
652
669
item_ident,
653
- & short_ty_str,
654
670
& mut ty_file,
655
671
) {
656
672
return guar;
657
673
}
658
674
span = item_ident. span ;
659
675
660
- // Don't show generic arguments when the method can't be found in any implementation (#81576).
661
- let mut ty_str_reported = ty_str. clone ( ) ;
662
- if let ty:: Adt ( _, generics) = rcvr_ty. kind ( ) {
663
- if generics. len ( ) > 0 {
664
- let mut autoderef = self . autoderef ( span, rcvr_ty) . silence_errors ( ) ;
665
- let candidate_found = autoderef. any ( |( ty, _) | {
666
- if let ty:: Adt ( adt_def, _) = ty. kind ( ) {
667
- self . tcx
668
- . inherent_impls ( adt_def. did ( ) )
669
- . into_iter ( )
670
- . any ( |def_id| self . associated_value ( * def_id, item_ident) . is_some ( ) )
671
- } else {
672
- false
673
- }
674
- } ) ;
675
- let has_deref = autoderef. step_count ( ) > 0 ;
676
- if !candidate_found && !has_deref && unsatisfied_predicates. is_empty ( ) {
677
- if let Some ( ( path_string, _) ) = ty_str. split_once ( '<' ) {
678
- ty_str_reported = path_string. to_string ( ) ;
679
- }
680
- }
681
- }
682
- }
683
-
684
676
let is_write = sugg_span. ctxt ( ) . outer_expn_data ( ) . macro_def_id . is_some_and ( |def_id| {
685
677
tcx. is_diagnostic_item ( sym:: write_macro, def_id)
686
678
|| tcx. is_diagnostic_item ( sym:: writeln_macro, def_id)
@@ -698,16 +690,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
698
690
} else {
699
691
rcvr_ty. prefix_string ( self . tcx )
700
692
} ,
701
- ty_str : ty_str_reported . clone ( ) ,
693
+ ty : rcvr_ty ,
702
694
trait_missing_method,
703
695
} ) ;
704
- * err. long_ty_path ( ) = ty_file;
705
696
706
697
if is_method {
707
698
self . suggest_use_shadowed_binding_with_method (
708
699
source,
709
700
item_ident,
710
- & ty_str_reported,
701
+ & unsatisfied_predicates,
702
+ rcvr_ty,
711
703
& mut err,
712
704
) ;
713
705
}
@@ -738,6 +730,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
738
730
739
731
err
740
732
} ;
733
+
741
734
if tcx. sess . source_map ( ) . is_multiline ( sugg_span) {
742
735
err. span_label ( sugg_span. with_hi ( span. lo ( ) ) , "" ) ;
743
736
}
@@ -754,6 +747,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
754
747
}
755
748
756
749
if tcx. ty_is_opaque_future ( rcvr_ty) && item_ident. name == sym:: poll {
750
+ let ty_str = self . tcx . short_string ( rcvr_ty, err. long_ty_path ( ) ) ;
757
751
err. help ( format ! (
758
752
"method `poll` found on `Pin<&mut {ty_str}>`, \
759
753
see documentation for `std::pin::Pin`"
@@ -1351,6 +1345,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1351
1345
( None , None , Vec :: new ( ) )
1352
1346
} ;
1353
1347
let primary_message = primary_message. unwrap_or_else ( || {
1348
+ let ty_str = self . tcx . short_string ( rcvr_ty, err. long_ty_path ( ) ) ;
1354
1349
format ! (
1355
1350
"the {item_kind} `{item_ident}` exists for {actual_prefix} `{ty_str}`, \
1356
1351
but its trait bounds were not satisfied"
@@ -1413,6 +1408,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1413
1408
let mut find_candidate_for_method = false ;
1414
1409
1415
1410
let mut label_span_not_found = |err : & mut Diag < ' _ > | {
1411
+ let ty_str = self . tcx . short_string ( rcvr_ty, err. long_ty_path ( ) ) ;
1416
1412
if unsatisfied_predicates. is_empty ( ) {
1417
1413
err. span_label ( span, format ! ( "{item_kind} not found in `{ty_str}`" ) ) ;
1418
1414
let is_string_or_ref_str = match rcvr_ty. kind ( ) {
@@ -2524,8 +2520,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2524
2520
source : SelfSource < ' tcx > ,
2525
2521
span : Span ,
2526
2522
item_name : Ident ,
2527
- ty_str : & str ,
2528
- long_ty_path : & mut Option < PathBuf > ,
2529
2523
) -> Result < ( ) , ErrorGuaranteed > {
2530
2524
if let SelfSource :: MethodCall ( expr) = source {
2531
2525
for ( _, parent) in tcx. hir_parent_iter ( expr. hir_id ) . take ( 5 ) {
@@ -2587,18 +2581,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2587
2581
) ;
2588
2582
if pick. is_ok ( ) {
2589
2583
let range_span = parent_expr. span . with_hi ( expr. span . hi ( ) ) ;
2590
- let mut err = self . dcx ( ) . create_err ( errors:: MissingParenthesesInRange {
2584
+ return Err ( self . dcx ( ) . emit_err ( errors:: MissingParenthesesInRange {
2591
2585
span,
2592
- ty_str : ty_str . to_string ( ) ,
2586
+ ty : actual ,
2593
2587
method_name : item_name. as_str ( ) . to_string ( ) ,
2594
2588
add_missing_parentheses : Some ( errors:: AddMissingParenthesesInRange {
2595
2589
func_name : item_name. name . as_str ( ) . to_string ( ) ,
2596
2590
left : range_span. shrink_to_lo ( ) ,
2597
2591
right : range_span. shrink_to_hi ( ) ,
2598
2592
} ) ,
2599
- } ) ;
2600
- * err. long_ty_path ( ) = long_ty_path. take ( ) ;
2601
- return Err ( err. emit ( ) ) ;
2593
+ } ) ) ;
2602
2594
}
2603
2595
}
2604
2596
}
@@ -2614,7 +2606,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2614
2606
span : Span ,
2615
2607
item_kind : & str ,
2616
2608
item_name : Ident ,
2617
- ty_str : & str ,
2618
2609
long_ty_path : & mut Option < PathBuf > ,
2619
2610
) -> Result < ( ) , ErrorGuaranteed > {
2620
2611
let found_candidate = all_traits ( self . tcx )
@@ -2647,14 +2638,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2647
2638
&& !actual. has_concrete_skeleton ( )
2648
2639
&& let SelfSource :: MethodCall ( expr) = source
2649
2640
{
2641
+ let ty_str = self . tcx . short_string ( actual, long_ty_path) ;
2650
2642
let mut err = struct_span_code_err ! (
2651
2643
self . dcx( ) ,
2652
2644
span,
2653
2645
E0689 ,
2654
- "can't call {} `{}` on ambiguous numeric type `{}`" ,
2655
- item_kind,
2656
- item_name,
2657
- ty_str
2646
+ "can't call {item_kind} `{item_name}` on ambiguous numeric type `{ty_str}`"
2658
2647
) ;
2659
2648
* err. long_ty_path ( ) = long_ty_path. take ( ) ;
2660
2649
let concrete_type = if actual. is_integral ( ) { "i32" } else { "f32" } ;
0 commit comments