about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/infer/error_reporting.rs38
-rw-r--r--src/librustc_typeck/check/_match.rs4
-rw-r--r--src/librustc_typeck/check/intrinsic.rs5
-rw-r--r--src/librustc_typeck/check/wfcheck.rs3
-rw-r--r--src/librustc_typeck/collect.rs5
-rw-r--r--src/librustc_typeck/lib.rs40
6 files changed, 46 insertions, 49 deletions
diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs
index abc6ff4a294..88972beb31b 100644
--- a/src/librustc/infer/error_reporting.rs
+++ b/src/librustc/infer/error_reporting.rs
@@ -249,12 +249,12 @@ pub trait ErrorReporting<'tcx> {
                                      terr: &TypeError<'tcx>)
                                      -> DiagnosticBuilder<'tcx>;
 
-    fn values_str(&self, values: &ValuePairs<'tcx>) -> Option<String>;
+    fn values_str(&self, values: &ValuePairs<'tcx>) -> Option<(String, String)>;
 
     fn expected_found_str<T: fmt::Display + Resolvable<'tcx> + TypeFoldable<'tcx>>(
         &self,
         exp_found: &ty::error::ExpectedFound<T>)
-        -> Option<String>;
+        -> Option<(String, String)>;
 
     fn report_concrete_failure(&self,
                                origin: SubregionOrigin<'tcx>,
@@ -535,7 +535,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                          trace: TypeTrace<'tcx>,
                          terr: &TypeError<'tcx>)
                          -> DiagnosticBuilder<'tcx> {
-        let expected_found_str = match self.values_str(&trace.values) {
+        let (expected, found) = match self.values_str(&trace.values) {
             Some(v) => v,
             None => {
                 return self.tcx.sess.diagnostic().struct_dummy(); /* derived error */
@@ -548,18 +548,17 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
             false
         };
 
-        let expected_found_str = if is_simple_error {
-            expected_found_str
-        } else {
-            format!("{} ({})", expected_found_str, terr)
-        };
-
         let mut err = struct_span_err!(self.tcx.sess,
                                        trace.origin.span(),
                                        E0308,
-                                       "{}: {}",
-                                       trace.origin,
-                                       expected_found_str);
+                                       "{}",
+                                       trace.origin);
+
+        if !is_simple_error {
+            err = err.note_expected_found(&"type", &expected, &found);
+        }
+
+        err = err.span_label(trace.origin.span(), &terr);
 
         self.check_and_note_conflicting_crates(&mut err, terr, trace.origin.span());
 
@@ -574,6 +573,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
             },
             _ => ()
         }
+
         err
     }
 
@@ -631,7 +631,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
 
     /// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived
     /// error.
-    fn values_str(&self, values: &ValuePairs<'tcx>) -> Option<String> {
+    fn values_str(&self, values: &ValuePairs<'tcx>) -> Option<(String, String)> {
         match *values {
             infer::Types(ref exp_found) => self.expected_found_str(exp_found),
             infer::TraitRefs(ref exp_found) => self.expected_found_str(exp_found),
@@ -642,7 +642,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
     fn expected_found_str<T: fmt::Display + Resolvable<'tcx> + TypeFoldable<'tcx>>(
         &self,
         exp_found: &ty::error::ExpectedFound<T>)
-        -> Option<String>
+        -> Option<(String, String)>
     {
         let expected = exp_found.expected.resolve(self);
         if expected.references_error() {
@@ -654,9 +654,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
             return None;
         }
 
-        Some(format!("expected `{}`, found `{}`",
-                     expected,
-                     found))
+        Some((format!("{}", expected), format!("{}", found)))
     }
 
     fn report_generic_bound_failure(&self,
@@ -1751,11 +1749,11 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                 };
 
                 match self.values_str(&trace.values) {
-                    Some(values_str) => {
+                    Some((expected, found)) => {
                         err.span_note(
                             trace.origin.span(),
-                            &format!("...so that {} ({})",
-                                    desc, values_str));
+                            &format!("...so that {} (expected {}, found {})",
+                                    desc, expected, found));
                     }
                     None => {
                         // Really should avoid printing this error at
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index a7a04f4a85f..544fb117f36 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -116,8 +116,8 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
 
             // Check that the types of the end-points can be unified.
             let types_unify = require_same_types(
-                    tcx, Some(fcx.infcx()), false, pat.span, rhs_ty, lhs_ty,
-                    || "mismatched types in range".to_string()
+                tcx, Some(fcx.infcx()), false, pat.span, rhs_ty, lhs_ty,
+                "mismatched types in range",
             );
 
             // It's ok to return without a message as `require_same_types` prints an error.
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index eae0cfb0f22..b71ee8722ab 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -61,10 +61,7 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: &TyCtxt<'tcx>, it: &hir::ForeignItem,
                            it.span,
                            i_ty.ty,
                            fty,
-                           || {
-                format!("intrinsic has wrong type: expected `{}`",
-                         fty)
-            });
+                           "intrinsic has wrong type");
     }
 }
 
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 3bfd53ceada..492dbce9bdf 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -418,8 +418,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         let _ = ::require_same_types(
             fcx.tcx(), Some(fcx.infcx()), false, span,
             sig.inputs[0], rcvr_ty,
-            || "mismatched method receiver".to_owned()
-        );
+            "mismatched method receiver");
     }
 
     fn check_variances_for_type_defn(&self,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index ffcf4277156..51534a46dda 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1044,8 +1044,9 @@ fn convert_enum_def<'tcx>(tcx: &TyCtxt<'tcx>,
                           -> ty::AdtDefMaster<'tcx>
 {
     fn print_err(tcx: &TyCtxt, span: Span, ty: ty::Ty, cv: ConstVal) {
-        span_err!(tcx.sess, span, E0079, "mismatched types: expected `{}` got `{}`",
-                  ty, cv.description());
+        struct_span_err!(tcx.sess, span, E0079, "mismatched types")
+            .note_expected_found(&"type", &ty, &format!("{}", cv.description()))
+            .emit();
     }
     fn evaluate_disr_expr<'tcx>(tcx: &TyCtxt<'tcx>,
                                 repr_ty: attr::IntType,
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 7f27d10ce1e..c51304120a8 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -185,15 +185,14 @@ fn require_c_abi_if_variadic(tcx: &TyCtxt,
     }
 }
 
-fn require_same_types<'a, 'tcx, M>(tcx: &TyCtxt<'tcx>,
-                                   maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
-                                   t1_is_expected: bool,
-                                   span: Span,
-                                   t1: Ty<'tcx>,
-                                   t2: Ty<'tcx>,
-                                   msg: M)
-                                   -> bool where
-    M: FnOnce() -> String,
+fn require_same_types<'a, 'tcx>(tcx: &TyCtxt<'tcx>,
+                                maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
+                                t1_is_expected: bool,
+                                span: Span,
+                                t1: Ty<'tcx>,
+                                t2: Ty<'tcx>,
+                                msg: &str)
+                                -> bool
 {
     let result = match maybe_infcx {
         None => {
@@ -208,7 +207,17 @@ fn require_same_types<'a, 'tcx, M>(tcx: &TyCtxt<'tcx>,
     match result {
         Ok(_) => true,
         Err(ref terr) => {
-            let mut err = struct_span_err!(tcx.sess, span, E0211, "{}: {}", msg(), terr);
+            let mut err = struct_span_err!(tcx.sess, span, E0211, "{}", msg);
+            err = err.span_label(span, &terr);
+            let (mut expected_ty, mut found_ty) =
+                if t1_is_expected {(t1, t2)} else {(t2, t1)};
+            if let Some(infcx) = maybe_infcx {
+                expected_ty = infcx.resolve_type_vars_if_possible(&expected_ty);
+                found_ty = infcx.resolve_type_vars_if_possible(&found_ty);
+            }
+            err = err.note_expected_found(&"type",
+                                          &expected_ty,
+                                          &found_ty);
             tcx.note_and_explain_type_err(&mut err, terr, span);
             err.emit();
             false
@@ -250,10 +259,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
             });
 
             require_same_types(tcx, None, false, main_span, main_t, se_ty,
-                || {
-                    format!("main function expects type: `{}`",
-                             se_ty)
-                });
+                               "main function has wrong type");
         }
         _ => {
             span_bug!(main_span,
@@ -301,11 +307,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
             });
 
             require_same_types(tcx, None, false, start_span, start_t, se_ty,
-                || {
-                    format!("start function expects type: `{}`",
-                             se_ty)
-                });
-
+                               "start function has wrong type");
         }
         _ => {
             span_bug!(start_span,