@@ -376,16 +376,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
376
376
}
377
377
}
378
378
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 < ' _ > {
381
385
let mut err = struct_span_code_err ! (
382
386
self . dcx( ) ,
383
387
rcvr_expr. span,
384
388
E0599 ,
385
389
"cannot write into `{}`" ,
386
- self . tcx. short_string( rcvr_ty, & mut file ) ,
390
+ self . tcx. short_string( rcvr_ty, & mut long_ty_path ) ,
387
391
) ;
388
- * err. long_ty_path ( ) = file ;
392
+ * err. long_ty_path ( ) = long_ty_path ;
389
393
err. span_note (
390
394
rcvr_expr. span ,
391
395
"must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method" ,
@@ -403,7 +407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
403
407
& self ,
404
408
self_source : SelfSource < ' tcx > ,
405
409
method_name : Ident ,
406
- ty_str_reported : & str ,
410
+ ty : Ty < ' tcx > ,
407
411
err : & mut Diag < ' _ > ,
408
412
) {
409
413
#[ derive( Debug ) ]
@@ -478,7 +482,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
478
482
}
479
483
480
484
// 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.
482
486
// For example like: `let mut x = Vec::new();`,
483
487
// `Vec::new()` is the itializer expression.
484
488
if let Some ( self_ty) = self . fcx . node_ty_opt ( binding. init_hir_id )
@@ -566,17 +570,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
566
570
let mut span = MultiSpan :: from_span ( sugg_let. span ) ;
567
571
span. push_span_label ( sugg_let. span ,
568
572
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 ( ) ) ;
569
575
span. push_span_label (
570
576
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}`" ) ,
574
578
) ;
575
579
err. span_note (
576
580
span,
577
581
format ! (
578
582
"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"
580
584
) ,
581
585
) ;
582
586
}
@@ -602,15 +606,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
602
606
let tcx = self . tcx ;
603
607
let rcvr_ty = self . resolve_vars_if_possible ( rcvr_ty) ;
604
608
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
- } ;
614
609
let is_method = mode == Mode :: MethodCall ;
615
610
let unsatisfied_predicates = & no_match_data. unsatisfied_predicates ;
616
611
let similar_candidate = no_match_data. similar_candidate ;
@@ -629,15 +624,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
629
624
630
625
// We could pass the file for long types into these two, but it isn't strictly necessary
631
626
// 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
+ {
641
630
return guar;
642
631
}
643
632
if let Err ( guar) = self . report_failed_method_call_on_numerical_infer_var (
@@ -647,44 +636,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
647
636
span,
648
637
item_kind,
649
638
item_ident,
650
- & short_ty_str,
651
639
& mut ty_file,
652
640
) {
653
641
return guar;
654
642
}
655
643
span = item_ident. span ;
656
644
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
-
681
645
let is_write = sugg_span. ctxt ( ) . outer_expn_data ( ) . macro_def_id . is_some_and ( |def_id| {
682
646
tcx. is_diagnostic_item ( sym:: write_macro, def_id)
683
647
|| tcx. is_diagnostic_item ( sym:: writeln_macro, def_id)
684
648
} ) && item_ident. name == sym:: write_fmt;
685
649
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 )
687
651
} 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
+
688
675
let mut err = self . dcx ( ) . create_err ( NoAssociatedItem {
689
676
span,
690
677
item_kind,
@@ -695,16 +682,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695
682
} else {
696
683
rcvr_ty. prefix_string ( self . tcx )
697
684
} ,
698
- ty_str : ty_str_reported . clone ( ) ,
685
+ ty ,
699
686
trait_missing_method,
700
687
} ) ;
701
688
702
689
if is_method {
703
690
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,
708
692
) ;
709
693
}
710
694
@@ -734,6 +718,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
734
718
735
719
err
736
720
} ;
721
+
737
722
if tcx. sess . source_map ( ) . is_multiline ( sugg_span) {
738
723
err. span_label ( sugg_span. with_hi ( span. lo ( ) ) , "" ) ;
739
724
}
@@ -750,6 +735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
750
735
}
751
736
752
737
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 ( ) ) ;
753
739
err. help ( format ! (
754
740
"method `poll` found on `Pin<&mut {ty_str}>`, \
755
741
see documentation for `std::pin::Pin`"
@@ -1339,14 +1325,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1339
1325
}
1340
1326
let OnUnimplementedNote { message, label, notes, .. } = self
1341
1327
. err_ctxt ( )
1342
- . on_unimplemented_note ( trait_ref, & obligation, & mut ty_file ) ;
1328
+ . on_unimplemented_note ( trait_ref, & obligation, err . long_ty_path ( ) ) ;
1343
1329
( message, label, notes)
1344
1330
} )
1345
1331
. unwrap ( )
1346
1332
} else {
1347
1333
( None , None , Vec :: new ( ) )
1348
1334
} ;
1349
1335
let primary_message = primary_message. unwrap_or_else ( || {
1336
+ let ty_str = self . tcx . short_string ( rcvr_ty, err. long_ty_path ( ) ) ;
1350
1337
format ! (
1351
1338
"the {item_kind} `{item_ident}` exists for {actual_prefix} `{ty_str}`, \
1352
1339
but its trait bounds were not satisfied"
@@ -1409,6 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1409
1396
let mut find_candidate_for_method = false ;
1410
1397
1411
1398
let mut label_span_not_found = |err : & mut Diag < ' _ > | {
1399
+ let ty_str = self . tcx . short_string ( rcvr_ty, err. long_ty_path ( ) ) ;
1412
1400
if unsatisfied_predicates. is_empty ( ) {
1413
1401
err. span_label ( span, format ! ( "{item_kind} not found in `{ty_str}`" ) ) ;
1414
1402
let is_string_or_ref_str = match rcvr_ty. kind ( ) {
@@ -2520,8 +2508,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2520
2508
source : SelfSource < ' tcx > ,
2521
2509
span : Span ,
2522
2510
item_name : Ident ,
2523
- ty_str : & str ,
2524
- long_ty_path : & mut Option < PathBuf > ,
2525
2511
) -> Result < ( ) , ErrorGuaranteed > {
2526
2512
if let SelfSource :: MethodCall ( expr) = source {
2527
2513
for ( _, parent) in tcx. hir_parent_iter ( expr. hir_id ) . take ( 5 ) {
@@ -2583,18 +2569,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2583
2569
) ;
2584
2570
if pick. is_ok ( ) {
2585
2571
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 {
2587
2573
span,
2588
- ty_str : ty_str . to_string ( ) ,
2574
+ ty : actual ,
2589
2575
method_name : item_name. as_str ( ) . to_string ( ) ,
2590
2576
add_missing_parentheses : Some ( errors:: AddMissingParenthesesInRange {
2591
2577
func_name : item_name. name . as_str ( ) . to_string ( ) ,
2592
2578
left : range_span. shrink_to_lo ( ) ,
2593
2579
right : range_span. shrink_to_hi ( ) ,
2594
2580
} ) ,
2595
- } ) ;
2596
- * err. long_ty_path ( ) = long_ty_path. take ( ) ;
2597
- return Err ( err. emit ( ) ) ;
2581
+ } ) ) ;
2598
2582
}
2599
2583
}
2600
2584
}
@@ -2610,7 +2594,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2610
2594
span : Span ,
2611
2595
item_kind : & str ,
2612
2596
item_name : Ident ,
2613
- ty_str : & str ,
2614
2597
long_ty_path : & mut Option < PathBuf > ,
2615
2598
) -> Result < ( ) , ErrorGuaranteed > {
2616
2599
let found_candidate = all_traits ( self . tcx )
@@ -2643,14 +2626,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2643
2626
&& !actual. has_concrete_skeleton ( )
2644
2627
&& let SelfSource :: MethodCall ( expr) = source
2645
2628
{
2629
+ let ty_str = self . tcx . short_string ( actual, long_ty_path) ;
2646
2630
let mut err = struct_span_code_err ! (
2647
2631
self . dcx( ) ,
2648
2632
span,
2649
2633
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}`"
2654
2635
) ;
2655
2636
* err. long_ty_path ( ) = long_ty_path. take ( ) ;
2656
2637
let concrete_type = if actual. is_integral ( ) { "i32" } else { "f32" } ;
0 commit comments