-
Notifications
You must be signed in to change notification settings - Fork 11.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[move][move-linter] implement unnecessary while loop rules
- Loading branch information
Showing
8 changed files
with
126 additions
and
142 deletions.
There are no files selected for viewing
109 changes: 0 additions & 109 deletions
109
external-crates/move/crates/move-compiler/src/linters/shift_overflow.rs
This file was deleted.
Oops, something went wrong.
78 changes: 78 additions & 0 deletions
78
external-crates/move/crates/move-compiler/src/linters/unnecessary_while_loop.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
//! Encourages replacing `while(true)` with `loop` for infinite loops in Move for clarity and conciseness. | ||
//! Identifies `while(true)` patterns, suggesting a more idiomatic approach using `loop`. | ||
//! Aims to enhance code readability and adherence to Rust idioms. | ||
use crate::{ | ||
diag, | ||
diagnostics::{ | ||
codes::{custom, DiagnosticInfo, Severity}, | ||
WarningFilters, | ||
}, | ||
expansion::ast::Value_, | ||
shared::CompilationEnv, | ||
typing::{ | ||
ast::{self as T, UnannotatedExp_}, | ||
visitor::{TypingVisitorConstructor, TypingVisitorContext}, | ||
}, | ||
}; | ||
use move_ir_types::location::Loc; | ||
|
||
use super::{LinterDiagnosticCategory, LINT_WARNING_PREFIX, WHILE_TRUE_TO_LOOP_DIAG_CODE}; | ||
|
||
const WHILE_TRUE_TO_LOOP_DIAG: DiagnosticInfo = custom( | ||
LINT_WARNING_PREFIX, | ||
Severity::Warning, | ||
LinterDiagnosticCategory::Complexity as u8, | ||
WHILE_TRUE_TO_LOOP_DIAG_CODE, | ||
"", | ||
); | ||
|
||
pub struct WhileTrueToLoop; | ||
|
||
pub struct Context<'a> { | ||
env: &'a mut CompilationEnv, | ||
} | ||
|
||
impl TypingVisitorConstructor for WhileTrueToLoop { | ||
type Context<'a> = Context<'a>; | ||
|
||
fn context<'a>(env: &'a mut CompilationEnv, _program: &T::Program) -> Self::Context<'a> { | ||
Context { env } | ||
} | ||
} | ||
|
||
impl TypingVisitorContext for Context<'_> { | ||
fn visit_exp_custom(&mut self, exp: &mut T::Exp) -> bool { | ||
if let UnannotatedExp_::While(_, cond, _) = &exp.exp.value { | ||
if is_condition_always_true(&cond.exp.value) { | ||
report_while_true_to_loop(self.env, exp.exp.loc); | ||
} | ||
} | ||
false | ||
} | ||
fn add_warning_filter_scope(&mut self, filter: WarningFilters) { | ||
self.env.add_warning_filter_scope(filter) | ||
} | ||
|
||
fn pop_warning_filter_scope(&mut self) { | ||
self.env.pop_warning_filter_scope() | ||
} | ||
} | ||
|
||
fn is_condition_always_true(condition: &UnannotatedExp_) -> bool { | ||
if let UnannotatedExp_::Value(val) = condition { | ||
if let Value_::Bool(b) = &val.value { | ||
return *b; | ||
} | ||
} | ||
false | ||
} | ||
fn report_while_true_to_loop(env: &mut CompilationEnv, loc: Loc) { | ||
let diag = diag!( | ||
WHILE_TRUE_TO_LOOP_DIAG, | ||
( | ||
loc, | ||
"Detected `while(true) {}` loop. Consider replacing with `loop {}`" | ||
) | ||
); | ||
env.add_diag(diag); | ||
} |
24 changes: 0 additions & 24 deletions
24
external-crates/move/crates/move-compiler/tests/custom_rules/shift_overflow.exp
This file was deleted.
Oops, something went wrong.
9 changes: 0 additions & 9 deletions
9
external-crates/move/crates/move-compiler/tests/custom_rules/shift_overflow.move
This file was deleted.
Oops, something went wrong.
12 changes: 12 additions & 0 deletions
12
external-crates/move/crates/move-compiler/tests/linter/correct_unnecessary_while_loop.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module 0x42::M { | ||
|
||
public fun finite_loop() { | ||
let counter = 0; | ||
loop { | ||
if(counter == 10) { | ||
break | ||
}; | ||
counter = counter + 1; | ||
} | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
external-crates/move/crates/move-compiler/tests/linter/incorrect_unnecessary_while_loop.exp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
warning[Lint W01013]: | ||
┌─ tests/linter/incorrect_unnecessary_while_loop.move:5:9 | ||
│ | ||
5 │ ╭ while (true) { | ||
6 │ │ if(counter == 10) { | ||
7 │ │ break | ||
8 │ │ }; | ||
9 │ │ counter = counter + 1; | ||
10 │ │ } | ||
│ ╰─────────^ Detected `while(true) {}` loop. Consider replacing with `loop {}` | ||
│ | ||
= This warning can be suppressed with '#[allow(lint(unnecessary_while_loop))]' applied to the 'module' or module member ('const', 'fun', or 'struct') | ||
|
12 changes: 12 additions & 0 deletions
12
external-crates/move/crates/move-compiler/tests/linter/incorrect_unnecessary_while_loop.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module 0x42::M { | ||
|
||
public fun finite_loop() { | ||
let counter = 0; | ||
while (true) { | ||
if(counter == 10) { | ||
break | ||
}; | ||
counter = counter + 1; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters