about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/typeck/check/_match.rs74
-rw-r--r--src/librustc/middle/typeck/infer/mod.rs43
-rw-r--r--src/test/compile-fail/issue-5100.rs2
-rw-r--r--src/test/compile-fail/suppressed-error.rs14
4 files changed, 84 insertions, 49 deletions
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index a1a098bc576..07083459020 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -146,13 +146,12 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path,
                     kind_name = "variant";
                 }
                 None => {
-                    let resolved_expected =
-                        fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
-                    fcx.infcx().type_error_message_str(pat.span,
-                                                       |actual| {
+                    fcx.infcx().type_error_message_str_with_expected(pat.span,
+                                                       |expected, actual| {
+                                                       expected.map_default(~"", |&e| {
                         fmt!("mismatched types: expected `%s` but found %s",
-                             resolved_expected, actual)},
-                             ~"a structure pattern",
+                             e, actual)})},
+                             Some(expected), ~"a structure pattern",
                              None);
                     fcx.write_error(pat.id);
                     kind_name = "[error]";
@@ -189,13 +188,12 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path,
             kind_name = "structure";
         }
         _ => {
-            let resolved_expected =
-                fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
-            fcx.infcx().type_error_message_str(pat.span,
-                                               |actual| {
+            fcx.infcx().type_error_message_str_with_expected(pat.span,
+                                               |expected, actual| {
+                                               expected.map_default(~"", |&e| {
                     fmt!("mismatched types: expected `%s` but found %s",
-                         resolved_expected, actual)},
-                    ~"an enum or structure pattern",
+                         e, actual)})},
+                    Some(expected), ~"an enum or structure pattern",
                     None);
             fcx.write_error(pat.id);
             kind_name = "[error]";
@@ -508,9 +506,6 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
                 for elts.each |elt| {
                     check_pat(pcx, *elt, ty::mk_err());
                 }
-                let actual = ty::mk_tup(tcx, elts.map(|pat_var| {
-                    fcx.node_ty(pat_var.id)
-                }));
                 // use terr_tuple_size if both types are tuples
                 let type_error = match s {
                     ty::ty_tup(ref ex_elts) =>
@@ -518,10 +513,10 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
                                                            found: e_count}),
                     _ => ty::terr_mismatch
                 };
-                fcx.infcx().report_mismatched_types(pat.span,
-                                                    expected,
-                                                    actual,
-                                                    &type_error);
+                fcx.infcx().type_error_message_str_with_expected(pat.span, |expected, actual| {
+                expected.map_default(~"", |&e| {
+                    fmt!("mismatched types: expected `%s` but found %s",
+                                     e, actual)})}, Some(expected), ~"tuple", Some(&type_error));
                 fcx.write_error(pat.id);
             }
         }
@@ -566,14 +561,15 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
               for after.each |&elt| {
                   check_pat(pcx, elt, ty::mk_err());
               }
-              let resolved_expected =
-                  fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
-              fcx.infcx().type_error_message_str(pat.span,
-                  |actual| {
-                      fmt!("mismatched types: expected `%s` but found %s",
-                           resolved_expected, actual)},
-                                                 ~"a vector pattern",
-                                                 None);
+              fcx.infcx().type_error_message_str_with_expected(
+                  pat.span,
+                  |expected, actual| {
+                      expected.map_default(~"", |&e| {
+                          fmt!("mismatched types: expected `%s` but found %s",
+                               e, actual)})},
+                  Some(expected),
+                  ~"a vector pattern",
+                  None);
               fcx.write_error(pat.id);
               return;
           }
@@ -623,17 +619,19 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
         }
         _ => {
             check_pat(pcx, inner, ty::mk_err());
-            let resolved_expected =
-                fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
-            fcx.infcx().type_error_message_str(span, |actual| {
-                    fmt!("mismatched types: expected `%s` but found %s",
-                         resolved_expected, actual)},
-                                               fmt!("%s pattern", match pointer_kind {
-                                                   Managed => "an @-box",
-                                                   Owned => "a ~-box",
-                                                   Borrowed => "an &-pointer"
-                                               }),
-                    None);
+            fcx.infcx().type_error_message_str_with_expected(
+                span,
+                |expected, actual| {
+                    expected.map_default(~"", |&e| {
+                        fmt!("mismatched types: expected `%s` but found %s",
+                             e, actual)})},
+                Some(expected),
+                fmt!("%s pattern", match pointer_kind {
+                    Managed => "an @-box",
+                    Owned => "a ~-box",
+                    Borrowed => "an &-pointer"
+                }),
+                None);
             fcx.write_error(pat_id);
           }
     }
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index 2e784b11c35..2c42914f4b5 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -728,21 +728,45 @@ pub impl InferCtxt {
         }
     }
 
