Skip to content

Commit ebd357e

Browse files
committed
Auto merge of #8934 - DevAccentor:as_underscore, r=Manishearth
add [`as_underscore`] lint closes #8847 detect usage of `as _` and enforce the usage of explicit type like ```rust fn foo(n: usize) {} let n: u16 = 256; foo(n as _); ``` will suggest to change to ```rust fn foo(n: usize) {} let n: u16 = 256; foo(n as usize); ``` changelog: add [`as_underscore`] lint
2 parents 7c0d649 + 64fe4e3 commit ebd357e

8 files changed

+125
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3280,6 +3280,7 @@ Released 2018-09-13
32803280
[`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped
32813281
[`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
32823282
[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
3283+
[`as_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_underscore
32833284
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
32843285
[`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern
32853286
[`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops

clippy_lints/src/as_underscore.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
2+
use rustc_errors::Applicability;
3+
use rustc_hir::{Expr, ExprKind, TyKind};
4+
use rustc_lint::{LateContext, LateLintPass, LintContext};
5+
use rustc_middle::lint::in_external_macro;
6+
use rustc_middle::ty;
7+
use rustc_session::{declare_lint_pass, declare_tool_lint};
8+
9+
declare_clippy_lint! {
10+
/// ### What it does
11+
/// Check for the usage of `as _` conversion using inferred type.
12+
///
13+
/// ### Why is this bad?
14+
/// The conversion might include lossy conversion and dangerous cast that might go
15+
/// undetected du to the type being inferred.
16+
///
17+
/// The lint is allowed by default as using `_` is less wordy than always specifying the type.
18+
///
19+
/// ### Example
20+
/// ```rust
21+
/// fn foo(n: usize) {}
22+
/// let n: u16 = 256;
23+
/// foo(n as _);
24+
/// ```
25+
/// Use instead:
26+
/// ```rust
27+
/// fn foo(n: usize) {}
28+
/// let n: u16 = 256;
29+
/// foo(n as usize);
30+
/// ```
31+
#[clippy::version = "1.63.0"]
32+
pub AS_UNDERSCORE,
33+
restriction,
34+
"detects `as _` conversion"
35+
}
36+
declare_lint_pass!(AsUnderscore => [AS_UNDERSCORE]);
37+
38+
impl<'tcx> LateLintPass<'tcx> for AsUnderscore {
39+
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
40+
if in_external_macro(cx.sess(), expr.span) {
41+
return;
42+
}
43+
44+
if let ExprKind::Cast(_, ty) = expr.kind && let TyKind::Infer = ty.kind {
45+
46+
let ty_resolved = cx.typeck_results().expr_ty(expr);
47+
if let ty::Error(_) = ty_resolved.kind() {
48+
span_lint_and_help(
49+
cx,
50+
AS_UNDERSCORE,
51+
expr.span,
52+
"using `as _` conversion",
53+
None,
54+
"consider giving the type explicitly",
55+
);
56+
} else {
57+
span_lint_and_then(
58+
cx,
59+
AS_UNDERSCORE,
60+
expr.span,
61+
"using `as _` conversion",
62+
|diag| {
63+
diag.span_suggestion(
64+
ty.span,
65+
"consider giving the type explicitly",
66+
format!("{}", ty_resolved),
67+
Applicability::MachineApplicable,
68+
);
69+
}
70+
);
71+
}
72+
}
73+
}
74+
}

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ store.register_lints(&[
3737
almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE,
3838
approx_const::APPROX_CONSTANT,
3939
as_conversions::AS_CONVERSIONS,
40+
as_underscore::AS_UNDERSCORE,
4041
asm_syntax::INLINE_ASM_X86_ATT_SYNTAX,
4142
asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX,
4243
assertions_on_constants::ASSERTIONS_ON_CONSTANTS,

clippy_lints/src/lib.register_restriction.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
66
LintId::of(as_conversions::AS_CONVERSIONS),
7+
LintId::of(as_underscore::AS_UNDERSCORE),
78
LintId::of(asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
89
LintId::of(asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
910
LintId::of(attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON),

clippy_lints/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ mod absurd_extreme_comparisons;
171171
mod almost_complete_letter_range;
172172
mod approx_const;
173173
mod as_conversions;
174+
mod as_underscore;
174175
mod asm_syntax;
175176
mod assertions_on_constants;
176177
mod assign_ops;
@@ -919,6 +920,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
919920
store.register_early_pass(move || Box::new(almost_complete_letter_range::AlmostCompleteLetterRange::new(msrv)));
920921
store.register_late_pass(|| Box::new(swap_ptr_to_ref::SwapPtrToRef));
921922
store.register_late_pass(|| Box::new(mismatching_type_param_order::TypeParamMismatch));
923+
store.register_late_pass(|| Box::new(as_underscore::AsUnderscore));
922924
// add lints here, do not remove this comment, it's used in `new_lint`
923925
}
924926

tests/ui/as_underscore.fixed

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// run-rustfix
2+
3+
#![warn(clippy::as_underscore)]
4+
5+
fn foo(_n: usize) {}
6+
7+
fn main() {
8+
let n: u16 = 256;
9+
foo(n as usize);
10+
11+
let n = 0_u128;
12+
let _n: u8 = n as u8;
13+
}

tests/ui/as_underscore.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// run-rustfix
2+
3+
#![warn(clippy::as_underscore)]
4+
5+
fn foo(_n: usize) {}
6+
7+
fn main() {
8+
let n: u16 = 256;
9+
foo(n as _);
10+
11+
let n = 0_u128;
12+
let _n: u8 = n as _;
13+
}

tests/ui/as_underscore.stderr

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: using `as _` conversion
2+
--> $DIR/as_underscore.rs:9:9
3+
|
4+
LL | foo(n as _);
5+
| ^^^^^-
6+
| |
7+
| help: consider giving the type explicitly: `usize`
8+
|
9+
= note: `-D clippy::as-underscore` implied by `-D warnings`
10+
11+
error: using `as _` conversion
12+
--> $DIR/as_underscore.rs:12:18
13+
|
14+
LL | let _n: u8 = n as _;
15+
| ^^^^^-
16+
| |
17+
| help: consider giving the type explicitly: `u8`
18+
19+
error: aborting due to 2 previous errors
20+

0 commit comments

Comments
 (0)