Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions third_party/move/tools/move-linter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ publish = { workspace = true }
repository = { workspace = true }
rust-version = { workspace = true }

[lib]
doctest = false

[features]
default = []

[dependencies]
codespan-reporting = { workspace = true }
legacy-move-compiler = { workspace = true }
Expand All @@ -25,12 +31,6 @@ num = { workspace = true }
datatest-stable = { workspace = true }
move-prover-test-utils = { workspace = true }

[features]
default = []

[[test]]
name = "testsuite"
harness = false

[lib]
doctest = false
2 changes: 2 additions & 0 deletions third_party/move/tools/move-linter/src/model_ast_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod almost_swapped;
mod assert_const;
mod blocks_in_conditions;
mod cyclomatic_complexity;
mod empty_if;
mod equal_operands_in_bin_op;
mod find_unnecessary_casts;
mod known_to_abort;
Expand All @@ -34,6 +35,7 @@ pub fn get_default_linter_pipeline(config: &BTreeMap<String, String>) -> Vec<Box
Box::<almost_swapped::AlmostSwapped>::default(),
Box::<assert_const::AssertConst>::default(),
Box::<blocks_in_conditions::BlocksInConditions>::default(),
Box::<empty_if::EmptyIf>::default(),
Box::<equal_operands_in_bin_op::EqualOperandsInBinOp>::default(),
Box::<find_unnecessary_casts::FindUnnecessaryCasts>::default(),
Box::<known_to_abort::KnownToAbort>::default(),
Expand Down
58 changes: 58 additions & 0 deletions third_party/move/tools/move-linter/src/model_ast_lints/empty_if.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) Aptos Foundation
// SPDX-License-Identifier: Apache-2.0

//! This module implements an expression linter that checks for empty `else` branches
//! public fun empty_if(x: u64): u64 {
//! if (x > 35) { // <----
//! } else {
//! x = x + 1;
//! };
//! x
//! }

use move_compiler_v2::external_checks::ExpChecker;
use move_model::{
ast::{ExpData, Operation},
model::FunctionEnv,
};

#[derive(Default)]
pub struct EmptyIf;

impl ExpChecker for EmptyIf {
fn get_name(&self) -> String {
"empty_if".to_string()
}

fn visit_expr_pre(&mut self, function: &FunctionEnv, expr: &ExpData) {
let ExpData::IfElse(full_nid, .., if_branch, else_branch) = expr else {
return;
};

let ExpData::Call(_, Operation::Tuple, args) = if_branch.as_ref() else {
return;
};

if !args.is_empty() {
return;
}

if let ExpData::Call(_, Operation::Abort, _) = else_branch.as_ref() {
return;
}

let genv = function.env();

let message = match else_branch.as_ref() {
ExpData::Call(.., Operation::Tuple, eargs) if eargs.is_empty() => {
"Empty `if` branch. Consider simplifying by removing or rewriting."
},
ExpData::LoopCont(_, _, _) => {
return;
},
_ => "Empty `if` branch. Consider simplifying this `if-else`.",
};

self.report(genv, &genv.get_node_loc(*full_nid), message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ warning: [lint] This looks like a swap, but one assignment overwrites the other.
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(almost_swapped)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#almost_swapped.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/almost_swapped.move:13:5
13 │ if (y == x) ();
│ ^^^^^^^^^^^^^^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] This looks like a swap, but one assignment overwrites the other.
┌─ tests/model_ast_lints/almost_swapped.move:19:5
Expand All @@ -20,6 +29,15 @@ warning: [lint] This looks like a swap, but one assignment overwrites the other.
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(almost_swapped)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#almost_swapped.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/almost_swapped.move:21:5
21 │ if (x2 == x1) ();
│ ^^^^^^^^^^^^^^^^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] This looks like a swap, but one assignment overwrites the other.
┌─ tests/model_ast_lints/almost_swapped.move:27:5
Expand Down Expand Up @@ -70,6 +88,15 @@ warning: [lint] This looks like a swap, but one assignment overwrites the other.
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(almost_swapped)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#almost_swapped.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/almost_swapped.move:54:5
54 │ if (y2 == y1) ();
│ ^^^^^^^^^^^^^^^^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] This looks like a swap, but one assignment overwrites the other.
┌─ tests/model_ast_lints/almost_swapped.move:61:5
Expand Down Expand Up @@ -100,6 +127,15 @@ warning: [lint] This looks like a swap, but one assignment overwrites the other.
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(almost_swapped)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#almost_swapped.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/almost_swapped.move:74:5
74 │ if (y4 == y3) ()
│ ^^^^^^^^^^^^^^^^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] This looks like a swap, but one assignment overwrites the other.
┌─ tests/model_ast_lints/almost_swapped.move:80:5
Expand Down Expand Up @@ -130,6 +166,15 @@ warning: [lint] This looks like a swap, but one assignment overwrites the other.
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(almost_swapped)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#almost_swapped.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/almost_swapped.move:90:5
90 │ if (y == x) ();
│ ^^^^^^^^^^^^^^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] This looks like a swap, but one assignment overwrites the other.
┌─ tests/model_ast_lints/almost_swapped.move:98:5
Expand All @@ -140,6 +185,15 @@ warning: [lint] This looks like a swap, but one assignment overwrites the other.
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(almost_swapped)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#almost_swapped.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/almost_swapped.move:100:5
100 │ if (v1 == v2) ();
│ ^^^^^^^^^^^^^^^^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] This looks like a swap, but one assignment overwrites the other.
┌─ tests/model_ast_lints/almost_swapped.move:111:5
Expand All @@ -149,3 +203,30 @@ warning: [lint] This looks like a swap, but one assignment overwrites the other.
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(almost_swapped)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#almost_swapped.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/almost_swapped.move:120:5
120 │ if (y == x) ();
│ ^^^^^^^^^^^^^^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/almost_swapped.move:153:5
153 │ if (x2 == x1) ();
│ ^^^^^^^^^^^^^^^^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/almost_swapped.move:162:5
162 │ if (y == x) ();
│ ^^^^^^^^^^^^^^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

