Skip to content

Commit 0274c70

Browse files
committed
Only print "irrefutable if-let pattern" errors once
When an `if let` translates into a `match` with more than two arms, we don't want to print multiple "irrefutable if-let pattern" errors.
1 parent e497a9d commit 0274c70

File tree

2 files changed

+71
-6
lines changed

2 files changed

+71
-6
lines changed

src/librustc/middle/check_match.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -253,19 +253,26 @@ fn check_for_static_nan(cx: &MatchCheckCtxt, arms: &[Arm]) {
253253
// Check for unreachable patterns
254254
fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm], source: MatchSource) {
255255
let mut seen = Matrix(vec!());
256+
let mut printed_if_let_err = false;
256257
for arm in arms.iter() {
257258
for &pat in arm.pats.iter() {
258259
let v = vec![pat];
259260
match is_useful(cx, &seen, v.as_slice(), LeaveOutWitness) {
260261
NotUseful => {
261262
if source == MatchIfLetDesugar {
262-
// find the first arm pattern so we can use its span
263-
let first_arm = &arms[0]; // we know there's at least 1 arm
264-
let first_pat = first_arm.pats.get(0); // and it's safe to assume 1 pat
265-
let span = first_pat.span;
266-
span_err!(cx.tcx.sess, span, E0159, "irrefutable if-let pattern")
263+
if printed_if_let_err {
264+
// we already printed an irrefutable if-let pattern error.
265+
// We don't want two, that's just confusing.
266+
} else {
267+
// find the first arm pattern so we can use its span
268+
let first_arm = &arms[0]; // we know there's at least 1 arm
269+
let first_pat = first_arm.pats.get(0); // and it's safe to assume 1 pat
270+
let span = first_pat.span;
271+
span_err!(cx.tcx.sess, span, E0159, "irrefutable if-let pattern");
272+
printed_if_let_err = true;
273+
}
267274
} else {
268-
span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern")
275+
span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern");
269276
}
270277
}
271278
Useful => (),

src/test/compile-fail/if-let.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright 2014 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+
#![feature(macro_rules)]
12+
13+
fn macros() {
14+
macro_rules! foo{
15+
($p:pat, $e:expr, $b:block) => {{
16+
if let $p = $e $b
17+
}}
18+
}
19+
macro_rules! bar{
20+
($p:pat, $e:expr, $b:block) => {{
21+
foo!($p, $e, $b)
22+
}}
23+
}
24+
25+
foo!(a, 1i, { //~ ERROR irrefutable if-let
26+
println!("irrefutable pattern");
27+
});
28+
bar!(a, 1i, { //~ ERROR irrefutable if-let
29+
println!("irrefutable pattern");
30+
});
31+
}
32+
33+
pub fn main() {
34+
if let a = 1i { //~ ERROR irrefutable if-let
35+
println!("irrefutable pattern");
36+
}
37+
38+
if let a = 1i { //~ ERROR irrefutable if-let
39+
println!("irrefutable pattern");
40+
} else if true {
41+
println!("else-if in irrefutable if-let");
42+
} else {
43+
println!("else in irrefutable if-let");
44+
}
45+
46+
if let 1i = 2i {
47+
println!("refutable pattern");
48+
} else if let a = 1i { //~ ERROR irrefutable if-let
49+
println!("irrefutable pattern");
50+
}
51+
52+
if true {
53+
println!("if");
54+
} else if let a = 1i { //~ ERROR irrefutable if-let
55+
println!("irrefutable pattern");
56+
}
57+
}
58+

0 commit comments

Comments
 (0)