@@ -961,7 +961,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
961961 & self ,
962962 sig1 : & ty:: PolyFnSig < ' tcx > ,
963963 sig2 : & ty:: PolyFnSig < ' tcx > ,
964- ) -> ( DiagnosticStyledString , DiagnosticStyledString ) {
964+ values : & mut ( DiagnosticStyledString , DiagnosticStyledString ) ,
965+ highlight_empty_parens : bool ,
966+ ) {
965967 let get_lifetimes = |sig| {
966968 use rustc_hir:: def:: Namespace ;
967969 let ( _, sig, reg) = ty:: print:: FmtPrinter :: new ( self . tcx , Namespace :: TypeNS )
@@ -974,11 +976,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
974976 let ( lt1, sig1) = get_lifetimes ( sig1) ;
975977 let ( lt2, sig2) = get_lifetimes ( sig2) ;
976978
979+ // illustrative example:
977980 // unsafe extern "C" for<'a> fn(&'a T) -> &'a T
978- let mut values = (
979- DiagnosticStyledString :: normal ( "" . to_string ( ) ) ,
980- DiagnosticStyledString :: normal ( "" . to_string ( ) ) ,
981- ) ;
982981
983982 // unsafe extern "C" for<'a> fn(&'a T) -> &'a T
984983 // ^^^^^^
@@ -1002,14 +1001,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10021001
10031002 // unsafe extern "C" for<'a> fn(&'a T) -> &'a T
10041003 // ^^^
1005- values. 0 . push_normal ( "fn(" ) ;
1006- values. 1 . push_normal ( "fn(" ) ;
1004+ let len1 = sig1. inputs ( ) . len ( ) ;
1005+ let len2 = sig2. inputs ( ) . len ( ) ;
1006+ let same_len = len1 == len2;
1007+ // when comparing between fn item and fn pointer types, make sure to
1008+ // always pull attention to the mismatching function signatures, too,
1009+ // by highlighting *something* (to compensate the stylistic difference
1010+ // `fn(...) -> ...` vs `[fn item {path::to::foo}: fn(...) -> ...]`)
1011+ let highlight_parens = highlight_empty_parens && !same_len && ( len1 == 0 || len2 == 0 ) ;
1012+ values. 0 . push_normal ( "fn" ) ;
1013+ values. 1 . push_normal ( "fn" ) ;
1014+ values. 0 . push ( "(" , highlight_parens) ;
1015+ values. 1 . push ( "(" , highlight_parens) ;
10071016
10081017 // unsafe extern "C" for<'a> fn(&'a T) -> &'a T
10091018 // ^^^^^
1010- let len1 = sig1. inputs ( ) . len ( ) ;
1011- let len2 = sig2. inputs ( ) . len ( ) ;
1012- if len1 == len2 {
1019+ if same_len {
10131020 for ( i, ( l, r) ) in iter:: zip ( sig1. inputs ( ) , sig2. inputs ( ) ) . enumerate ( ) {
10141021 let ( x1, x2) = self . cmp ( * l, * r) ;
10151022 ( values. 0 ) . 0 . extend ( x1. 0 ) ;
@@ -1033,36 +1040,37 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10331040
10341041 if sig1. c_variadic {
10351042 if len1 > 0 {
1036- values. 0 . push_normal ( ", " ) ;
1043+ values. 0 . push ( ", " , !same_len ) ;
10371044 }
10381045 values. 0 . push ( "..." , !sig2. c_variadic ) ;
10391046 }
10401047 if sig2. c_variadic {
10411048 if len2 > 0 {
1042- values. 1 . push_normal ( ", " ) ;
1049+ values. 1 . push ( ", " , !same_len ) ;
10431050 }
10441051 values. 1 . push ( "..." , !sig1. c_variadic ) ;
10451052 }
10461053
10471054 // unsafe extern "C" for<'a> fn(&'a T) -> &'a T
10481055 // ^
1049- values. 0 . push_normal ( ")" ) ;
1050- values. 1 . push_normal ( ")" ) ;
1056+ values. 0 . push ( ")" , highlight_parens ) ;
1057+ values. 1 . push ( ")" , highlight_parens ) ;
10511058
10521059 // unsafe extern "C" for<'a> fn(&'a T) -> &'a T
10531060 // ^^^^^^^^
10541061 let output1 = sig1. output ( ) ;
10551062 let output2 = sig2. output ( ) ;
10561063 let ( x1, x2) = self . cmp ( output1, output2) ;
1057- if !output1. is_unit ( ) {
1058- values. 0 . push_normal ( " -> " ) ;
1064+ let non_unit1 = !output1. is_unit ( ) ;
1065+ let non_unit2 = !output2. is_unit ( ) ;
1066+ if non_unit1 {
1067+ values. 0 . push ( " -> " , non_unit1 != non_unit2) ;
10591068 ( values. 0 ) . 0 . extend ( x1. 0 ) ;
10601069 }
1061- if !output2 . is_unit ( ) {
1062- values. 1 . push_normal ( " -> " ) ;
1070+ if non_unit2 {
1071+ values. 1 . push ( " -> " , non_unit1 != non_unit2 ) ;
10631072 ( values. 1 ) . 0 . extend ( x2. 0 ) ;
10641073 }
1065- values
10661074 }
10671075
10681076 /// Compares two given types, eliding parts that are the same between them and highlighting
@@ -1363,36 +1371,54 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13631371 ( ty:: FnDef ( did1, substs1) , ty:: FnDef ( did2, substs2) ) => {
13641372 let sig1 = self . tcx . bound_fn_sig ( * did1) . subst ( self . tcx , substs1) ;
13651373 let sig2 = self . tcx . bound_fn_sig ( * did2) . subst ( self . tcx , substs2) ;
1366- let mut values = self . cmp_fn_sig ( & sig1, & sig2) ;
1367- let path1 = format ! ( " {{{}}}" , self . tcx. def_path_str_with_substs( * did1, substs1) ) ;
1368- let path2 = format ! ( " {{{}}}" , self . tcx. def_path_str_with_substs( * did2, substs2) ) ;
1374+ let mut values = (
1375+ DiagnosticStyledString :: normal ( "[fn item {" . to_string ( ) ) ,
1376+ DiagnosticStyledString :: normal ( "[fn item {" . to_string ( ) ) ,
1377+ ) ;
1378+ let path1 = self . tcx . def_path_str_with_substs ( * did1, substs1) ;
1379+ let path2 = self . tcx . def_path_str_with_substs ( * did2, substs2) ;
13691380 let same_path = path1 == path2;
13701381 values. 0 . push ( path1, !same_path) ;
13711382 values. 1 . push ( path2, !same_path) ;
1383+ values. 0 . push_normal ( "}: " ) ;
1384+ values. 1 . push_normal ( "}: " ) ;
1385+ self . cmp_fn_sig ( & sig1, & sig2, & mut values, false ) ;
1386+ values. 0 . push_normal ( "]" ) ;
1387+ values. 1 . push_normal ( "]" ) ;
13721388 values
13731389 }
13741390
13751391 ( ty:: FnDef ( did1, substs1) , ty:: FnPtr ( sig2) ) => {
13761392 let sig1 = self . tcx . bound_fn_sig ( * did1) . subst ( self . tcx , substs1) ;
1377- let mut values = self . cmp_fn_sig ( & sig1, sig2) ;
1378- values. 0 . push_highlighted ( format ! (
1379- " {{{}}}" ,
1380- self . tcx. def_path_str_with_substs( * did1, substs1)
1381- ) ) ;
1393+ let mut values = (
1394+ DiagnosticStyledString :: normal ( "[fn item {" . to_string ( ) ) ,
1395+ DiagnosticStyledString :: new ( ) ,
1396+ ) ;
1397+ values. 0 . push_highlighted ( self . tcx . def_path_str_with_substs ( * did1, substs1) ) ;
1398+ values. 0 . push_normal ( "}: " ) ;
1399+ self . cmp_fn_sig ( & sig1, sig2, & mut values, true ) ;
1400+ values. 0 . push_normal ( "]" ) ;
13821401 values
13831402 }
13841403
13851404 ( ty:: FnPtr ( sig1) , ty:: FnDef ( did2, substs2) ) => {
13861405 let sig2 = self . tcx . bound_fn_sig ( * did2) . subst ( self . tcx , substs2) ;
1387- let mut values = self . cmp_fn_sig ( sig1, & sig2) ;
1388- values. 1 . push_normal ( format ! (
1389- " {{{}}}" ,
1390- self . tcx. def_path_str_with_substs( * did2, substs2)
1391- ) ) ;
1406+ let mut values = (
1407+ DiagnosticStyledString :: new ( ) ,
1408+ DiagnosticStyledString :: normal ( "[fn item {" . to_string ( ) ) ,
1409+ ) ;
1410+ values. 1 . push_highlighted ( self . tcx . def_path_str_with_substs ( * did2, substs2) ) ;
1411+ values. 1 . push_normal ( "}: " ) ;
1412+ self . cmp_fn_sig ( sig1, & sig2, & mut values, true ) ;
1413+ values. 1 . push_normal ( "]" ) ;
13921414 values
13931415 }
13941416
1395- ( ty:: FnPtr ( sig1) , ty:: FnPtr ( sig2) ) => self . cmp_fn_sig ( sig1, sig2) ,
1417+ ( ty:: FnPtr ( sig1) , ty:: FnPtr ( sig2) ) => {
1418+ let mut values = ( DiagnosticStyledString :: new ( ) , DiagnosticStyledString :: new ( ) ) ;
1419+ self . cmp_fn_sig ( sig1, sig2, & mut values, false ) ;
1420+ values
1421+ }
13961422
13971423 _ => {
13981424 if t1 == t2 {
0 commit comments