@@ -80,6 +80,7 @@ use rustc_middle::ty::{
8080use rustc_span:: { sym, symbol:: kw, BytePos , DesugaringKind , Pos , Span } ;
8181use rustc_target:: spec:: abi;
8282use std:: ops:: { ControlFlow , Deref } ;
83+ use std:: path:: PathBuf ;
8384use std:: { cmp, fmt, iter} ;
8485
8586mod note;
@@ -1352,10 +1353,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
13521353 . map ( |( mod_str, _) | mod_str. len ( ) + separator_len)
13531354 . sum ( ) ;
13541355
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" ) ;
13591357
13601358 if split_idx >= min_len {
13611359 // paths are identical, highlight everything
@@ -1366,7 +1364,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
13661364 } else {
13671365 let ( common, uniq1) = t1_str. split_at ( split_idx) ;
13681366 let ( _, uniq2) = t2_str. split_at ( split_idx) ;
1369- debug ! ( "cmp: common={}, uniq1={}, uniq2={}" , common , uniq1 , uniq2 ) ;
1367+ debug ! ( ? common, ? uniq1, ? uniq2, "cmp" ) ;
13701368
13711369 values. 0 . push_normal ( common) ;
13721370 values. 0 . push_highlighted ( uniq1) ;
@@ -1659,17 +1657,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
16591657 }
16601658 ValuePairs :: Regions ( _) => ( false , Mismatch :: Fixed ( "lifetime" ) ) ,
16611659 } ;
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 ;
16711666 } ;
1672- ( vals, exp_found, is_simple_error, Some ( values) )
1667+ ( Some ( vals) , exp_found, is_simple_error, Some ( values) )
16731668 }
16741669 } ;
16751670
@@ -1701,7 +1696,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
17011696 label_or_note ( span, & terr. to_string ( ) ) ;
17021697 }
17031698
1704- if let Some ( ( expected, found) ) = expected_found {
1699+ if let Some ( ( expected, found, exp_p , found_p ) ) = expected_found {
17051700 let ( expected_label, found_label, exp_found) = match exp_found {
17061701 Mismatch :: Variable ( ef) => (
17071702 ef. expected . prefix_string ( self . tcx ) ,
@@ -1818,32 +1813,41 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
18181813 }
18191814 TypeError :: Sorts ( values) => {
18201815 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+ ) ) ;
18441849 }
1845- ( true , _) => format ! ( " ({})" , ty. sort_string( self . tcx) ) ,
1846- ( false , _) => "" . to_string ( ) ,
1850+ s
18471851 } ;
18481852 if !( values. expected . is_simple_text ( ) && values. found . is_simple_text ( ) )
18491853 || ( exp_found. map_or ( false , |ef| {
@@ -1865,8 +1869,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
18651869 expected,
18661870 & found_label,
18671871 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 ) ,
18701874 ) ;
18711875 }
18721876 }
@@ -2339,7 +2343,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
23392343 let code = trace. cause . code ( ) ;
23402344 if let & MatchExpressionArm ( box MatchExpressionArmCause { source, .. } ) = code
23412345 && 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 )
23432347 {
23442348 err. note ( & format ! (
23452349 "`?` operator cannot convert from `{}` to `{}`" ,
@@ -2455,7 +2459,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
24552459 fn values_str (
24562460 & self ,
24572461 values : ValuePairs < ' tcx > ,
2458- ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString ) > {
2462+ ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString , Option < PathBuf > , Option < PathBuf > ) >
2463+ {
24592464 match values {
24602465 infer:: Regions ( exp_found) => self . expected_found_str ( exp_found) ,
24612466 infer:: Terms ( exp_found) => self . expected_found_str_term ( exp_found) ,
@@ -2465,7 +2470,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
24652470 found : exp_found. found . print_only_trait_path ( ) ,
24662471 } ;
24672472 match self . expected_found_str ( pretty_exp_found) {
2468- Some ( ( expected, found) ) if expected == found => {
2473+ Some ( ( expected, found, _ , _ ) ) if expected == found => {
24692474 self . expected_found_str ( exp_found)
24702475 }
24712476 ret => ret,
@@ -2477,7 +2482,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
24772482 found : exp_found. found . print_only_trait_path ( ) ,
24782483 } ;
24792484 match self . expected_found_str ( pretty_exp_found) {
2480- Some ( ( expected, found) ) if expected == found => {
2485+ Some ( ( expected, found, _ , _ ) ) if expected == found => {
24812486 self . expected_found_str ( exp_found)
24822487 }
24832488 ret => ret,
@@ -2489,17 +2494,41 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
24892494 fn expected_found_str_term (
24902495 & self ,
24912496 exp_found : ty:: error:: ExpectedFound < ty:: Term < ' tcx > > ,
2492- ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString ) > {
2497+ ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString , Option < PathBuf > , Option < PathBuf > ) >
2498+ {
24932499 let exp_found = self . resolve_vars_if_possible ( exp_found) ;
24942500 if exp_found. references_error ( ) {
24952501 return None ;
24962502 }
24972503
24982504 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+ }
25002527 _ => (
25012528 DiagnosticStyledString :: highlighted ( exp_found. expected . to_string ( ) ) ,
25022529 DiagnosticStyledString :: highlighted ( exp_found. found . to_string ( ) ) ,
2530+ None ,
2531+ None ,
25032532 ) ,
25042533 } )
25052534 }
@@ -2508,7 +2537,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
25082537 fn expected_found_str < T : fmt:: Display + TypeFoldable < ' tcx > > (
25092538 & self ,
25102539 exp_found : ty:: error:: ExpectedFound < T > ,
2511- ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString ) > {
2540+ ) -> Option < ( DiagnosticStyledString , DiagnosticStyledString , Option < PathBuf > , Option < PathBuf > ) >
2541+ {
25122542 let exp_found = self . resolve_vars_if_possible ( exp_found) ;
25132543 if exp_found. references_error ( ) {
25142544 return None ;
@@ -2517,6 +2547,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
25172547 Some ( (
25182548 DiagnosticStyledString :: highlighted ( exp_found. expected . to_string ( ) ) ,
25192549 DiagnosticStyledString :: highlighted ( exp_found. found . to_string ( ) ) ,
2550+ None ,
2551+ None ,
25202552 ) )
25212553 }
25222554
@@ -2850,36 +2882,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
28502882 debug ! ( "report_sub_sup_conflict: sup_region={:?}" , sup_region) ;
28512883 debug ! ( "report_sub_sup_conflict: sup_origin={:?}" , sup_origin) ;
28522884
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
28552891 {
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+ ) ;
28772904
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 ;
28832908 }
28842909
28852910 self . note_region_origin ( & mut err, & sup_origin) ;
0 commit comments