Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add as_conversions lint #4821

Merged
merged 1 commit into from
Nov 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@ Released 2018-09-13
[`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons
[`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped
[`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
[`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern
[`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

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

[There are 337 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
[There are 338 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
56 changes: 56 additions & 0 deletions clippy_lints/src/as_conversions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
use syntax::ast::*;

use crate::utils::span_help_and_lint;

declare_clippy_lint! {
/// **What it does:** Checks for usage of `as` conversions.
///
/// **Why is this bad?** `as` conversions will perform many kinds of
/// conversions, including silently lossy conversions and dangerous coercions.
/// There are cases when it makes sense to use `as`, so the lint is
/// Allow by default.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust,ignore
/// let a: u32;
/// ...
/// f(a as u16);
/// ```
///
/// Usually better represents the semantics you expect:
/// ```rust,ignore
/// f(a.try_into()?);
/// ```
/// or
/// ```rust,ignore
/// f(a.try_into().expect("Unexpected u16 overflow in f"));
/// ```
///
pub AS_CONVERSIONS,
restriction,
"using a potentially dangerous silent `as` conversion"
}

declare_lint_pass!(AsConversions => [AS_CONVERSIONS]);

impl EarlyLintPass for AsConversions {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
if in_external_macro(cx.sess(), expr.span) {
return;
}

if let ExprKind::Cast(_, _) = expr.kind {
span_help_and_lint(
cx,
AS_CONVERSIONS,
expr.span,
"using a potentially dangerous silent `as` conversion",
"consider using a safe wrapper for this conversion",
);
}
}
}
4 changes: 4 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ mod utils;
// begin lints modules, do not remove this comment, it’s used in `update_lints`
pub mod approx_const;
pub mod arithmetic;
pub mod as_conversions;
pub mod assertions_on_constants;
pub mod assign_ops;
pub mod attrs;
Expand Down Expand Up @@ -448,6 +449,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
&approx_const::APPROX_CONSTANT,
&arithmetic::FLOAT_ARITHMETIC,
&arithmetic::INTEGER_ARITHMETIC,
&as_conversions::AS_CONVERSIONS,
&assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
&assign_ops::ASSIGN_OP_PATTERN,
&assign_ops::MISREFACTORED_ASSIGN_OP,
Expand Down Expand Up @@ -959,10 +961,12 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
store.register_late_pass(|| box to_digit_is_some::ToDigitIsSome);
let array_size_threshold = conf.array_size_threshold;
store.register_late_pass(move || box large_stack_arrays::LargeStackArrays::new(array_size_threshold));
store.register_early_pass(|| box as_conversions::AsConversions);

store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
LintId::of(&arithmetic::INTEGER_ARITHMETIC),
LintId::of(&as_conversions::AS_CONVERSIONS),
LintId::of(&dbg_macro::DBG_MACRO),
LintId::of(&else_if_without_else::ELSE_IF_WITHOUT_ELSE),
LintId::of(&exit::EXIT),
Expand Down
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; 337] = [
pub const ALL_LINTS: [Lint; 338] = [
Lint {
name: "absurd_extreme_comparisons",
group: "correctness",
Expand All @@ -28,6 +28,13 @@ pub const ALL_LINTS: [Lint; 337] = [
deprecation: None,
module: "approx_const",
},
Lint {
name: "as_conversions",
group: "restriction",
desc: "using a potentially dangerous silent `as` conversion",
deprecation: None,
module: "as_conversions",
},
Lint {
name: "assertions_on_constants",
group: "style",
Expand Down
7 changes: 7 additions & 0 deletions tests/ui/as_conversions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#[warn(clippy::as_conversions)]

fn main() {
let i = 0u32 as u64;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing macro test cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I'll open a follow-up pr

let j = &i as *const u64 as *mut u64;
}
27 changes: 27 additions & 0 deletions tests/ui/as_conversions.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error: using a potentially dangerous silent `as` conversion
--> $DIR/as_conversions.rs:4:13
|
LL | let i = 0u32 as u64;
| ^^^^^^^^^^^
|
= note: `-D clippy::as-conversions` implied by `-D warnings`
= help: consider using a safe wrapper for this conversion

error: using a potentially dangerous silent `as` conversion
--> $DIR/as_conversions.rs:6:13
|
LL | let j = &i as *const u64 as *mut u64;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider using a safe wrapper for this conversion

error: using a potentially dangerous silent `as` conversion
--> $DIR/as_conversions.rs:6:13
|
LL | let j = &i as *const u64 as *mut u64;
| ^^^^^^^^^^^^^^^^
|
= help: consider using a safe wrapper for this conversion

error: aborting due to 3 previous errors

2 changes: 1 addition & 1 deletion tests/ui/types.fixed
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// run-rustfix

#![allow(dead_code, unused_variables)]
#![warn(clippy::all, clippy::pedantic)]
#![warn(clippy::cast_lossless)]

// should not warn on lossy casting in constant types
// because not supported yet
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// run-rustfix

#![allow(dead_code, unused_variables)]
#![warn(clippy::all, clippy::pedantic)]
#![warn(clippy::cast_lossless)]

// should not warn on lossy casting in constant types
// because not supported yet
Expand Down