fn report_and_explain_type_error(&self,
trace: TypeTrace<'tcx>,
terr: &ty::type_err<'tcx>) {
+ let span = trace.origin.span();
self.report_type_error(trace, terr);
- ty::note_and_explain_type_err(self.tcx, terr);
+ ty::note_and_explain_type_err(self.tcx, terr, span);
}
/// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived
}
self.give_suggestion(same_regions);
for &(ref trace, terr) in trace_origins {
- self.report_type_error(trace.clone(), &terr);
+ self.report_and_explain_type_error(trace.clone(), &terr);
}
}
error_str));
if let Some(err) = err {
- ty::note_and_explain_type_err(self.tcx, err)
+ ty::note_and_explain_type_err(self.tcx, err, sp)
}
}
}
}
}
-pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) {
+pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>, sp: Span) {
match *err {
terr_regions_does_not_outlive(subregion, superregion) => {
note_and_explain_region(cx, "", subregion, "...");
"expected concrete lifetime is ",
conc_region, "");
}
+ terr_sorts(values) => {
+ let expected_str = ty_sort_string(cx, values.expected);
+ let found_str = ty_sort_string(cx, values.found);
+ if expected_str == found_str && expected_str == "closure" {
+ cx.sess.span_note(sp, &format!("no two closures, even if identical, have the same \
+ type"));
+ cx.sess.span_help(sp, &format!("consider boxing your closure and/or \
+ using it as a trait object"));
+ }
+ }
_ => {}
}
}
self.diagnostic().handler().note(msg)
}
pub fn help(&self, msg: &str) {
- self.diagnostic().handler().note(msg)
+ self.diagnostic().handler().help(msg)
}
pub fn opt_span_bug(&self, opt_sp: Option<Span>, msg: &str) -> ! {
match opt_sp {
.ty_to_string(
actual_structure_type),
type_error_description);
- ty::note_and_explain_type_err(tcx, &type_error);
+ ty::note_and_explain_type_err(tcx, &type_error, path.span);
}
}
}
msg(),
ty::type_err_to_str(tcx,
terr));
- ty::note_and_explain_type_err(tcx, terr);
+ ty::note_and_explain_type_err(tcx, terr, span);
false
}
}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn closure_to_loc() {
+ let mut x = |c| c + 1;
+ x = |c| c + 1;
+ //~^ ERROR mismatched types
+ //~| NOTE no two closures, even if identical, have the same type
+ //~| HELP consider boxing your closure and/or using it as a trait object
+}
+
+fn closure_from_match() {
+ let x = match 1usize {
+ 1 => |c| c + 1,
+ 2 => |c| c - 1,
+ _ => |c| c - 1
+ };
+ //~^^^^^ ERROR match arms have incompatible types
+ //~| NOTE no two closures, even if identical, have the same type
+ //~| HELP consider boxing your closure and/or using it as a trait object
+}
+
+fn main() { }