@@ -961,7 +961,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
961
961
& self ,
962
962
sig1 : & ty:: PolyFnSig < ' tcx > ,
963
963
sig2 : & ty:: PolyFnSig < ' tcx > ,
964
- ) -> ( DiagnosticStyledString , DiagnosticStyledString ) {
964
+ values : & mut ( DiagnosticStyledString , DiagnosticStyledString ) ,
965
+ highlight_empty_parens : bool ,
966
+ ) {
965
967
let get_lifetimes = |sig| {
966
968
use rustc_hir:: def:: Namespace ;
967
969
let ( _, sig, reg) = ty:: print:: FmtPrinter :: new ( self . tcx , Namespace :: TypeNS )
@@ -974,11 +976,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
974
976
let ( lt1, sig1) = get_lifetimes ( sig1) ;
975
977
let ( lt2, sig2) = get_lifetimes ( sig2) ;
976
978
979
+ // illustrative example:
977
980
// 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
- ) ;
982
981
983
982
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
984
983
// ^^^^^^
@@ -1002,14 +1001,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1002
1001
1003
1002
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
1004
1003
// ^^^
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) ;
1007
1016
1008
1017
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
1009
1018
// ^^^^^
1010
- let len1 = sig1. inputs ( ) . len ( ) ;
1011
- let len2 = sig2. inputs ( ) . len ( ) ;
1012
- if len1 == len2 {
1019
+ if same_len {
1013
1020
for ( i, ( l, r) ) in iter:: zip ( sig1. inputs ( ) , sig2. inputs ( ) ) . enumerate ( ) {
1014
1021
let ( x1, x2) = self . cmp ( * l, * r) ;
1015
1022
( values. 0 ) . 0 . extend ( x1. 0 ) ;
@@ -1033,36 +1040,37 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1033
1040
1034
1041
if sig1. c_variadic {
1035
1042
if len1 > 0 {
1036
- values. 0 . push_normal ( ", " ) ;
1043
+ values. 0 . push ( ", " , !same_len ) ;
1037
1044
}
1038
1045
values. 0 . push ( "..." , !sig2. c_variadic ) ;
1039
1046
}
1040
1047
if sig2. c_variadic {
1041
1048
if len2 > 0 {
1042
- values. 1 . push_normal ( ", " ) ;
1049
+ values. 1 . push ( ", " , !same_len ) ;
1043
1050
}
1044
1051
values. 1 . push ( "..." , !sig1. c_variadic ) ;
1045
1052
}
1046
1053
1047
1054
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
1048
1055
// ^
1049
- values. 0 . push_normal ( ")" ) ;
1050
- values. 1 . push_normal ( ")" ) ;
1056
+ values. 0 . push ( ")" , highlight_parens ) ;
1057
+ values. 1 . push ( ")" , highlight_parens ) ;
1051
1058
1052
1059
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
1053
1060
// ^^^^^^^^
1054
1061
let output1 = sig1. output ( ) ;
1055
1062
let output2 = sig2. output ( ) ;
1056
1063
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) ;
1059
1068
( values. 0 ) . 0 . extend ( x1. 0 ) ;
1060
1069
}
1061
- if !output2 . is_unit ( ) {
1062
- values. 1 . push_normal ( " -> " ) ;
1070
+ if non_unit2 {
1071
+ values. 1 . push ( " -> " , non_unit1 != non_unit2 ) ;
1063
1072
( values. 1 ) . 0 . extend ( x2. 0 ) ;
1064
1073
}
1065
- values
1066
1074
}
1067
1075
1068
1076
/// Compares two given types, eliding parts that are the same between them and highlighting
@@ -1363,36 +1371,54 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1363
1371
( ty:: FnDef ( did1, substs1) , ty:: FnDef ( did2, substs2) ) => {
1364
1372
let sig1 = self . tcx . bound_fn_sig ( * did1) . subst ( self . tcx , substs1) ;
1365
1373
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) ;
1369
1380
let same_path = path1 == path2;
1370
1381
values. 0 . push ( path1, !same_path) ;
1371
1382
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 ( "]" ) ;
1372
1388
values
1373
1389
}
1374
1390
1375
1391
( ty:: FnDef ( did1, substs1) , ty:: FnPtr ( sig2) ) => {
1376
1392
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 ( "]" ) ;
1382
1401
values
1383
1402
}
1384
1403
1385
1404
( ty:: FnPtr ( sig1) , ty:: FnDef ( did2, substs2) ) => {
1386
1405
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 ( "]" ) ;
1392
1414
values
1393
1415
}
1394
1416
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
+ }
1396
1422
1397
1423
_ => {
1398
1424
if t1 == t2 {
0 commit comments