Skip to content

Commit c7470de

Browse files
committed
Change the way fn-item types are displayed: make them easier to distinguish from fn pointers.
1 parent 2f847b8 commit c7470de

File tree

2 files changed

+60
-34
lines changed
  • compiler
    • rustc_infer/src/infer/error_reporting
    • rustc_middle/src/ty/print

2 files changed

+60
-34
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ pub trait PrettyPrinter<'tcx>:
591591
}
592592
ty::FnDef(def_id, substs) => {
593593
let sig = self.tcx().bound_fn_sig(def_id).subst(self.tcx(), substs);
594-
p!(print(sig), " {{", print_value_path(def_id, substs), "}}");
594+
p!("[fn item {{", print_value_path(def_id, substs), "}}: ", print(sig), "]");
595595
}
596596
ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
597597
ty::Infer(infer_ty) => {

0 commit comments

Comments
 (0)