about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-12 16:37:29 +0000
committerbors <bors@rust-lang.org>2015-04-12 16:37:29 +0000
commit37cb1d455e77fbdb132c920e523eb4845f6b4fb9 (patch)
tree5bb7a7a76b4e46274350fc43871bde14cc834117
parenta1e3c25a2688664e85052b6205187b62410c0df0 (diff)
parent3308c06e33855f89627b417fd6b57f76d9df50a1 (diff)
downloadrust-37cb1d455e77fbdb132c920e523eb4845f6b4fb9.tar.gz
rust-37cb1d455e77fbdb132c920e523eb4845f6b4fb9.zip
Auto merge of #24072 - ebfull:explain_closure_type_err, r=pnkfelix
Also fixed bug calling .note() instead of .help()

See #24036
-rw-r--r--src/librustc/middle/infer/error_reporting.rs5
-rw-r--r--src/librustc/middle/infer/mod.rs2
-rw-r--r--src/librustc/middle/ty.rs12
-rw-r--r--src/librustc/session/mod.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/lib.rs2
-rw-r--r--src/test/compile-fail/issue-24036.rs30
7 files changed, 48 insertions, 7 deletions
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 36229a558e9..03e76f5ee25 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -373,8 +373,9 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
     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
@@ -812,7 +813,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
         }
         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);
         }
     }
 
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index b11e25c059d..0f62b440bf3 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -987,7 +987,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     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)
                 }
             }
         }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 952996c90f5..0a747ba881f 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -5103,7 +5103,7 @@ pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) -> String {
     }
 }
 
-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, "...");
@@ -5134,6 +5134,16 @@ pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) {
                                     "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"));
+            }
+        }
         _ => {}
     }
 }
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 88faf1cb68a..500af5fc772 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -163,7 +163,7 @@ impl Session {
         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 {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 31039e3abca..862c454a388 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3575,7 +3575,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                             .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);
                 }
             }
         }
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 9d6c04b1ad4..be3fc860b2b 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -200,7 +200,7 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
                                       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
         }
     }
diff --git a/src/test/compile-fail/issue-24036.rs b/src/test/compile-fail/issue-24036.rs
new file mode 100644
index 00000000000..3c8a64eaf7d
--- /dev/null
+++ b/src/test/compile-fail/issue-24036.rs
@@ -0,0 +1,30 @@
+// 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() { }