]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/as_underscore.rs
Auto merge of #9148 - arieluy:then_some_unwrap_or, r=Jarcho
[rust.git] / clippy_lints / src / as_underscore.rs
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                         ty_resolved,
67                         Applicability::MachineApplicable,
68                     );
69             }
70             );
71         }
72         }
73     }
74 }