Skip to content

Commit d377486

Browse files
committed
Auto merge of #4821 - Areredify:as_conversions, r=flip1995
Add `as_conversions` lint changelog: closes #4771, adding a new pedantic allow-by-default lint that lints against any usage of `as`.
2 parents d6accfc + 9ec8888 commit d377486

File tree

9 files changed

+106
-4
lines changed

9 files changed

+106
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,7 @@ Released 2018-09-13
929929
[`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons
930930
[`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped
931931
[`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
932+
[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
932933
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
933934
[`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern
934935
[`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

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

9-
[There are 337 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
9+
[There are 338 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
1010

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

clippy_lints/src/as_conversions.rs

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
2+
use rustc::{declare_lint_pass, declare_tool_lint};
3+
use syntax::ast::*;
4+
5+
use crate::utils::span_help_and_lint;
6+
7+
declare_clippy_lint! {
8+
/// **What it does:** Checks for usage of `as` conversions.
9+
///
10+
/// **Why is this bad?** `as` conversions will perform many kinds of
11+
/// conversions, including silently lossy conversions and dangerous coercions.
12+
/// There are cases when it makes sense to use `as`, so the lint is
13+
/// Allow by default.
14+
///
15+
/// **Known problems:** None.
16+
///
17+
/// **Example:**
18+
/// ```rust,ignore
19+
/// let a: u32;
20+
/// ...
21+
/// f(a as u16);
22+
/// ```
23+
///
24+
/// Usually better represents the semantics you expect:
25+
/// ```rust,ignore
26+
/// f(a.try_into()?);
27+
/// ```
28+
/// or
29+
/// ```rust,ignore
30+
/// f(a.try_into().expect("Unexpected u16 overflow in f"));
31+
/// ```
32+
///
33+
pub AS_CONVERSIONS,
34+
restriction,
35+
"using a potentially dangerous silent `as` conversion"
36+
}
37+
38+
declare_lint_pass!(AsConversions => [AS_CONVERSIONS]);
39+
40+
impl EarlyLintPass for AsConversions {
41+
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
42+
if in_external_macro(cx.sess(), expr.span) {
43+
return;
44+
}
45+
46+
if let ExprKind::Cast(_, _) = expr.kind {
47+
span_help_and_lint(
48+
cx,
49+
AS_CONVERSIONS,
50+
expr.span,
51+
"using a potentially dangerous silent `as` conversion",
52+
"consider using a safe wrapper for this conversion",
53+
);
54+
}
55+
}
56+
}

clippy_lints/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ mod utils;
156156
// begin lints modules, do not remove this comment, it’s used in `update_lints`
157157
pub mod approx_const;
158158
pub mod arithmetic;
159+
pub mod as_conversions;
159160
pub mod assertions_on_constants;
160161
pub mod assign_ops;
161162
pub mod attrs;
@@ -449,6 +450,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
449450
&approx_const::APPROX_CONSTANT,
450451
&arithmetic::FLOAT_ARITHMETIC,
451452
&arithmetic::INTEGER_ARITHMETIC,
453+
&as_conversions::AS_CONVERSIONS,
452454
&assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
453455
&assign_ops::ASSIGN_OP_PATTERN,
454456
&assign_ops::MISREFACTORED_ASSIGN_OP,
@@ -960,10 +962,12 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
960962
store.register_late_pass(|| box to_digit_is_some::ToDigitIsSome);
961963
let array_size_threshold = conf.array_size_threshold;
962964
store.register_late_pass(move || box large_stack_arrays::LargeStackArrays::new(array_size_threshold));
965+
store.register_early_pass(|| box as_conversions::AsConversions);
963966

964967
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
965968
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
966969
LintId::of(&arithmetic::INTEGER_ARITHMETIC),
970+
LintId::of(&as_conversions::AS_CONVERSIONS),
967971
LintId::of(&dbg_macro::DBG_MACRO),
968972
LintId::of(&else_if_without_else::ELSE_IF_WITHOUT_ELSE),
969973
LintId::of(&exit::EXIT),

src/lintlist/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub use lint::Lint;
66
pub use lint::LINT_LEVELS;
77

88
// begin lint list, do not remove this comment, it’s used in `update_lints`
9-
pub const ALL_LINTS: [Lint; 337] = [
9+
pub const ALL_LINTS: [Lint; 338] = [
1010
Lint {
1111
name: "absurd_extreme_comparisons",
1212
group: "correctness",
@@ -28,6 +28,13 @@ pub const ALL_LINTS: [Lint; 337] = [
2828
deprecation: None,
2929
module: "approx_const",
3030
},
31+
Lint {
32+
name: "as_conversions",
33+
group: "restriction",
34+
desc: "using a potentially dangerous silent `as` conversion",
35+
deprecation: None,
36+
module: "as_conversions",
37+
},
3138
Lint {
3239
name: "assertions_on_constants",
3340
group: "style",

tests/ui/as_conversions.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#[warn(clippy::as_conversions)]
2+
3+
fn main() {
4+
let i = 0u32 as u64;
5+
6+
let j = &i as *const u64 as *mut u64;
7+
}

tests/ui/as_conversions.stderr

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error: using a potentially dangerous silent `as` conversion
2+
--> $DIR/as_conversions.rs:4:13
3+
|
4+
LL | let i = 0u32 as u64;
5+
| ^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::as-conversions` implied by `-D warnings`
8+
= help: consider using a safe wrapper for this conversion
9+
10+
error: using a potentially dangerous silent `as` conversion
11+
--> $DIR/as_conversions.rs:6:13
12+
|
13+
LL | let j = &i as *const u64 as *mut u64;
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
|
16+
= help: consider using a safe wrapper for this conversion
17+
18+
error: using a potentially dangerous silent `as` conversion
19+
--> $DIR/as_conversions.rs:6:13
20+
|
21+
LL | let j = &i as *const u64 as *mut u64;
22+
| ^^^^^^^^^^^^^^^^
23+
|
24+
= help: consider using a safe wrapper for this conversion
25+
26+
error: aborting due to 3 previous errors
27+

tests/ui/types.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// run-rustfix
22

33
#![allow(dead_code, unused_variables)]
4-
#![warn(clippy::all, clippy::pedantic)]
4+
#![warn(clippy::cast_lossless)]
55

66
// should not warn on lossy casting in constant types
77
// because not supported yet

tests/ui/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// run-rustfix
22

33
#![allow(dead_code, unused_variables)]
4-
#![warn(clippy::all, clippy::pedantic)]
4+
#![warn(clippy::cast_lossless)]
55

66
// should not warn on lossy casting in constant types
77
// because not supported yet

0 commit comments

Comments
 (0)