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;
7 use rustc_session::{declare_lint_pass, declare_tool_lint};
11 /// Check for the usage of `as _` conversion using inferred type.
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.
17 /// The lint is allowed by default as using `_` is less wordy than always specifying the type.
21 /// fn foo(n: usize) {}
27 /// fn foo(n: usize) {}
31 #[clippy::version = "1.63.0"]
34 "detects `as _` conversion"
36 declare_lint_pass!(AsUnderscore => [AS_UNDERSCORE]);
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) {
44 if let ExprKind::Cast(_, ty) = expr.kind && let TyKind::Infer = ty.kind {
46 let ty_resolved = cx.typeck_results().expr_ty(expr);
47 if let ty::Error(_) = ty_resolved.kind() {
52 "using `as _` conversion",
54 "consider giving the type explicitly",
61 "using `as _` conversion",
65 "consider giving the type explicitly",
66 format!("{}", ty_resolved),
67 Applicability::MachineApplicable,