Skip to content

Commit 541cfb4

Browse files
committed
On type errors, show closure signature
Instead of refering to closures with their span, format their signature.
1 parent 9053fdd commit 541cfb4

File tree

6 files changed

+73
-37
lines changed

6 files changed

+73
-37
lines changed

src/librustc/hir/mod.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1440,8 +1440,13 @@ pub struct Ty {
14401440

14411441
impl fmt::Debug for Ty {
14421442
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1443-
write!(f, "type({})",
1444-
print::to_string(print::NO_ANN, |s| s.print_type(self)))
1443+
write!(f, "type({})", print::to_string(print::NO_ANN, |s| s.print_type(self)))
1444+
}
1445+
}
1446+
1447+
impl fmt::Display for Ty {
1448+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1449+
write!(f, "{}", print::to_string(print::NO_ANN, |s| s.print_type(self)))
14451450
}
14461451
}
14471452

src/librustc/infer/error_reporting/mod.rs

+34-2
Original file line numberDiff line numberDiff line change
@@ -723,8 +723,40 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
723723
// When encountering &T != &mut T, highlight only the borrow
724724
(&ty::TyRef(r1, ref tnm1), &ty::TyRef(r2, ref tnm2)) if equals(&tnm1.ty, &tnm2.ty) => {
725725
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
726-
push_ty_ref(&r1, tnm1, &mut values.0);
727-
push_ty_ref(&r2, tnm2, &mut values.1);
726+
push_ty_ref(& r1, tnm1, & mut values.0);
727+
push_ty_ref( & r2, tnm2, &mut values.1);
728+
values
729+
}
730+
// When comparing against a closure, print its signature without location
731+
(_, &ty::TyClosure(did, _)) => {
732+
let mut values = (DiagnosticStyledString::highlighted(format!("{}", t1)),
733+
DiagnosticStyledString::new());
734+
if let Some(node_id) = self.tcx.hir.as_local_node_id(did) {
735+
if let Some(hir::map::NodeExpr(expr)) = self.tcx.hir.find(node_id) {
736+
if let hir::ExprClosure(capture, ref fn_decl, _, _, _) = expr.node {
737+
let args = fn_decl.inputs.iter()
738+
.map(|arg| format!("{}", arg))
739+
.collect::<Vec<String>>()
740+
.join(", ");
741+
values.1.push_highlighted(
742+
format!("{}fn({}) -> {}",
743+
if capture == hir::CaptureByValue {
744+
"move "
745+
} else {
746+
""
747+
},
748+
args,
749+
if let hir::Return(ref r_ty) = fn_decl.output {
750+
format!("{}", r_ty)
751+
} else {
752+
"_".to_string()
753+
}));
754+
return values;
755+
}
756+
}
757+
}
758+
// fallback
759+
values.1.push_highlighted(format!("{}", t2));
728760
values
729761
}
730762

src/librustc/traits/error_reporting.rs

+28-29
Original file line numberDiff line numberDiff line change
@@ -938,51 +938,50 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
938938
err
939939
}
940940

941+
fn build_fn_sig_string(&self, trait_ref: &ty::TraitRef<'tcx>) -> String {
942+
let inputs = trait_ref.substs.type_at(1);
943+
let sig = if let ty::TyTuple(inputs, _) = inputs.sty {
944+
self.tcx.mk_fn_sig(
945+
inputs.iter().map(|&x| x),
946+
self.tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
947+
false,
948+
hir::Unsafety::Normal,
949+
::syntax::abi::Abi::Rust
950+
)
951+
} else {
952+
self.tcx.mk_fn_sig(
953+
::std::iter::once(inputs),
954+
self.tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
955+
false,
956+
hir::Unsafety::Normal,
957+
::syntax::abi::Abi::Rust
958+
)
959+
};
960+
format!("{}", ty::Binder(sig))
961+
}
962+
941963
fn report_closure_arg_mismatch(&self,
942-
span: Span,
943-
found_span: Option<Span>,
944-
expected_ref: ty::PolyTraitRef<'tcx>,
945-
found: ty::PolyTraitRef<'tcx>)
964+
span: Span,
965+
found_span: Option<Span>,
966+
expected_ref: ty::PolyTraitRef<'tcx>,
967+
found: ty::PolyTraitRef<'tcx>)
946968
-> DiagnosticBuilder<'tcx>
947969
{
948-
fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
949-
trait_ref: &ty::TraitRef<'tcx>) -> String {
950-
let inputs = trait_ref.substs.type_at(1);
951-
let sig = if let ty::TyTuple(inputs, _) = inputs.sty {
952-
tcx.mk_fn_sig(
953-
inputs.iter().map(|&x| x),
954-
tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
955-
false,
956-
hir::Unsafety::Normal,
957-
::syntax::abi::Abi::Rust
958-
)
959-
} else {
960-
tcx.mk_fn_sig(
961-
::std::iter::once(inputs),
962-
tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
963-
false,
964-
hir::Unsafety::Normal,
965-
::syntax::abi::Abi::Rust
966-
)
967-
};
968-
format!("{}", ty::Binder(sig))
969-
}
970-
971970
let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure();
972971
let mut err = struct_span_err!(self.tcx.sess, span, E0631,
973972
"type mismatch in {} arguments",
974973
if argument_is_closure { "closure" } else { "function" });
975974

976975
let found_str = format!(
977976
"expected signature of `{}`",
978-
build_fn_sig_string(self.tcx, found.skip_binder())
977+
self.build_fn_sig_string(found.skip_binder())
979978
);
980979
err.span_label(span, found_str);
981980

982981
let found_span = found_span.unwrap_or(span);
983982
let expected_str = format!(
984983
"found signature of `{}`",
985-
build_fn_sig_string(self.tcx, expected_ref.skip_binder())
984+
self.build_fn_sig_string(expected_ref.skip_binder())
986985
);
987986
err.span_label(found_span, expected_str);
988987

src/test/compile-fail/issue-24036.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn closure_to_loc() {
1616
//~| HELP consider boxing your closure and/or using it as a trait object
1717
//~| expected closure, found a different closure
1818
//~| expected type `[closure
19-
//~| found type `[closure
19+
//~| found type `fn(_) -> _`
2020
}
2121

2222
fn closure_from_match() {
@@ -31,7 +31,7 @@ fn closure_from_match() {
3131
//~| HELP consider boxing your closure and/or using it as a trait object
3232
//~| expected closure, found a different closure
3333
//~| expected type `[closure
34-
//~| found type `[closure
34+
//~| found type `fn(_) -> _`
3535
}
3636

3737
fn main() { }

src/test/ui/block-result/issue-20862.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ error[E0308]: mismatched types
77
| ^^^^^^^^^ expected (), found closure
88
|
99
= note: expected type `()`
10-
found type `[closure@$DIR/issue-20862.rs:12:5: 12:14 x:_]`
10+
found type `fn(_) -> _`
1111

1212
error[E0618]: expected function, found `()`
1313
--> $DIR/issue-20862.rs:17:13

src/test/ui/span/move-closure.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ error[E0308]: mismatched types
55
| ^^^^^^^^^^ expected (), found closure
66
|
77
= note: expected type `()`
8-
found type `[closure@$DIR/move-closure.rs:15:17: 15:27]`
8+
found type `move fn() -> _`
99

1010
error: aborting due to previous error
1111

0 commit comments

Comments
 (0)