Skip to content

Commit a8e5547

Browse files
Add [unary_parenthesis_followed_by_cast]
1 parent 015fb8a commit a8e5547

6 files changed

+94
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4967,6 +4967,7 @@ Released 2018-09-13
49674967
[`try_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#try_err
49684968
[`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity
49694969
[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds
4970+
[`unary_parenthesis_followed_by_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unary_parenthesis_followed_by_cast
49704971
[`unchecked_duration_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction
49714972
[`undocumented_unsafe_blocks`]: https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks
49724973
[`undropped_manually_drops`]: https://rust-lang.github.io/rust-clippy/master/index.html#undropped_manually_drops

clippy_lints/src/declared_lints.rs

+1
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
610610
crate::types::REDUNDANT_ALLOCATION_INFO,
611611
crate::types::TYPE_COMPLEXITY_INFO,
612612
crate::types::VEC_BOX_INFO,
613+
crate::unary_parenthesis_followed_by_cast::UNARY_PARENTHESIS_FOLLOWED_BY_CAST_INFO,
613614
crate::undocumented_unsafe_blocks::UNDOCUMENTED_UNSAFE_BLOCKS_INFO,
614615
crate::undocumented_unsafe_blocks::UNNECESSARY_SAFETY_COMMENT_INFO,
615616
crate::unicode::INVISIBLE_CHARACTERS_INFO,

clippy_lints/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ mod trailing_empty_array;
298298
mod trait_bounds;
299299
mod transmute;
300300
mod types;
301+
mod unary_parenthesis_followed_by_cast;
301302
mod undocumented_unsafe_blocks;
302303
mod unicode;
303304
mod uninit_vec;
@@ -960,6 +961,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
960961
store.register_late_pass(|_| Box::new(tests_outside_test_module::TestsOutsideTestModule));
961962
store.register_late_pass(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation));
962963
store.register_early_pass(|| Box::new(suspicious_doc_comments::SuspiciousDocComments));
964+
store.register_early_pass(|| Box::new(unary_parenthesis_followed_by_cast::UnaryParenthesisFollowedByCast));
963965
// add lints here, do not remove this comment, it's used in `new_lint`
964966
}
965967

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use clippy_utils::diagnostics::span_lint_and_help;
2+
use rustc_ast::ast::{Expr, ExprKind, Path};
3+
use rustc_ast::ast_traits::AstDeref;
4+
use rustc_ast::ptr::P;
5+
use rustc_lint::{EarlyContext, EarlyLintPass};
6+
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
8+
declare_clippy_lint! {
9+
/// ### What it does
10+
/// Checks for cast which argument is parenthesized variable.
11+
///
12+
/// ### Why is this bad?
13+
/// It's same effect as `variable as Type`, thus you don't need parentheses.
14+
///
15+
/// ### Example
16+
/// ```rust
17+
/// fn no_op(arg_1: f64) {}
18+
///
19+
/// let x = (1.0f32) as f64;
20+
/// let y = (2.0f32) as f64;
21+
/// no_op(y);
22+
/// ```
23+
/// Use instead:
24+
/// ```rust
25+
/// fn no_op(arg_1: f64) {}
26+
///
27+
/// let x = 1.0f32 as f64;
28+
/// let y = 2.0f32 as f64;
29+
/// no_op(y);
30+
/// ```
31+
#[clippy::version = "1.70.0"]
32+
pub UNARY_PARENTHESIS_FOLLOWED_BY_CAST,
33+
complexity,
34+
"default lint description"
35+
}
36+
declare_lint_pass!(UnaryParenthesisFollowedByCast => [UNARY_PARENTHESIS_FOLLOWED_BY_CAST]);
37+
38+
impl EarlyLintPass for UnaryParenthesisFollowedByCast {
39+
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
40+
if let ExprKind::Cast(ref expr, _) = expr.kind
41+
&& let ExprKind::Paren(ref parenthesized) = expr.kind
42+
&& is_item_path_is_local_and_not_qualified(parenthesized)
43+
{
44+
span_lint_and_help(
45+
cx,
46+
UNARY_PARENTHESIS_FOLLOWED_BY_CAST,
47+
expr.span,
48+
"unnecessary parenthesis",
49+
None,
50+
"consider remove parenthesis"
51+
);
52+
}
53+
}
54+
}
55+
56+
fn is_item_path_is_local_and_not_qualified(parenthesized: &P<Expr>) -> bool {
57+
if let ExprKind::Path(ref impl_qualifier, ref item_path) = parenthesized.ast_deref().kind
58+
&& impl_qualifier.is_none()
59+
// is item_path local variable?
60+
&& !item_path.is_global()
61+
&& let Path { segments, .. } = item_path
62+
&& segments.len() == 1 {
63+
true
64+
} else {
65+
false
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![allow(unused)]
2+
#![allow(clippy::unnecessary_cast)]
3+
#![warn(clippy::unary_parenthesis_followed_by_cast)]
4+
5+
fn hello(arg_1: f64) {}
6+
7+
fn main() {
8+
// fire
9+
let x = 3.0f32;
10+
11+
hello((x) as f64);
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: unnecessary parenthesis
2+
--> $DIR/unary_parenthesis_followed_by_cast.rs:11:11
3+
|
4+
LL | hello((x) as f64);
5+
| ^^^
6+
|
7+
= help: consider remove parenthesis
8+
= note: `-D clippy::unary-parenthesis-followed-by-cast` implied by `-D warnings`
9+
10+
error: aborting due to previous error
11+

0 commit comments

Comments
 (0)