Skip to content

Commit a31dcb7

Browse files
committed
Auto merge of rust-lang#8562 - Jarcho:enum_tuple_variant_as_int, r=Manishearth
Add lint `cast_enum_constructor` fixes: rust-lang#1116 changelog: Add lint `cast_enum_constructor`
2 parents 9fd3c2d + 39329d1 commit a31dcb7

8 files changed

+79
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3069,6 +3069,7 @@ Released 2018-09-13
30693069
[`bytes_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#bytes_nth
30703070
[`cargo_common_metadata`]: https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata
30713071
[`case_sensitive_file_extension_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#case_sensitive_file_extension_comparisons
3072+
[`cast_enum_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_enum_constructor
30723073
[`cast_enum_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_enum_truncation
30733074
[`cast_lossless`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless
30743075
[`cast_possible_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_possible_truncation
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use clippy_utils::diagnostics::span_lint;
2+
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
3+
use rustc_hir::{Expr, ExprKind};
4+
use rustc_lint::LateContext;
5+
use rustc_middle::ty::{self, Ty};
6+
7+
use super::CAST_ENUM_CONSTRUCTOR;
8+
9+
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>) {
10+
if matches!(cast_from.kind(), ty::FnDef(..))
11+
&& let ExprKind::Path(path) = &cast_expr.kind
12+
&& let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), _) = cx.qpath_res(path, cast_expr.hir_id)
13+
{
14+
span_lint(
15+
cx,
16+
CAST_ENUM_CONSTRUCTOR,
17+
expr.span,
18+
"cast of an enum tuple constructor to an integer",
19+
);
20+
}
21+
}

clippy_lints/src/casts/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod cast_enum_constructor;
12
mod cast_lossless;
23
mod cast_possible_truncation;
34
mod cast_possible_wrap;
@@ -454,6 +455,24 @@ declare_clippy_lint! {
454455
"casting using `as` between raw pointers to slices of types with different sizes"
455456
}
456457

458+
declare_clippy_lint! {
459+
/// ### What it does
460+
/// Checks for casts from an enum tuple constructor to an integer.
461+
///
462+
/// ### Why is this bad?
463+
/// The cast is easily confused with casting a c-like enum value to an integer.
464+
///
465+
/// ### Example
466+
/// ```rust
467+
/// enum E { X(i32) };
468+
/// let _ = E::X as usize;
469+
/// ```
470+
#[clippy::version = "1.61.0"]
471+
pub CAST_ENUM_CONSTRUCTOR,
472+
suspicious,
473+
"casts from an enum tuple constructor to an integer"
474+
}
475+
457476
pub struct Casts {
458477
msrv: Option<RustcVersion>,
459478
}
@@ -481,6 +500,7 @@ impl_lint_pass!(Casts => [
481500
CHAR_LIT_AS_U8,
482501
PTR_AS_PTR,
483502
CAST_ENUM_TRUNCATION,
503+
CAST_ENUM_CONSTRUCTOR
484504
]);
485505

486506
impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -518,6 +538,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
518538
cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to);
519539
}
520540
cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv);
541+
cast_enum_constructor::check(cx, expr, cast_expr, cast_from);
521542
}
522543
}
523544

clippy_lints/src/lib.register_all.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
2323
LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
2424
LintId::of(booleans::LOGIC_BUG),
2525
LintId::of(booleans::NONMINIMAL_BOOL),
26+
LintId::of(casts::CAST_ENUM_CONSTRUCTOR),
2627
LintId::of(casts::CAST_ENUM_TRUNCATION),
2728
LintId::of(casts::CAST_REF_TO_MUT),
2829
LintId::of(casts::CAST_SLICE_DIFFERENT_SIZES),

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ store.register_lints(&[
7070
cargo::REDUNDANT_FEATURE_NAMES,
7171
cargo::WILDCARD_DEPENDENCIES,
7272
case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
73+
casts::CAST_ENUM_CONSTRUCTOR,
7374
casts::CAST_ENUM_TRUNCATION,
7475
casts::CAST_LOSSLESS,
7576
casts::CAST_POSSIBLE_TRUNCATION,

clippy_lints/src/lib.register_suspicious.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec!
77
LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
88
LintId::of(await_holding_invalid::AWAIT_HOLDING_LOCK),
99
LintId::of(await_holding_invalid::AWAIT_HOLDING_REFCELL_REF),
10+
LintId::of(casts::CAST_ENUM_CONSTRUCTOR),
1011
LintId::of(casts::CAST_ENUM_TRUNCATION),
1112
LintId::of(eval_order_dependence::EVAL_ORDER_DEPENDENCE),
1213
LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),

tests/ui/cast_enum_constructor.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![warn(clippy::cast_enum_constructor)]
2+
#![allow(clippy::fn_to_numeric_cast)]
3+
4+
fn main() {
5+
enum Foo {
6+
Y(u32),
7+
}
8+
9+
enum Bar {
10+
X,
11+
}
12+
13+
let _ = Foo::Y as usize;
14+
let _ = Foo::Y as isize;
15+
let _ = Foo::Y as fn(u32) -> Foo;
16+
let _ = Bar::X as usize;
17+
}

tests/ui/cast_enum_constructor.stderr

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: cast of an enum tuple constructor to an integer
2+
--> $DIR/cast_enum_constructor.rs:13:13
3+
|
4+
LL | let _ = Foo::Y as usize;
5+
| ^^^^^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::cast-enum-constructor` implied by `-D warnings`
8+
9+
error: cast of an enum tuple constructor to an integer
10+
--> $DIR/cast_enum_constructor.rs:14:13
11+
|
12+
LL | let _ = Foo::Y as isize;
13+
| ^^^^^^^^^^^^^^^
14+
15+
error: aborting due to 2 previous errors
16+

0 commit comments

Comments
 (0)