@@ -80,6 +80,7 @@ use rustc_middle::ty::{
80
80
use rustc_span:: { sym, symbol:: kw, BytePos , DesugaringKind , Pos , Span } ;
81
81
use rustc_target:: spec:: abi;
82
82
use std:: ops:: { ControlFlow , Deref } ;
83
+ use std:: path:: PathBuf ;
83
84
use std:: { cmp, fmt, iter} ;
84
85
85
86
mod note;
@@ -1352,10 +1353,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1352
1353
. map ( |( mod_str, _) | mod_str. len ( ) + separator_len)
1353
1354
. sum ( ) ;
1354
1355
1355
- debug ! (
1356
- "cmp: separator_len={}, split_idx={}, min_len={}" ,
1357
- separator_len, split_idx, min_len
1358
- ) ;
1356
+ debug ! ( ?separator_len, ?split_idx, ?min_len, "cmp" ) ;
1359
1357
1360
1358
if split_idx >= min_len {
1361
1359
// paths are identical, highlight everything
@@ -1366,7 +1364,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1366
1364
} else {
1367
1365
let ( common, uniq1) = t1_str. split_at ( split_idx) ;
1368
1366
let ( _, uniq2) = t2_str. split_at ( split_idx) ;
1369
- debug ! ( "cmp: common={}, uniq1={}, uniq2={}" , common , uniq1 , uniq2 ) ;
1367
+ debug ! ( ? common, ? uniq1, ? uniq2, "cmp" ) ;
1370
1368
1371
1369
values. 0 . push_normal ( common) ;
1372
1370
values. 0 . push_highlighted ( uniq1) ;
@@ -1659,17 +1657,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1659
1657
}
1660
1658
ValuePairs :: Regions ( _) => ( false , Mismatch :: Fixed ( "lifetime" ) ) ,
1661
1659
} ;
1662
- let vals = match self . values_str ( values) {
1663
- Some ( ( expected, found) ) => Some ( ( expected, found) ) ,
1664
- None => {
1665
- // Derived error. Cancel the emitter.
1666
- // NOTE(eddyb) this was `.cancel()`, but `diag`
1667
- // is borrowed, so we can't fully defuse it.
1668
- diag. downgrade_to_delayed_bug ( ) ;
1669
- return ;
1670
- }
1660
+ let Some ( vals) = self . values_str ( values) else {
1661
+ // Derived error. Cancel the emitter.
1662
+ // NOTE(eddyb) this was `.cancel()`, but `diag`
1663
+ // is borrowed, so we can't fully defuse it.
1664
+ diag. downgrade_to_delayed_bug ( ) ;
1665
+ return ;
1671
1666
} ;
1672
- ( vals, exp_found, is_simple_error, Some ( values) )
1667
+ ( Some ( vals) , exp_found, is_simple_error, Some ( values) )
1673
1668
}
1674
1669
} ;
1675
1670
@@ -1701,7 +1696,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1701
1696
label_or_note ( span, & terr. to_string ( ) ) ;
1702
1697
}
1703
1698
1704
- if let Some ( ( expected, found) ) = expected_found {
1699
+ if let Some ( ( expected, found, exp_p , found_p ) ) = expected_found {
1705
1700
let ( expected_label, found_label, exp_found) = match exp_found {
1706
1701
Mismatch :: Variable ( ef) => (
1707
1702
ef. expected . prefix_string ( self . tcx ) ,
@@ -1818,32 +1813,41 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1818
1813
}
1819
1814
TypeError :: Sorts ( values) => {
1820
1815
let extra = expected == found;
1821
- let sort_string = |ty : Ty < ' tcx > | match ( extra, ty. kind ( ) ) {
1822
- ( true , ty:: Opaque ( def_id, _) ) => {
1823
- let sm = self . tcx . sess . source_map ( ) ;
1824
- let pos = sm. lookup_char_pos ( self . tcx . def_span ( * def_id) . lo ( ) ) ;
1825
- format ! (
1826
- " (opaque type at <{}:{}:{}>)" ,
1827
- sm. filename_for_diagnostics( & pos. file. name) ,
1828
- pos. line,
1829
- pos. col. to_usize( ) + 1 ,
1830
- )
1831
- }
1832
- ( true , ty:: Projection ( proj) )
1833
- if self . tcx . def_kind ( proj. item_def_id )
1834
- == DefKind :: ImplTraitPlaceholder =>
1835
- {
1836
- let sm = self . tcx . sess . source_map ( ) ;
1837
- let pos = sm. lookup_char_pos ( self . tcx . def_span ( proj. item_def_id ) . lo ( ) ) ;
1838
- format ! (
1839
- " (trait associated opaque type at <{}:{}:{}>)" ,
1840
- sm. filename_for_diagnostics( & pos. file. name) ,
1841
- pos. line,
1842
- pos. col. to_usize( ) + 1 ,
1843
- )
1816
+ let sort_string = |ty : Ty < ' tcx > , path : Option < PathBuf > | {
1817
+ let mut s = match ( extra, ty. kind ( ) ) {
1818
+ ( true , ty:: Opaque ( def_id, _) ) => {
1819
+ let sm = self . tcx . sess . source_map ( ) ;
1820
+ let pos = sm. lookup_char_pos ( self . tcx . def_span ( * def_id) . lo ( ) ) ;
1821
+ format ! (
1822
+ " (opaque type at <{}:{}:{}>)" ,
1823
+ sm. filename_for_diagnostics( & pos. file. name) ,
1824
+ pos. line,
1825
+ pos. col. to_usize( ) + 1 ,
1826
+ )
1827
+ }
1828
+ ( true , ty:: Projection ( proj) )
1829
+ if self . tcx . def_kind ( proj. item_def_id )
1830
+ == DefKind :: ImplTraitPlaceholder =>
1831
+ {
1832
+ let sm = self . tcx . sess . source_map ( ) ;
1833
+ let pos = sm. lookup_char_pos ( self . tcx . def_span ( proj. item_def_id ) . lo ( ) ) ;
1834
+ format ! (
1835
+ " (trait associated opaque type at <{}:{}:{}>)" ,
1836
+ sm. filename_for_diagnostics( & pos. file. name) ,
1837
+ pos. line,
1838
+ pos. col. to_usize( ) + 1 ,
1839
+ )
1840
+ }
1841
+ ( true , _) => format ! ( " ({})" , ty. sort_string( self . tcx) ) ,
1842
+ ( false , _) => "" . to_string ( ) ,
1843
+ } ;
1844
+ if let Some ( path) = path {
1845
+ s. push_str ( & format ! (
1846
+ "\n the full type name has been written to '{}'" ,
1847
+ path. display( ) ,
1848
+ ) ) ;
1844
1849
}
1845
- ( true , _) => format ! ( " ({})" , ty. sort_string( self . tcx) ) ,
1846
- ( false , _) => "" . to_string ( ) ,
1850
+ s
1847
1851
} ;
1848
1852
if !( values. expected . is_simple_text ( ) && values. found . is_simple_text ( ) )
1849
1853
|| ( exp_found. map_or ( false , |ef| {
@@ -1865,8 +1869,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1865
1869
expected,
1866
1870
& found_label,
1867
1871
found,
1868
- & sort_string ( values. expected ) ,
1869
- & sort_string ( values. found ) ,
1872
+ & sort_string ( values. expected , exp_p ) ,
1873
+ & sort_string ( values. found , found_p ) ,
1870
1874
) ;
1871
1875
}
1872
1876
}
@@ -2339,7 +2343,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2339
2343
let code = trace. cause . code ( ) ;
2340
2344
if let & MatchExpressionArm ( box MatchExpressionArmCause { source, .. } ) = code
2341
2345
&& let hir:: MatchSource :: TryDesugar = source
2342
- && let Some ( ( expected_ty, found_ty) ) = self . values_str ( trace. values )
2346
+ && let Some ( ( expected_ty, found_ty, _ , _ ) ) = self . values_str ( trace. values )
2343
2347
{
2344
2348
err. note ( & format ! (
2345
2349
"`?` operator cannot convert from `{}` to `{}`" ,
@@ -2455,7 +2459,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2455
2459
fn values_str (
2456
2460
& self ,
2457
2461
values : ValuePairs < ' tcx > ,
2458
- ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString ) > {
2462
+ ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString , Option < PathBuf > , Option < PathBuf > ) >
2463
+ {
2459
2464
match values {
2460
2465
infer:: Regions ( exp_found) => self . expected_found_str ( exp_found) ,
2461
2466
infer:: Terms ( exp_found) => self . expected_found_str_term ( exp_found) ,
@@ -2465,7 +2470,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2465
2470
found : exp_found. found . print_only_trait_path ( ) ,
2466
2471
} ;
2467
2472
match self . expected_found_str ( pretty_exp_found) {
2468
- Some ( ( expected, found) ) if expected == found => {
2473
+ Some ( ( expected, found, _ , _ ) ) if expected == found => {
2469
2474
self . expected_found_str ( exp_found)
2470
2475
}
2471
2476
ret => ret,
@@ -2477,7 +2482,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2477
2482
found : exp_found. found . print_only_trait_path ( ) ,
2478
2483
} ;
2479
2484
match self . expected_found_str ( pretty_exp_found) {
2480
- Some ( ( expected, found) ) if expected == found => {
2485
+ Some ( ( expected, found, _ , _ ) ) if expected == found => {
2481
2486
self . expected_found_str ( exp_found)
2482
2487
}
2483
2488
ret => ret,
@@ -2489,17 +2494,41 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2489
2494
fn expected_found_str_term (
2490
2495
& self ,
2491
2496
exp_found : ty:: error:: ExpectedFound < ty:: Term < ' tcx > > ,
2492
- ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString ) > {
2497
+ ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString , Option < PathBuf > , Option < PathBuf > ) >
2498
+ {
2493
2499
let exp_found = self . resolve_vars_if_possible ( exp_found) ;
2494
2500
if exp_found. references_error ( ) {
2495
2501
return None ;
2496
2502
}
2497
2503
2498
2504
Some ( match ( exp_found. expected . unpack ( ) , exp_found. found . unpack ( ) ) {
2499
- ( ty:: TermKind :: Ty ( expected) , ty:: TermKind :: Ty ( found) ) => self . cmp ( expected, found) ,
2505
+ ( ty:: TermKind :: Ty ( expected) , ty:: TermKind :: Ty ( found) ) => {
2506
+ let ( mut exp, mut fnd) = self . cmp ( expected, found) ;
2507
+ // Use the terminal width as the basis to determine when to compress the printed
2508
+ // out type, but give ourselves some leeway to avoid ending up creating a file for
2509
+ // a type that is somewhat shorter than the path we'd write to.
2510
+ let len = self . tcx . sess ( ) . diagnostic_width ( ) + 40 ;
2511
+ let exp_s = exp. content ( ) ;
2512
+ let fnd_s = fnd. content ( ) ;
2513
+ let mut exp_p = None ;
2514
+ let mut fnd_p = None ;
2515
+ if exp_s. len ( ) > len {
2516
+ let ( exp_s, exp_path) = self . tcx . short_ty_string ( expected) ;
2517
+ exp = DiagnosticStyledString :: highlighted ( exp_s) ;
2518
+ exp_p = exp_path;
2519
+ }
2520
+ if fnd_s. len ( ) > len {
2521
+ let ( fnd_s, fnd_path) = self . tcx . short_ty_string ( found) ;
2522
+ fnd = DiagnosticStyledString :: highlighted ( fnd_s) ;
2523
+ fnd_p = fnd_path;
2524
+ }
2525
+ ( exp, fnd, exp_p, fnd_p)
2526
+ }
2500
2527
_ => (
2501
2528
DiagnosticStyledString :: highlighted ( exp_found. expected . to_string ( ) ) ,
2502
2529
DiagnosticStyledString :: highlighted ( exp_found. found . to_string ( ) ) ,
2530
+ None ,
2531
+ None ,
2503
2532
) ,
2504
2533
} )
2505
2534
}
@@ -2508,7 +2537,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2508
2537
fn expected_found_str < T : fmt:: Display + TypeFoldable < ' tcx > > (
2509
2538
& self ,
2510
2539
exp_found : ty:: error:: ExpectedFound < T > ,
2511
- ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString ) > {
2540
+ ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString , Option < PathBuf > , Option < PathBuf > ) >
2541
+ {
2512
2542
let exp_found = self . resolve_vars_if_possible ( exp_found) ;
2513
2543
if exp_found. references_error ( ) {
2514
2544
return None ;
@@ -2517,6 +2547,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2517
2547
Some ( (
2518
2548
DiagnosticStyledString :: highlighted ( exp_found. expected . to_string ( ) ) ,
2519
2549
DiagnosticStyledString :: highlighted ( exp_found. found . to_string ( ) ) ,
2550
+ None ,
2551
+ None ,
2520
2552
) )
2521
2553
}
2522
2554
@@ -2850,36 +2882,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2850
2882
debug ! ( "report_sub_sup_conflict: sup_region={:?}" , sup_region) ;
2851
2883
debug ! ( "report_sub_sup_conflict: sup_origin={:?}" , sup_origin) ;
2852
2884
2853
- if let ( & infer:: Subtype ( ref sup_trace) , & infer:: Subtype ( ref sub_trace) ) =
2854
- ( & sup_origin, & sub_origin)
2885
+ if let infer:: Subtype ( ref sup_trace) = sup_origin
2886
+ && let infer:: Subtype ( ref sub_trace) = sub_origin
2887
+ && let Some ( ( sup_expected, sup_found, _, _) ) = self . values_str ( sup_trace. values )
2888
+ && let Some ( ( sub_expected, sub_found, _, _) ) = self . values_str ( sub_trace. values )
2889
+ && sub_expected == sup_expected
2890
+ && sub_found == sup_found
2855
2891
{
2856
- debug ! ( "report_sub_sup_conflict: sup_trace={:?}" , sup_trace) ;
2857
- debug ! ( "report_sub_sup_conflict: sub_trace={:?}" , sub_trace) ;
2858
- debug ! ( "report_sub_sup_conflict: sup_trace.values={:?}" , sup_trace. values) ;
2859
- debug ! ( "report_sub_sup_conflict: sub_trace.values={:?}" , sub_trace. values) ;
2860
-
2861
- if let ( Some ( ( sup_expected, sup_found) ) , Some ( ( sub_expected, sub_found) ) ) =
2862
- ( self . values_str ( sup_trace. values ) , self . values_str ( sub_trace. values ) )
2863
- {
2864
- if sub_expected == sup_expected && sub_found == sup_found {
2865
- note_and_explain_region (
2866
- self . tcx ,
2867
- & mut err,
2868
- "...but the lifetime must also be valid for " ,
2869
- sub_region,
2870
- "..." ,
2871
- None ,
2872
- ) ;
2873
- err. span_note (
2874
- sup_trace. cause . span ,
2875
- & format ! ( "...so that the {}" , sup_trace. cause. as_requirement_str( ) ) ,
2876
- ) ;
2892
+ note_and_explain_region (
2893
+ self . tcx ,
2894
+ & mut err,
2895
+ "...but the lifetime must also be valid for " ,
2896
+ sub_region,
2897
+ "..." ,
2898
+ None ,
2899
+ ) ;
2900
+ err. span_note (
2901
+ sup_trace. cause . span ,
2902
+ & format ! ( "...so that the {}" , sup_trace. cause. as_requirement_str( ) ) ,
2903
+ ) ;
2877
2904
2878
- err. note_expected_found ( & "" , sup_expected, & "" , sup_found) ;
2879
- err. emit ( ) ;
2880
- return ;
2881
- }
2882
- }
2905
+ err. note_expected_found ( & "" , sup_expected, & "" , sup_found) ;
2906
+ err. emit ( ) ;
2907
+ return ;
2883
2908
}
2884
2909
2885
2910
self . note_region_origin ( & mut err, & sup_origin) ;
0 commit comments