chore: use multipart_suggestions for str_splitn
This commit is contained in:
parent
f83a227d39
commit
dcc4025405
4 changed files with 196 additions and 80 deletions
|
|
@ -129,7 +129,7 @@ fn check_manual_split_once_indirect(
|
|||
let ctxt = expr.span.ctxt();
|
||||
let mut parents = cx.tcx.hir().parent_iter(expr.hir_id);
|
||||
if let (_, Node::LetStmt(local)) = parents.next()?
|
||||
&& let PatKind::Binding(BindingMode::MUT, iter_binding_id, iter_ident, None) = local.pat.kind
|
||||
&& let PatKind::Binding(BindingMode::MUT, iter_binding_id, _, None) = local.pat.kind
|
||||
&& let (iter_stmt_id, Node::Stmt(_)) = parents.next()?
|
||||
&& let (_, Node::Block(enclosing_block)) = parents.next()?
|
||||
&& let mut stmts = enclosing_block
|
||||
|
|
@ -162,16 +162,20 @@ fn check_manual_split_once_indirect(
|
|||
UnwrapKind::Unwrap => ".unwrap()",
|
||||
UnwrapKind::QuestionMark => "?",
|
||||
};
|
||||
diag.span_suggestion_verbose(
|
||||
local.span,
|
||||
format!("try `{r}split_once`"),
|
||||
format!("let ({lhs}, {rhs}) = {self_snip}.{r}split_once({pat_snip}){unwrap};"),
|
||||
|
||||
// Add a multipart suggestion
|
||||
diag.multipart_suggestion(
|
||||
format!("replace with `{r}split_once`"),
|
||||
vec![
|
||||
(
|
||||
local.span,
|
||||
format!("let ({lhs}, {rhs}) = {self_snip}.{r}split_once({pat_snip}){unwrap};"),
|
||||
),
|
||||
(first.span, String::new()), // Remove the first usage
|
||||
(second.span, String::new()), // Remove the second usage
|
||||
],
|
||||
app,
|
||||
);
|
||||
|
||||
let remove_msg = format!("remove the `{iter_ident}` usages");
|
||||
diag.span_suggestion(first.span, remove_msg.clone(), "", app);
|
||||
diag.span_suggestion(second.span, remove_msg, "", app);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
144
tests/ui/manual_split_once.fixed
Normal file
144
tests/ui/manual_split_once.fixed
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
#![warn(clippy::manual_split_once)]
|
||||
#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
|
||||
|
||||
extern crate itertools;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use itertools::Itertools;
|
||||
|
||||
fn main() {
|
||||
let _ = "key=value".splitn(2, '=').nth(2);
|
||||
let _ = "key=value".split_once('=').unwrap().1;
|
||||
let _ = "key=value".split_once('=').unwrap().1;
|
||||
let (_, _) = "key=value".split_once('=').unwrap();
|
||||
|
||||
let s = String::from("key=value");
|
||||
let _ = s.split_once('=').unwrap().1;
|
||||
|
||||
let s = Box::<str>::from("key=value");
|
||||
let _ = s.split_once('=').unwrap().1;
|
||||
|
||||
let s = &"key=value";
|
||||
let _ = s.split_once('=').unwrap().1;
|
||||
|
||||
fn _f(s: &str) -> Option<&str> {
|
||||
let _ = s.split_once('=')?.1;
|
||||
let _ = s.split_once('=')?.1;
|
||||
let _ = s.rsplit_once('=')?.0;
|
||||
let _ = s.rsplit_once('=')?.0;
|
||||
None
|
||||
}
|
||||
|
||||
// Don't lint, slices don't have `split_once`
|
||||
let _ = [0, 1, 2].splitn(2, |&x| x == 1).nth(1).unwrap();
|
||||
|
||||
// `rsplitn` gives the results in the reverse order of `rsplit_once`
|
||||
let _ = "key=value".rsplit_once('=').unwrap().0;
|
||||
let (_, _) = "key=value".rsplit_once('=').map(|(x, y)| (y, x)).unwrap();
|
||||
let _ = s.rsplit_once('=').map(|x| x.0);
|
||||
}
|
||||
|
||||
fn indirect() -> Option<()> {
|
||||
let (l, r) = "a.b.c".split_once('.').unwrap();
|
||||
|
||||
|
||||
|
||||
let (l, r) = "a.b.c".split_once('.')?;
|
||||
|
||||
|
||||
|
||||
let (l, r) = "a.b.c".rsplit_once('.').unwrap();
|
||||
|
||||
|
||||
|
||||
let (l, r) = "a.b.c".rsplit_once('.')?;
|
||||
|
||||
|
||||
|
||||
// could lint, currently doesn't
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let other = 1;
|
||||
let l = iter.next()?;
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let mut mut_binding = iter.next()?;
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let tuple = (iter.next()?, iter.next()?);
|
||||
|
||||
// should not lint
|
||||
|
||||
let mut missing_unwrap = "a.b.c".splitn(2, '.');
|
||||
let l = missing_unwrap.next();
|
||||
let r = missing_unwrap.next();
|
||||
|
||||
let mut mixed_unrap = "a.b.c".splitn(2, '.');
|
||||
let unwrap = mixed_unrap.next().unwrap();
|
||||
let question_mark = mixed_unrap.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let same_name = iter.next()?;
|
||||
let same_name = iter.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let shadows_existing = "d";
|
||||
let shadows_existing = iter.next()?;
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let becomes_shadowed = iter.next()?;
|
||||
let becomes_shadowed = "d";
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let l = iter.next()?;
|
||||
let r = iter.next()?;
|
||||
let third_usage = iter.next()?;
|
||||
|
||||
let mut n_three = "a.b.c".splitn(3, '.');
|
||||
let l = n_three.next()?;
|
||||
let r = n_three.next()?;
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
{
|
||||
let in_block = iter.next()?;
|
||||
}
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut lacks_binding = "a.b.c".splitn(2, '.');
|
||||
let _ = lacks_binding.next()?;
|
||||
let r = lacks_binding.next()?;
|
||||
|
||||
let mut mapped = "a.b.c".splitn(2, '.').map(|_| "~");
|
||||
let l = iter.next()?;
|
||||
let r = iter.next()?;
|
||||
|
||||
let mut assigned = "";
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let l = iter.next()?;
|
||||
assigned = iter.next()?;
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.51"]
|
||||
fn _msrv_1_51() {
|
||||
// `str::split_once` was stabilized in 1.52. Do not lint this
|
||||
let _ = "key=value".splitn(2, '=').nth(1).unwrap();
|
||||
|
||||
let mut iter = "a.b.c".splitn(2, '.');
|
||||
let a = iter.next().unwrap();
|
||||
let b = iter.next().unwrap();
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.52"]
|
||||
fn _msrv_1_52() {
|
||||
let _ = "key=value".split_once('=').unwrap().1;
|
||||
|
||||
let (a, b) = "a.b.c".split_once('.').unwrap();
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
#![warn(clippy::manual_split_once)]
|
||||
#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
|
||||
|
||||
//@no-rustfix: need to change the suggestion to a multipart suggestion
|
||||
|
||||
extern crate itertools;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:13:13
|
||||
--> tests/ui/manual_split_once.rs:11:13
|
||||
|
|
||||
LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
|
||||
|
|
@ -8,79 +8,79 @@ LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
|
|||
= help: to override `-D warnings` add `#[allow(clippy::manual_split_once)]`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:14:13
|
||||
--> tests/ui/manual_split_once.rs:12:13
|
||||
|
|
||||
LL | let _ = "key=value".splitn(2, '=').skip(1).next().unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:15:18
|
||||
--> tests/ui/manual_split_once.rs:13:18
|
||||
|
|
||||
LL | let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=')`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:18:13
|
||||
--> tests/ui/manual_split_once.rs:16:13
|
||||
|
|
||||
LL | let _ = s.splitn(2, '=').nth(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:21:13
|
||||
--> tests/ui/manual_split_once.rs:19:13
|
||||
|
|
||||
LL | let _ = s.splitn(2, '=').nth(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:24:13
|
||||
--> tests/ui/manual_split_once.rs:22:13
|
||||
|
|
||||
LL | let _ = s.splitn(2, '=').skip(1).next().unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:27:17
|
||||
--> tests/ui/manual_split_once.rs:25:17
|
||||
|
|
||||
LL | let _ = s.splitn(2, '=').nth(1)?;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:28:17
|
||||
--> tests/ui/manual_split_once.rs:26:17
|
||||
|
|
||||
LL | let _ = s.splitn(2, '=').skip(1).next()?;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:29:17
|
||||
--> tests/ui/manual_split_once.rs:27:17
|
||||
|
|
||||
LL | let _ = s.rsplitn(2, '=').nth(1)?;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:30:17
|
||||
--> tests/ui/manual_split_once.rs:28:17
|
||||
|
|
||||
LL | let _ = s.rsplitn(2, '=').skip(1).next()?;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:38:13
|
||||
--> tests/ui/manual_split_once.rs:36:13
|
||||
|
|
||||
LL | let _ = "key=value".rsplitn(2, '=').nth(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').unwrap().0`
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:39:18
|
||||
--> tests/ui/manual_split_once.rs:37:18
|
||||
|
|
||||
LL | let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))`
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:40:13
|
||||
--> tests/ui/manual_split_once.rs:38:13
|
||||
|
|
||||
LL | let _ = s.rsplitn(2, '=').nth(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=').map(|x| x.0)`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:44:5
|
||||
--> tests/ui/manual_split_once.rs:42:5
|
||||
|
|
||||
LL | let mut iter = "a.b.c".splitn(2, '.');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -89,21 +89,15 @@ LL | let l = iter.next().unwrap();
|
|||
LL | let r = iter.next().unwrap();
|
||||
| ----------------------------- second usage here
|
||||
|
|
||||
help: try `split_once`
|
||||
help: replace with `split_once`
|
||||
|
|
||||
LL | let (l, r) = "a.b.c".split_once('.').unwrap();
|
||||
|
|
||||
help: remove the `iter` usages
|
||||
|
|
||||
LL - let l = iter.next().unwrap();
|
||||
|
|
||||
help: remove the `iter` usages
|
||||
|
|
||||
LL - let r = iter.next().unwrap();
|
||||
LL ~ let (l, r) = "a.b.c".split_once('.').unwrap();
|
||||
LL ~
|
||||
LL ~
|
||||
|
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:48:5
|
||||
--> tests/ui/manual_split_once.rs:46:5
|
||||
|
|
||||
LL | let mut iter = "a.b.c".splitn(2, '.');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -112,21 +106,15 @@ LL | let l = iter.next()?;
|
|||
LL | let r = iter.next()?;
|
||||
| --------------------- second usage here
|
||||
|
|
||||
help: try `split_once`
|
||||
help: replace with `split_once`
|
||||
|
|
||||
LL | let (l, r) = "a.b.c".split_once('.')?;
|
||||
|
|
||||
help: remove the `iter` usages
|
||||
|
|
||||
LL - let l = iter.next()?;
|
||||
|
|
||||
help: remove the `iter` usages
|
||||
|
|
||||
LL - let r = iter.next()?;
|
||||
LL ~ let (l, r) = "a.b.c".split_once('.')?;
|
||||
LL ~
|
||||
LL ~
|
||||
|
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:52:5
|
||||
--> tests/ui/manual_split_once.rs:50:5
|
||||
|
|
||||
LL | let mut iter = "a.b.c".rsplitn(2, '.');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -135,21 +123,15 @@ LL | let r = iter.next().unwrap();
|
|||
LL | let l = iter.next().unwrap();
|
||||
| ----------------------------- second usage here
|
||||
|
|
||||
help: try `rsplit_once`
|
||||
help: replace with `rsplit_once`
|
||||
|
|
||||
LL | let (l, r) = "a.b.c".rsplit_once('.').unwrap();
|
||||
|
|
||||
help: remove the `iter` usages
|
||||
|
|
||||
LL - let r = iter.next().unwrap();
|
||||
|
|
||||
help: remove the `iter` usages
|
||||
|
|
||||
LL - let l = iter.next().unwrap();
|
||||
LL ~ let (l, r) = "a.b.c".rsplit_once('.').unwrap();
|
||||
LL ~
|
||||
LL ~
|
||||
|
|
||||
|
||||
error: manual implementation of `rsplit_once`
|
||||
--> tests/ui/manual_split_once.rs:56:5
|
||||
--> tests/ui/manual_split_once.rs:54:5
|
||||
|
|
||||
LL | let mut iter = "a.b.c".rsplitn(2, '.');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -158,27 +140,21 @@ LL | let r = iter.next()?;
|
|||
LL | let l = iter.next()?;
|
||||
| --------------------- second usage here
|
||||
|
|
||||
help: try `rsplit_once`
|
||||
help: replace with `rsplit_once`
|
||||
|
|
||||
LL | let (l, r) = "a.b.c".rsplit_once('.')?;
|
||||
|
|
||||
help: remove the `iter` usages
|
||||
|
|
||||
LL - let r = iter.next()?;
|
||||
|
|
||||
help: remove the `iter` usages
|
||||
|
|
||||
LL - let l = iter.next()?;
|
||||
LL ~ let (l, r) = "a.b.c".rsplit_once('.')?;
|
||||
LL ~
|
||||
LL ~
|
||||
|
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:141:13
|
||||
--> tests/ui/manual_split_once.rs:139:13
|
||||
|
|
||||
LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
|
||||
|
||||
error: manual implementation of `split_once`
|
||||
--> tests/ui/manual_split_once.rs:143:5
|
||||
--> tests/ui/manual_split_once.rs:141:5
|
||||
|
|
||||
LL | let mut iter = "a.b.c".splitn(2, '.');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -187,17 +163,11 @@ LL | let a = iter.next().unwrap();
|
|||
LL | let b = iter.next().unwrap();
|
||||
| ----------------------------- second usage here
|
||||
|
|
||||
help: try `split_once`
|
||||
help: replace with `split_once`
|
||||
|
|
||||
LL | let (a, b) = "a.b.c".split_once('.').unwrap();
|
||||
|
|
||||
help: remove the `iter` usages
|
||||
|
|
||||
LL - let a = iter.next().unwrap();
|
||||
|
|
||||
help: remove the `iter` usages
|
||||
|
|
||||
LL - let b = iter.next().unwrap();
|
||||
LL ~ let (a, b) = "a.b.c".split_once('.').unwrap();
|
||||
LL ~
|
||||
LL ~
|
||||
|
|
||||
|
||||
error: aborting due to 19 previous errors
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue