]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs
Auto merge of #107843 - bjorn3:sync_cg_clif-2023-02-09, r=bjorn3
[rust.git] / src / tools / clippy / clippy_lints / src / methods / seek_from_current.rs
1 use rustc_ast::ast::{LitIntType, LitKind};
2 use rustc_errors::Applicability;
3 use rustc_hir::{Expr, ExprKind};
4 use rustc_lint::LateContext;
5
6 use clippy_utils::{
7     diagnostics::span_lint_and_sugg, get_trait_def_id, match_def_path, paths, source::snippet_with_applicability,
8     ty::implements_trait,
9 };
10
11 use super::SEEK_FROM_CURRENT;
12
13 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) {
14     let ty = cx.typeck_results().expr_ty(recv);
15
16     if let Some(def_id) = get_trait_def_id(cx, &paths::STD_IO_SEEK) {
17         if implements_trait(cx, ty, def_id, &[]) && arg_is_seek_from_current(cx, arg) {
18             let mut applicability = Applicability::MachineApplicable;
19             let snip = snippet_with_applicability(cx, recv.span, "..", &mut applicability);
20
21             span_lint_and_sugg(
22                 cx,
23                 SEEK_FROM_CURRENT,
24                 expr.span,
25                 "using `SeekFrom::Current` to start from current position",
26                 "replace with",
27                 format!("{snip}.stream_position()"),
28                 applicability,
29             );
30         }
31     }
32 }
33
34 fn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {
35     if let ExprKind::Call(f, args) = expr.kind &&
36         let ExprKind::Path(ref path) = f.kind &&
37         let Some(def_id) = cx.qpath_res(path, f.hir_id).opt_def_id() &&
38         match_def_path(cx, def_id, &paths::STD_IO_SEEK_FROM_CURRENT) {
39         // check if argument of `SeekFrom::Current` is `0`
40         if args.len() == 1 &&
41             let ExprKind::Lit(ref lit) = args[0].kind &&
42             let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node {
43             return true
44         }
45     }
46
47     false
48 }