Skip to content

Commit df9cc2e

Browse files
committed
auto merge of #5924 : catamorphism/rust/non-fatal-errors, r=catamorphism
2 parents 50cd218 + 62847b0 commit df9cc2e

File tree

2 files changed

+68
-11
lines changed

2 files changed

+68
-11
lines changed

src/librustc/middle/typeck/check/_match.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,9 @@ pub fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::Path,
195195
Some(ref subpats) => subpats_len = subpats.len()
196196
}
197197

198-
if arg_len > 0u {
198+
let mut error_happened = false;
199+
200+
if arg_len > 0 {
199201
// N-ary variant.
200202
if arg_len != subpats_len {
201203
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,
205207
kind_name,
206208
arg_len,
207209
if arg_len == 1u { ~"" } else { ~"s" });
208-
// XXX: This should not be fatal.
209-
tcx.sess.span_fatal(pat.span, s);
210+
tcx.sess.span_err(pat.span, s);
211+
error_happened = true;
210212
}
211213
212-
for subpats.each |pats| {
213-
for vec::each2(*pats, arg_types) |subpat, arg_ty| {
214-
check_pat(pcx, *subpat, *arg_ty);
214+
if !error_happened {
215+
for subpats.each |pats| {
216+
for vec::each2(*pats, arg_types) |subpat, arg_ty| {
217+
check_pat(pcx, *subpat, *arg_ty);
218+
}
215219
}
216220
}
217-
} else if subpats_len > 0u {
218-
tcx.sess.span_fatal
221+
} else if subpats_len > 0 {
222+
tcx.sess.span_err
219223
(pat.span, fmt!("this pattern has %u field%s, but the \
220224
corresponding %s has no fields",
221225
subpats_len,
222226
if subpats_len == 1u { ~"" }
223227
else { ~"s" },
224228
kind_name));
229+
error_happened = true;
230+
}
231+
232+
if error_happened {
233+
let tcx = pcx.fcx.ccx.tcx;
234+
235+
for subpats.each |pats| {
236+
for pats.each |pat| {
237+
check_pat(pcx, *pat, ty::mk_err(tcx));
238+
}
239+
}
225240
}
226241
}
227242
@@ -446,6 +461,7 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
446461
ast::pat_struct(path, ref fields, etc) => {
447462
// Grab the class data that we care about.
448463
let structure = structure_of(fcx, pat.span, expected);
464+
let mut error_happened = false;
449465
match structure {
450466
ty::ty_struct(cid, ref substs) => {
451467
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) {
457473
substs);
458474
}
459475
_ => {
460-
// XXX: This should not be fatal.
461-
tcx.sess.span_fatal(pat.span,
476+
tcx.sess.span_err(pat.span,
462477
fmt!("mismatched types: expected `%s` \
463478
but found struct",
464479
fcx.infcx().ty_to_str(expected)));
480+
error_happened = true;
465481
}
466482
}
467483
468484
// Finally, write in the type.
469-
fcx.write_ty(pat.id, expected);
485+
if error_happened {
486+
fcx.write_error(pat.id);
487+
}
488+
else {
489+
fcx.write_ty(pat.id, expected);
490+
}
470491
}
471492
ast::pat_tup(ref elts) => {
472493
let s = structure_of(fcx, pat.span, expected);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that certain pattern-match type errors are non-fatal
12+
13+
enum A {
14+
B(int, int),
15+
C(int, int, int),
16+
D
17+
}
18+
19+
struct S {
20+
a: int
21+
}
22+
23+
fn f(_c: char) {}
24+
25+
fn main() {
26+
match B(1, 2) {
27+
B(_, _, _) => (), //~ ERROR this pattern has 3 fields, but
28+
D(_) => (), //~ ERROR this pattern has 1 field, but
29+
_ => ()
30+
}
31+
match 'c' {
32+
S { _ } => (), //~ ERROR mismatched types: expected `char` but found struct
33+
_ => ()
34+
}
35+
f(true); //~ ERROR mismatched types: expected `char` but found `bool`
36+
}

0 commit comments

Comments
 (0)