1 use clippy_utils
::diagnostics
::span_lint_and_help
;
2 use clippy_utils
::paths
;
3 use clippy_utils
::ty
::match_type
;
4 use if_chain
::if_chain
;
5 use rustc_hir
::{Expr, ExprKind, QPath}
;
6 use rustc_lint
::{LateContext, LateLintPass}
;
7 use rustc_session
::{declare_lint_pass, declare_tool_lint}
;
10 /// **What it does:** Checks for use of File::read_to_end and File::read_to_string.
12 /// **Why is this bad?** `fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values.
13 /// See also: [fs::read docs](https://doc.rust-lang.org/std/fs/fn.read.html), [fs::read_to_string docs](https://doc.rust-lang.org/std/fs/fn.read_to_string.html)
15 /// **Known problems:** None.
20 /// # use std::io::Read;
21 /// # use std::fs::File;
22 /// let mut f = File::open("foo.txt").unwrap();
23 /// let mut bytes = Vec::new();
24 /// f.read_to_end(&mut bytes).unwrap();
26 /// Can be written more concisely as
29 /// let mut bytes = fs::read("foo.txt").unwrap();
31 pub VERBOSE_FILE_READS
,
33 "use of `File::read_to_end` or `File::read_to_string`"
36 declare_lint_pass
!(VerboseFileReads
=> [VERBOSE_FILE_READS
]);
38 impl<'tcx
> LateLintPass
<'tcx
> for VerboseFileReads
{
39 fn check_expr(&mut self, cx
: &LateContext
<'tcx
>, expr
: &'tcx Expr
<'tcx
>) {
40 if is_file_read_to_end(cx
, expr
) {
45 "use of `File::read_to_end`",
47 "consider using `fs::read` instead",
49 } else if is_file_read_to_string(cx
, expr
) {
54 "use of `File::read_to_string`",
56 "consider using `fs::read_to_string` instead",
62 fn is_file_read_to_end
<'tcx
>(cx
: &LateContext
<'tcx
>, expr
: &'tcx Expr
<'tcx
>) -> bool
{
64 if let ExprKind
::MethodCall(method_name
, _
, exprs
, _
) = expr
.kind
;
65 if method_name
.ident
.as_str() == "read_to_end";
66 if let ExprKind
::Path(QPath
::Resolved(None
, _
)) = &exprs
[0].kind
;
67 let ty
= cx
.typeck_results().expr_ty(&exprs
[0]);
68 if match_type(cx
, ty
, &paths
::FILE
);
76 fn is_file_read_to_string
<'tcx
>(cx
: &LateContext
<'tcx
>, expr
: &'tcx Expr
<'tcx
>) -> bool
{
78 if let ExprKind
::MethodCall(method_name
, _
, exprs
, _
) = expr
.kind
;
79 if method_name
.ident
.as_str() == "read_to_string";
80 if let ExprKind
::Path(QPath
::Resolved(None
, _
)) = &exprs
[0].kind
;
81 let ty
= cx
.typeck_results().expr_ty(&exprs
[0]);
82 if match_type(cx
, ty
, &paths
::FILE
);