+    fn type_error_message_str(@mut self,
+                              sp: span,
+                              mk_msg: &fn(Option<~str>, ~str) -> ~str,
+                              actual_ty: ~str, err: Option<&ty::type_err>) {
+        self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
+    }
+
+    fn type_error_message_str_with_expected(@mut self,
+                                            sp: span,
+                                            mk_msg: &fn(Option<~str>, ~str) -> ~str,
+                                            expected_ty: Option<ty::t>, actual_ty: ~str,
+                                            err: Option<&ty::type_err>) {
+        debug!("hi! expected_ty = %?, actual_ty = %s", expected_ty, actual_ty);
 
-    fn type_error_message_str(@mut self, sp: span, mk_msg: &fn(~str) -> ~str,
-                          actual_ty: ~str, err: Option<&ty::type_err>) {
         let error_str = err.map_default(~"", |t_err|
                          fmt!(" (%s)",
                               ty::type_err_to_str(self.tcx, *t_err)));
-        self.tcx.sess.span_err(sp,
-           fmt!("%s%s", mk_msg(actual_ty), error_str));
-        for err.each |err| {
-            ty::note_and_explain_type_err(self.tcx, *err)
+        let resolved_expected = expected_ty.map(|&e_ty|
+                                                { self.resolve_type_vars_if_possible(e_ty) });
+        if !resolved_expected.map_default(false, |&e| { ty::type_is_error(e) }) {
+            match resolved_expected {
+                None => self.tcx.sess.span_err(sp,
+                            fmt!("%s%s", mk_msg(None, actual_ty), error_str)),
+                Some(e) => {
+                    self.tcx.sess.span_err(sp,
+                        fmt!("%s%s", mk_msg(Some(self.ty_to_str(e)), actual_ty), error_str));
+                }
+            }
+            for err.each |err| {
+                ty::note_and_explain_type_err(self.tcx, *err)
+            }
         }
     }
 
-    fn type_error_message(@mut self, sp: span, mk_msg: &fn(~str) -> ~str,
-                          actual_ty: ty::t, err: Option<&ty::type_err>) {
+    fn type_error_message(@mut self,
+                          sp: span,
+                          mk_msg: &fn(~str) -> ~str,
+                          actual_ty: ty::t,
+                          err: Option<&ty::type_err>) {
         let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
 
         // Don't report an error if actual type is ty_err.
@@ -750,8 +774,7 @@ pub impl InferCtxt {
             return;
         }
 
-        self.type_error_message_str(sp, mk_msg, self.ty_to_str(actual_ty),
-                                    err);
+        self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_str(actual_ty), err);
     }
 
     fn report_mismatched_types(@mut self, sp: span, e: ty::t, a: ty::t,
diff --git a/src/test/compile-fail/issue-5100.rs b/src/test/compile-fail/issue-5100.rs
index dbfdb38f721..8cc047230dc 100644
--- a/src/test/compile-fail/issue-5100.rs
+++ b/src/test/compile-fail/issue-5100.rs
@@ -17,7 +17,7 @@ fn main() {
     }
 
     match (true, false) {
-        (true, false, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found `(bool,bool,bool)` (expected a tuple with 2 elements but found one with 3 elements)
+        (true, false, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found tuple (expected a tuple with 2 elements but found one with 3 elements)
     }
 
     match (true, false) {
diff --git a/src/test/compile-fail/suppressed-error.rs b/src/test/compile-fail/suppressed-error.rs
new file mode 100644
index 00000000000..b4a72548cfc
--- /dev/null
+++ b/src/test/compile-fail/suppressed-error.rs
@@ -0,0 +1,14 @@
+// Copyright 2013 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 main() {
+    let (x, y) = (); //~ ERROR expected `()` but found tuple (types differ)
+    return x;
+}
\ No newline at end of file