Diagnostics:
warning: [lint] Empty `if` branch. Consider simplifying this `if-else`.
┌─ tests/model_ast_lints/empty_if.move:4:9
4 │ ╭ if (x > 0) {
5 │ │ } else {
6 │ │ return;
7 │ │ };
│ ╰─────────^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/empty_if.move:11:9
11 │ ╭ if (x > 0) {
12 │ │ };
│ ╰─────────^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/empty_if.move:23:9
23 │ ╭ if (x > 0) {
24 │ │ ()
25 │ │ };
│ ╰─────────^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/empty_if.move:30:9
30 │ ╭ if (x > 35) {
31 │ │ } else { };
│ ╰──────────────────^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] Empty `if` branch. Consider simplifying this `if-else`.
┌─ tests/model_ast_lints/empty_if.move:36:9
36 │ ╭ if (x > 35) {
37 │ │ } else {
38 │ │ return 2;
39 │ │ };
│ ╰──────────^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
module 0xc0ffee::m {

public fun empty_if(x: u64) {
if (x > 0) {
} else {
return;
};
}

public fun empty_if_no_else(x: u64) {
if (x > 0) {
};
}

public fun non_empty_if(x: u64): u64 {
if (x > 0) {
x = x + 1;
};
x
}

public fun empty_if_with_void(x: u64): u64 {
if (x > 0) {
()
};
x
}

public fun empty_if_with_empty_else(x: u64): u64 {
if (x > 35) {
} else { };
0
}

public fun empty_if_with_non_empty_else(x: u64): u64 {
if (x > 35) {
} else {
return 2;
};
0
}

public fun aborts(x: u64) {
assert!(x > 10);
}


#[lint::skip(empty_if)]
public fun skip_empty_if(x: u64) {
if (x > 0) {
} else {
abort(0)
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ warning: [lint] Unnecessary cast: the expression is already of the target type.
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(find_unnecessary_casts)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#find_unnecessary_casts.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/find_unnecessary_casts_test.move:38:9
38 │ if ((x as u64) > 0) { };
│ ^^^^^^^^^^^^^^^^^^^^^^^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] Unnecessary cast: the expression is already of the target type. Consider removing the cast for better readability.
┌─ tests/model_ast_lints/find_unnecessary_casts_test.move:43:17
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@

Diagnostics:
warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/multi_attributes_01.move:4:9
4 │ ╭ if ({let y = x + 1; y < 5}) {
5 │ │ // do nothing
6 │ │ };
│ ╰─────────^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] Having blocks in conditions make code harder to read. Consider rewriting this code.
┌─ tests/model_ast_lints/multi_attributes_01.move:13:13
Expand All @@ -9,6 +20,17 @@ warning: [lint] Having blocks in conditions make code harder to read. Consider r
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(blocks_in_conditions)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#blocks_in_conditions.

warning: [lint] Empty `if` branch. Consider simplifying by removing or rewriting.
┌─ tests/model_ast_lints/multi_attributes_01.move:13:9
13 │ ╭ if ({let y = x + 1; y < 5}) {
14 │ │ // do nothing
15 │ │ };
│ ╰─────────^
= To suppress this warning, annotate the function/module with the attribute `#[lint::skip(empty_if)]`.
= For more information, see https://aptos.dev/en/build/smart-contracts/linter#empty_if.

warning: [lint] Use the more explicit `loop` instead.
┌─ tests/model_ast_lints/multi_attributes_01.move:16:9
Expand Down
Loading
Loading