diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 0ab3d50cfbc3d..435c946bf846d 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -1053,6 +1053,49 @@ impl LintPass for UnnecessaryParens { } } +declare_lint!(CATCH_ALL_MATCH_ARMS, Allow, + "detects catch-all arms in match statements") + +pub struct CatchAllMatch; + +impl CatchAllMatch { + fn check_catch_all_pattern(&mut self, cx: &Context, arm: &ast::Arm) { + for a in arm.pats.iter() { + match a.node { + ast::PatWild => { + cx.span_lint(CATCH_ALL_MATCH_ARMS, + a.span, + "catch-all pattern in match") + } + _ => {} + } + } + } +} + +impl LintPass for CatchAllMatch { + fn get_lints(&self) -> LintArray { + lint_array!(CATCH_ALL_MATCH_ARMS) + } + + fn check_expr(&mut self, cx: &Context, e: &ast::Expr) { + match e.node { + ast::ExprMatch(ref subexpression, ref arms) => { + let t = ty::expr_ty(cx.tcx, *subexpression); + match ty::get(t).sty { + ty::ty_enum(_, _) => { + for arm in arms.iter() { + self.check_catch_all_pattern(cx, arm); + } + } + _ => return + } + } + _ => return + } + } +} + declare_lint!(UNUSED_UNSAFE, Warn, "unnecessary use of an `unsafe` block") diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 79fbd73c23d3c..2a5b4b3282fee 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -151,6 +151,7 @@ impl LintStore { NonUppercasePatternStatics, UppercaseVariables, UnnecessaryParens, + CatchAllMatch, UnusedUnsafe, UnsafeBlock, UnusedMut, diff --git a/src/test/compile-fail/lint-catchall.rs b/src/test/compile-fail/lint-catchall.rs new file mode 100644 index 0000000000000..3c9b03acaa1e5 --- /dev/null +++ b/src/test/compile-fail/lint-catchall.rs @@ -0,0 +1,59 @@ +// Copyright 2014 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. + +#![deny(catch_all_match_arms)] +#![allow(dead_code, unused_variable)] + +enum Things { + Foo, + Bar, + Baz +} + +// Lint on enums only + +fn test1() { + let a = Some(5u); + match a { + Some(x) => {} + _ => {} //~ ERROR: catch-all pattern in match + } +} + +fn test2() { + let a = Foo; + match a { + Foo => {} + Bar => {} + _ => {} //~ ERROR: catch-all pattern in match + } +} + +// Do not lint on other types + +fn test3() { + let b = 5u; + let a = match b { + 9u => {} + _ => {} + }; +} + +fn test4() { + let b: (int, uint) = (5i, 8u); + match b { + (3, 4) => {} + (3, _) => {} + _ => {} + }; +} + +fn main() {} +