Skip to content

Commit a2fdfc0

Browse files
authored
Merge pull request #2298 from goodmanjonathan/else_if_without_else
add new lint else_if_without_else
2 parents 3d2d94b + 40c6f43 commit a2fdfc0

File tree

4 files changed

+143
-0
lines changed

4 files changed

+143
-0
lines changed
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//! lint on if expressions with an else if, but without a final else branch
2+
3+
use rustc::lint::*;
4+
use syntax::ast::*;
5+
6+
use utils::{in_external_macro, span_lint_and_sugg};
7+
8+
/// **What it does:** Checks for usage of if expressions with an `else if` branch,
9+
/// but without a final `else` branch.
10+
///
11+
/// **Why is this bad?** Some coding guidelines require this (e.g. MISRA-C:2004 Rule 14.10).
12+
///
13+
/// **Known problems:** None.
14+
///
15+
/// **Example:**
16+
/// ```rust
17+
/// if x.is_positive() {
18+
/// a();
19+
/// } else if x.is_negative() {
20+
/// b();
21+
/// }
22+
/// ```
23+
///
24+
/// Could be written:
25+
///
26+
/// ```rust
27+
/// if x.is_positive() {
28+
/// a();
29+
/// } else if x.is_negative() {
30+
/// b();
31+
/// } else {
32+
/// // we don't care about zero
33+
/// }
34+
/// ```
35+
declare_restriction_lint! {
36+
pub ELSE_IF_WITHOUT_ELSE,
37+
"if expression with an `else if`, but without a final `else` branch"
38+
}
39+
40+
#[derive(Copy, Clone)]
41+
pub struct ElseIfWithoutElse;
42+
43+
impl LintPass for ElseIfWithoutElse {
44+
fn get_lints(&self) -> LintArray {
45+
lint_array!(ELSE_IF_WITHOUT_ELSE)
46+
}
47+
}
48+
49+
impl EarlyLintPass for ElseIfWithoutElse {
50+
fn check_expr(&mut self, cx: &EarlyContext, mut item: &Expr) {
51+
if in_external_macro(cx, item.span) {
52+
return;
53+
}
54+
55+
while let ExprKind::If(_, _, Some(ref els)) = item.node {
56+
if let ExprKind::If(_, _, None) = els.node {
57+
span_lint_and_sugg(
58+
cx,
59+
ELSE_IF_WITHOUT_ELSE,
60+
els.span,
61+
"if expression with an `else if`, but without a final `else`",
62+
"add an `else` block here",
63+
"".to_string()
64+
);
65+
}
66+
67+
item = els;
68+
}
69+
}
70+
}

clippy_lints/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub mod derive;
8888
pub mod doc;
8989
pub mod double_parens;
9090
pub mod drop_forget_ref;
91+
pub mod else_if_without_else;
9192
pub mod empty_enum;
9293
pub mod entry;
9394
pub mod enum_clike;
@@ -329,6 +330,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
329330
reg.register_early_lint_pass(box formatting::Formatting);
330331
reg.register_late_lint_pass(box swap::Swap);
331332
reg.register_early_lint_pass(box if_not_else::IfNotElse);
333+
reg.register_early_lint_pass(box else_if_without_else::ElseIfWithoutElse);
332334
reg.register_early_lint_pass(box int_plus_one::IntPlusOne);
333335
reg.register_late_lint_pass(box overflow_check_conditional::OverflowCheckConditional);
334336
reg.register_late_lint_pass(box unused_label::UnusedLabel);
@@ -369,6 +371,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
369371
arithmetic::INTEGER_ARITHMETIC,
370372
array_indexing::INDEXING_SLICING,
371373
assign_ops::ASSIGN_OPS,
374+
else_if_without_else::ELSE_IF_WITHOUT_ELSE,
372375
misc::FLOAT_CMP_CONST,
373376
]);
374377

tests/ui/else_if_without_else.rs

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#![warn(clippy)]
2+
#![warn(else_if_without_else)]
3+
4+
fn bla1() -> bool { unimplemented!() }
5+
fn bla2() -> bool { unimplemented!() }
6+
fn bla3() -> bool { unimplemented!() }
7+
8+
fn main() {
9+
if bla1() {
10+
println!("if");
11+
}
12+
13+
if bla1() {
14+
println!("if");
15+
} else {
16+
println!("else");
17+
}
18+
19+
if bla1() {
20+
println!("if");
21+
} else if bla2() {
22+
println!("else if");
23+
} else {
24+
println!("else")
25+
}
26+
27+
if bla1() {
28+
println!("if");
29+
} else if bla2() {
30+
println!("else if 1");
31+
} else if bla3() {
32+
println!("else if 2");
33+
} else {
34+
println!("else")
35+
}
36+
37+
if bla1() {
38+
println!("if");
39+
} else if bla2() { //~ ERROR else if without else
40+
println!("else if");
41+
}
42+
43+
if bla1() {
44+
println!("if");
45+
} else if bla2() {
46+
println!("else if 1");
47+
} else if bla3() { //~ ERROR else if without else
48+
println!("else if 2");
49+
}
50+
}

tests/ui/else_if_without_else.stderr

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: if expression with an `else if`, but without a final `else`
2+
--> $DIR/else_if_without_else.rs:39:12
3+
|
4+
39 | } else if bla2() { //~ ERROR else if without else
5+
| ____________^
6+
40 | | println!("else if");
7+
41 | | }
8+
| |_____^ help: add an `else` block here
9+
|
10+
= note: `-D else-if-without-else` implied by `-D warnings`
11+
12+
error: if expression with an `else if`, but without a final `else`
13+
--> $DIR/else_if_without_else.rs:47:12
14+
|
15+
47 | } else if bla3() { //~ ERROR else if without else
16+
| ____________^
17+
48 | | println!("else if 2");
18+
49 | | }
19+
| |_____^ help: add an `else` block here
20+

0 commit comments

Comments
 (0)