mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-16 05:58:41 +00:00
add a new lint bytes_nth
This commit is contained in:
parent
c1ce78f0b2
commit
1c3033d5cf
7 changed files with 102 additions and 0 deletions
|
@ -1877,6 +1877,7 @@ Released 2018-09-13
|
||||||
[`box_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_vec
|
[`box_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_vec
|
||||||
[`boxed_local`]: https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local
|
[`boxed_local`]: https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local
|
||||||
[`builtin_type_shadow`]: https://rust-lang.github.io/rust-clippy/master/index.html#builtin_type_shadow
|
[`builtin_type_shadow`]: https://rust-lang.github.io/rust-clippy/master/index.html#builtin_type_shadow
|
||||||
|
[`bytes_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#bytes_nth
|
||||||
[`cargo_common_metadata`]: https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata
|
[`cargo_common_metadata`]: https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata
|
||||||
[`case_sensitive_file_extension_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#case_sensitive_file_extension_comparisons
|
[`case_sensitive_file_extension_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#case_sensitive_file_extension_comparisons
|
||||||
[`cast_lossless`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless
|
[`cast_lossless`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless
|
||||||
|
|
|
@ -734,6 +734,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||||
&mem_replace::MEM_REPLACE_WITH_DEFAULT,
|
&mem_replace::MEM_REPLACE_WITH_DEFAULT,
|
||||||
&mem_replace::MEM_REPLACE_WITH_UNINIT,
|
&mem_replace::MEM_REPLACE_WITH_UNINIT,
|
||||||
&methods::BIND_INSTEAD_OF_MAP,
|
&methods::BIND_INSTEAD_OF_MAP,
|
||||||
|
&methods::BYTES_NTH,
|
||||||
&methods::CHARS_LAST_CMP,
|
&methods::CHARS_LAST_CMP,
|
||||||
&methods::CHARS_NEXT_CMP,
|
&methods::CHARS_NEXT_CMP,
|
||||||
&methods::CLONE_DOUBLE_REF,
|
&methods::CLONE_DOUBLE_REF,
|
||||||
|
@ -1531,6 +1532,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||||
LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT),
|
LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT),
|
||||||
LintId::of(&mem_replace::MEM_REPLACE_WITH_UNINIT),
|
LintId::of(&mem_replace::MEM_REPLACE_WITH_UNINIT),
|
||||||
LintId::of(&methods::BIND_INSTEAD_OF_MAP),
|
LintId::of(&methods::BIND_INSTEAD_OF_MAP),
|
||||||
|
LintId::of(&methods::BYTES_NTH),
|
||||||
LintId::of(&methods::CHARS_LAST_CMP),
|
LintId::of(&methods::CHARS_LAST_CMP),
|
||||||
LintId::of(&methods::CHARS_NEXT_CMP),
|
LintId::of(&methods::CHARS_NEXT_CMP),
|
||||||
LintId::of(&methods::CLONE_DOUBLE_REF),
|
LintId::of(&methods::CLONE_DOUBLE_REF),
|
||||||
|
@ -1749,6 +1751,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||||
LintId::of(&matches::SINGLE_MATCH),
|
LintId::of(&matches::SINGLE_MATCH),
|
||||||
LintId::of(&mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
|
LintId::of(&mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
|
||||||
LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT),
|
LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT),
|
||||||
|
LintId::of(&methods::BYTES_NTH),
|
||||||
LintId::of(&methods::CHARS_LAST_CMP),
|
LintId::of(&methods::CHARS_LAST_CMP),
|
||||||
LintId::of(&methods::CHARS_NEXT_CMP),
|
LintId::of(&methods::CHARS_NEXT_CMP),
|
||||||
LintId::of(&methods::FROM_ITER_INSTEAD_OF_COLLECT),
|
LintId::of(&methods::FROM_ITER_INSTEAD_OF_COLLECT),
|
||||||
|
|
39
clippy_lints/src/methods/bytes_nth.rs
Normal file
39
clippy_lints/src/methods/bytes_nth.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
use crate::utils::{is_type_diagnostic_item, snippet_with_applicability, span_lint_and_sugg};
|
||||||
|
use if_chain::if_chain;
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_hir::{Expr, ExprKind};
|
||||||
|
use rustc_lint::LateContext;
|
||||||
|
use rustc_span::sym;
|
||||||
|
|
||||||
|
use super::BYTES_NTH;
|
||||||
|
|
||||||
|
pub(super) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>]) {
|
||||||
|
if_chain! {
|
||||||
|
if let ExprKind::MethodCall(_, _, ref args, _) = expr.kind;
|
||||||
|
let ty = cx.typeck_results().expr_ty(&iter_args[0]).peel_refs();
|
||||||
|
let caller_type = if is_type_diagnostic_item(cx, ty, sym::string_type) {
|
||||||
|
Some("String")
|
||||||
|
} else if ty.is_str() {
|
||||||
|
Some("str")
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
if let Some(caller_type) = caller_type;
|
||||||
|
then {
|
||||||
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
BYTES_NTH,
|
||||||
|
expr.span,
|
||||||
|
&format!("called `.byte().nth()` on a `{}`", caller_type),
|
||||||
|
"try calling `.as_bytes().get()`",
|
||||||
|
format!(
|
||||||
|
"{}.as_bytes().get({})",
|
||||||
|
snippet_with_applicability(cx, iter_args[0].span, "..", &mut applicability),
|
||||||
|
snippet_with_applicability(cx, args[1].span, "..", &mut applicability)
|
||||||
|
),
|
||||||
|
applicability,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
mod bind_instead_of_map;
|
mod bind_instead_of_map;
|
||||||
|
mod bytes_nth;
|
||||||
mod filter_map_identity;
|
mod filter_map_identity;
|
||||||
mod inefficient_to_string;
|
mod inefficient_to_string;
|
||||||
mod inspect_for_each;
|
mod inspect_for_each;
|
||||||
|
@ -1490,6 +1491,28 @@ declare_clippy_lint! {
|
||||||
"call to `filter_map` where `flatten` is sufficient"
|
"call to `filter_map` where `flatten` is sufficient"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// **What it does:** Checks for the use of `.bytes().nth()`.
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** `.as_bytes().get()` is more efficient and more
|
||||||
|
/// readable.
|
||||||
|
///
|
||||||
|
/// **Known problems:** None.
|
||||||
|
///
|
||||||
|
/// **Example:**
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// // Bad
|
||||||
|
/// let _ = "Hello".bytes().nth(3);;
|
||||||
|
///
|
||||||
|
/// // Good
|
||||||
|
/// let _ = "Hello".as_bytes().get(3);
|
||||||
|
/// ```
|
||||||
|
pub BYTES_NTH,
|
||||||
|
style,
|
||||||
|
"replace `.bytes().nth()` with `.as_bytes().get()`"
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Methods {
|
pub struct Methods {
|
||||||
msrv: Option<RustcVersion>,
|
msrv: Option<RustcVersion>,
|
||||||
}
|
}
|
||||||
|
@ -1537,6 +1560,7 @@ impl_lint_pass!(Methods => [
|
||||||
ITER_NEXT_SLICE,
|
ITER_NEXT_SLICE,
|
||||||
ITER_NTH,
|
ITER_NTH,
|
||||||
ITER_NTH_ZERO,
|
ITER_NTH_ZERO,
|
||||||
|
BYTES_NTH,
|
||||||
ITER_SKIP_NEXT,
|
ITER_SKIP_NEXT,
|
||||||
GET_UNWRAP,
|
GET_UNWRAP,
|
||||||
STRING_EXTEND_CHARS,
|
STRING_EXTEND_CHARS,
|
||||||
|
@ -1614,6 +1638,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||||
["extend", ..] => lint_extend(cx, expr, arg_lists[0]),
|
["extend", ..] => lint_extend(cx, expr, arg_lists[0]),
|
||||||
["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false),
|
["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false),
|
||||||
["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true),
|
["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true),
|
||||||
|
["nth", "bytes"] => bytes_nth::lints(cx, expr, &arg_lists[1]),
|
||||||
["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]),
|
["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]),
|
||||||
["step_by", ..] => lint_step_by(cx, expr, arg_lists[0]),
|
["step_by", ..] => lint_step_by(cx, expr, arg_lists[0]),
|
||||||
["next", "skip"] => lint_iter_skip_next(cx, expr, arg_lists[1]),
|
["next", "skip"] => lint_iter_skip_next(cx, expr, arg_lists[1]),
|
||||||
|
|
9
tests/ui/bytes_nth.fixed
Normal file
9
tests/ui/bytes_nth.fixed
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![warn(clippy::bytes_nth)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = "Hello".as_bytes().get(3);
|
||||||
|
|
||||||
|
let _ = String::from("Hello").as_bytes().get(3);
|
||||||
|
}
|
9
tests/ui/bytes_nth.rs
Normal file
9
tests/ui/bytes_nth.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![warn(clippy::bytes_nth)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = "Hello".bytes().nth(3);
|
||||||
|
|
||||||
|
let _ = String::from("Hello").bytes().nth(3);
|
||||||
|
}
|
16
tests/ui/bytes_nth.stderr
Normal file
16
tests/ui/bytes_nth.stderr
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
error: called `.byte().nth()` on a `str`
|
||||||
|
--> $DIR/bytes_nth.rs:6:13
|
||||||
|
|
|
||||||
|
LL | let _ = "Hello".bytes().nth(3);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: try calling `.as_bytes().get()`: `"Hello".as_bytes().get(3)`
|
||||||
|
|
|
||||||
|
= note: `-D clippy::bytes-nth` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: called `.byte().nth()` on a `String`
|
||||||
|
--> $DIR/bytes_nth.rs:8:13
|
||||||
|
|
|
||||||
|
LL | let _ = String::from("Hello").bytes().nth(3);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try calling `.as_bytes().get()`: `String::from("Hello").as_bytes().get(3)`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
Add table
Reference in a new issue