Skip to content

Commit cdc8722

Browse files
committed
Add a lint pass to check for while true { ... } loops
And suggest changing them to loop { ... }. Had to fix the few remaining while true loops (in core::io). Closes #1962.
1 parent 594d22e commit cdc8722

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

src/libcore/io.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl reader_util for reader {
110110

111111
fn read_line() -> str {
112112
let mut buf: [u8] = [];
113-
while true {
113+
loop {
114114
let ch = self.read_byte();
115115
if ch == -1 || ch == 10 { break; }
116116
buf += [ch as u8];
@@ -120,7 +120,7 @@ impl reader_util for reader {
120120

121121
fn read_c_str() -> str {
122122
let mut buf: [u8] = [];
123-
while true {
123+
loop {
124124
let ch = self.read_byte();
125125
if ch < 1 { break; } else { buf += [ch as u8]; }
126126
}

src/rustc/middle/lint.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,26 @@ import syntax::attr;
55
import syntax::codemap::span;
66
import std::map::{map,hashmap,hash_from_strs};
77
import io::writer_util;
8+
import syntax::print::pprust::expr_to_str;
89

910
export lint, ctypes, unused_imports;
1011
export level, ignore, warn, error;
1112
export lookup_lint, lint_dict, get_lint_dict, check_crate;
1213

1314
#[doc="
1415
15-
A 'lint' check is a kind of miscallaneous constraint that a user _might_ want
16+
A 'lint' check is a kind of miscellaneous constraint that a user _might_ want
1617
to enforce, but might reasonably want to permit as well, on a module-by-module
1718
basis. They contrast with static constraints enforced by other phases of the
1819
compiler, which are generally required to hold in order to compile the program
19-
correctly at all.
20+
at all.
2021
2122
"]
2223

2324
enum lint {
2425
ctypes,
2526
unused_imports,
27+
while_true
2628
}
2729

2830
enum level {
@@ -35,6 +37,10 @@ type lint_spec = @{lint: lint,
3537

3638
type lint_dict = hashmap<str,lint_spec>;
3739

40+
/*
41+
Pass names should not contain a '-', as the compiler normalizes
42+
'-' to '_' in command-line flags
43+
*/
3844
fn get_lint_dict() -> lint_dict {
3945
let v = [
4046
("ctypes",
@@ -45,7 +51,12 @@ fn get_lint_dict() -> lint_dict {
4551
("unused_imports",
4652
@{lint: unused_imports,
4753
desc: "imports that are never used",
48-
default: ignore})
54+
default: ignore}),
55+
56+
("while_true",
57+
@{lint: while_true,
58+
desc: "suggest using loop { } instead of while(true) { }",
59+
default: warn})
4960
];
5061
hash_from_strs(v)
5162
}
@@ -165,11 +176,34 @@ fn check_item(cx: ctxt, i: @ast::item) {
165176
alt lint {
166177
ctypes { check_item_ctypes(cx, level, i); }
167178
unused_imports { check_item_unused_imports(cx, level, i); }
179+
while_true { check_item_while_true(cx, level, i); }
168180
}
169181
}
170182
}
171183
}
172184

185+
fn check_item_while_true(cx: ctxt, level: level, it: @ast::item) {
186+
let visit = visit::mk_simple_visitor(@{
187+
visit_expr: fn@(e: @ast::expr) {
188+
alt e.node {
189+
ast::expr_while(cond, _) {
190+
alt cond.node {
191+
ast::expr_lit(@{node: ast::lit_bool(true),_}) {
192+
cx.span_lint(
193+
level, e.span,
194+
"Denote infinite loops with loop { ... }");
195+
}
196+
_ {}
197+
}
198+
}
199+
_ {}
200+
}
201+
}
202+
with *visit::default_simple_visitor()
203+
});
204+
visit::visit_item(it, (), visit);
205+
}
206+
173207
fn check_item_unused_imports(_cx: ctxt, _level: level, _it: @ast::item) {
174208
// FIXME: Don't know how to check this in lint yet, it's currently being
175209
// done over in resolve. When resolve is rewritten, do it here instead.

src/test/compile-fail/issue-1962.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// compile-flags: -W err-while-true
2+
fn main() {
3+
let mut i = 0;
4+
while true { //! ERROR Denote infinite loops with loop
5+
i += 1;
6+
if i == 5 { break; }
7+
}
8+
}

0 commit comments

Comments
 (0)