Skip to content

Commit

Permalink
Add lint for use of ^ operator as pow.
Browse files Browse the repository at this point in the history
  • Loading branch information
KamilaBorowska committed Jun 17, 2019
1 parent be5d17f commit b009aef
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,7 @@ All notable changes to this project will be documented in this file.
[`wrong_pub_self_convention`]: https://rust-lang.github.io/rust-clippy/master/index.html#wrong_pub_self_convention
[`wrong_self_convention`]: https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention
[`wrong_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#wrong_transmute
[`xor_used_as_pow`]: https://rust-lang.github.io/rust-clippy/master/index.html#xor_used_as_pow
[`zero_divided_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_divided_by_zero
[`zero_prefixed_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_prefixed_literal
[`zero_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.

[There are 305 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
[There are 306 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)

We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:

Expand Down
4 changes: 4 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ pub mod use_self;
pub mod vec;
pub mod wildcard_dependencies;
pub mod write;
pub mod xor_used_as_pow;
pub mod zero_div_zero;
// end lints modules, do not remove this comment, it’s used in `update_lints`

Expand Down Expand Up @@ -582,6 +583,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
reg.register_late_lint_pass(box path_buf_push_overwrite::PathBufPushOverwrite);
reg.register_late_lint_pass(box checked_conversions::CheckedConversions);
reg.register_late_lint_pass(box integer_division::IntegerDivision);
reg.register_early_lint_pass(box xor_used_as_pow::XorUsedAsPow);

reg.register_lint_group("clippy::restriction", Some("clippy_restriction"), vec![
arithmetic::FLOAT_ARITHMETIC,
Expand Down Expand Up @@ -889,6 +891,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
write::WRITELN_EMPTY_STRING,
write::WRITE_LITERAL,
write::WRITE_WITH_NEWLINE,
xor_used_as_pow::XOR_USED_AS_POW,
zero_div_zero::ZERO_DIVIDED_BY_ZERO,
]);

Expand Down Expand Up @@ -1105,6 +1108,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
types::UNIT_CMP,
unicode::ZERO_WIDTH_SPACE,
unused_io_amount::UNUSED_IO_AMOUNT,
xor_used_as_pow::XOR_USED_AS_POW,
]);

reg.register_lint_group("clippy::perf", Some("clippy_perf"), vec![
Expand Down
54 changes: 54 additions & 0 deletions clippy_lints/src/xor_used_as_pow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::utils::span_lint_and_sugg;
use if_chain::if_chain;
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
use rustc_errors::Applicability;
use syntax::ast::{BinOpKind, Expr, ExprKind, LitKind};

declare_clippy_lint! {
/// **What it does:** Checks for use of `^` operator when pow was intended.
///
/// **Why is this bad?** This is most probably a typo.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust,ignore
/// // Bad
/// 2 ^ 16;
///
/// // Good
/// 1 << 16;
/// 2i32.pow(16);
/// ```
pub XOR_USED_AS_POW,
correctness,
"use of `^` operator when pow was intended"
}

declare_lint_pass!(XorUsedAsPow => [XOR_USED_AS_POW]);

impl EarlyLintPass for XorUsedAsPow {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
if_chain! {
if let ExprKind::Binary(op, left, right) = &expr.node;
if BinOpKind::BitXor == op.node;
if let ExprKind::Lit(lit) = &left.node;
if let LitKind::Int(2, _) = lit.node;
if let ExprKind::Lit(lit) = &right.node;
if let LitKind::Int(right, _) = lit.node;
then {
span_lint_and_sugg(
cx,
XOR_USED_AS_POW,
expr.span,
"`^` is not a pow operator but was used as one",
"did you mean to write",
format!("1 << {}", right),
Applicability::MaybeIncorrect,
)
}
}
}
}
9 changes: 8 additions & 1 deletion src/lintlist/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use lint::Lint;
pub use lint::LINT_LEVELS;

// begin lint list, do not remove this comment, it’s used in `update_lints`
pub const ALL_LINTS: [Lint; 305] = [
pub const ALL_LINTS: [Lint; 306] = [
Lint {
name: "absurd_extreme_comparisons",
group: "correctness",
Expand Down Expand Up @@ -2114,6 +2114,13 @@ pub const ALL_LINTS: [Lint; 305] = [
deprecation: None,
module: "transmute",
},
Lint {
name: "xor_used_as_pow",
group: "correctness",
desc: "use of `^` operator when pow was intended",
deprecation: None,
module: "xor_used_as_pow",
},
Lint {
name: "zero_divided_by_zero",
group: "complexity",
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/xor_used_as_pow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![warn(clippy::xor_used_as_pow)]

fn main() {
println!("{}", 2 ^ 16);
// Should be allowed
let x = 16;
println!("{}", 2 ^ x);
let y = 2;
println!("{}", y ^ 16);
}
10 changes: 10 additions & 0 deletions tests/ui/xor_used_as_pow.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: `^` is not a pow operator but was used as one
--> $DIR/xor_used_as_pow.rs:4:20
|
LL | println!("{}", 2 ^ 16);
| ^^^^^^ help: did you mean to write: `1 << 16`
|
= note: `-D clippy::xor-used-as-pow` implied by `-D warnings`

error: aborting due to previous error

0 comments on commit b009aef

Please sign in to comment.