From 62847b0f24a1a550778f0b150a09dcf4c90f3b41 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Wed, 17 Apr 2013 19:36:59 -0700 Subject: [PATCH] rustc: Make some typechecker errors non-fatal --- src/librustc/middle/typeck/check/_match.rs | 43 ++++++++++++++----- .../compile-fail/pattern-error-continue.rs | 36 ++++++++++++++++ 2 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 src/test/compile-fail/pattern-error-continue.rs diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index e2dd0d1ed9e..e0c3e71a5a1 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -195,7 +195,9 @@ pub fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::Path, Some(ref subpats) => subpats_len = subpats.len() } - if arg_len > 0u { + let mut error_happened = false; + + if arg_len > 0 { // N-ary variant. if arg_len != subpats_len { let s = fmt!("this pattern has %u field%s, but the corresponding \ @@ -205,23 +207,36 @@ pub fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::Path, kind_name, arg_len, if arg_len == 1u { ~"" } else { ~"s" }); - // XXX: This should not be fatal. - tcx.sess.span_fatal(pat.span, s); + tcx.sess.span_err(pat.span, s); + error_happened = true; } - for subpats.each |pats| { - for vec::each2(*pats, arg_types) |subpat, arg_ty| { - check_pat(pcx, *subpat, *arg_ty); + if !error_happened { + for subpats.each |pats| { + for vec::each2(*pats, arg_types) |subpat, arg_ty| { + check_pat(pcx, *subpat, *arg_ty); + } } } - } else if subpats_len > 0u { - tcx.sess.span_fatal + } else if subpats_len > 0 { + tcx.sess.span_err (pat.span, fmt!("this pattern has %u field%s, but the \ corresponding %s has no fields", subpats_len, if subpats_len == 1u { ~"" } else { ~"s" }, kind_name)); + error_happened = true; + } + + if error_happened { + let tcx = pcx.fcx.ccx.tcx; + + for subpats.each |pats| { + for pats.each |pat| { + check_pat(pcx, *pat, ty::mk_err(tcx)); + } + } } } @@ -446,6 +461,7 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { ast::pat_struct(path, ref fields, etc) => { // Grab the class data that we care about. let structure = structure_of(fcx, pat.span, expected); + let mut error_happened = false; match structure { ty::ty_struct(cid, ref substs) => { check_struct_pat(pcx, pat.id, pat.span, expected, path, @@ -457,16 +473,21 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { substs); } _ => { - // XXX: This should not be fatal. - tcx.sess.span_fatal(pat.span, + tcx.sess.span_err(pat.span, fmt!("mismatched types: expected `%s` \ but found struct", fcx.infcx().ty_to_str(expected))); + error_happened = true; } } // Finally, write in the type. - fcx.write_ty(pat.id, expected); + if error_happened { + fcx.write_error(pat.id); + } + else { + fcx.write_ty(pat.id, expected); + } } ast::pat_tup(ref elts) => { let s = structure_of(fcx, pat.span, expected); diff --git a/src/test/compile-fail/pattern-error-continue.rs b/src/test/compile-fail/pattern-error-continue.rs new file mode 100644 index 00000000000..14d8b04ade4 --- /dev/null +++ b/src/test/compile-fail/pattern-error-continue.rs @@ -0,0 +1,36 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that certain pattern-match type errors are non-fatal + +enum A { + B(int, int), + C(int, int, int), + D +} + +struct S { + a: int +} + +fn f(_c: char) {} + +fn main() { + match B(1, 2) { + B(_, _, _) => (), //~ ERROR this pattern has 3 fields, but + D(_) => (), //~ ERROR this pattern has 1 field, but + _ => () + } + match 'c' { + S { _ } => (), //~ ERROR mismatched types: expected `char` but found struct + _ => () + } + f(true); //~ ERROR mismatched types: expected `char` but found `bool` +} \ No newline at end of file