diff options
| -rw-r--r-- | clippy_lints/src/loops/char_indices_as_byte_indices.rs | 5 | ||||
| -rw-r--r-- | tests/ui/char_indices_as_byte_indices.fixed | 6 | ||||
| -rw-r--r-- | tests/ui/char_indices_as_byte_indices.rs | 6 | ||||
| -rw-r--r-- | tests/ui/char_indices_as_byte_indices.stderr | 35 |
4 files changed, 37 insertions, 15 deletions
diff --git a/clippy_lints/src/loops/char_indices_as_byte_indices.rs b/clippy_lints/src/loops/char_indices_as_byte_indices.rs index 90e6f71e41a..8916454ada1 100644 --- a/clippy_lints/src/loops/char_indices_as_byte_indices.rs +++ b/clippy_lints/src/loops/char_indices_as_byte_indices.rs @@ -84,6 +84,9 @@ fn check_index_usage<'tcx>( let is_string_like = |ty: Ty<'_>| ty.is_str() || is_type_lang_item(cx, ty, LangItem::String); let message = match parent_expr.kind { ExprKind::MethodCall(segment, recv, ..) + // We currently only lint `str` methods (which `String` can deref to), so a `.is_str()` check is sufficient here + // (contrary to the `ExprKind::Index` case which needs to handle both with `is_string_like` because `String` implements + // `Index` directly and no deref to `str` would happen in that case). if cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_str() && BYTE_INDEX_METHODS.contains(&segment.ident.name.as_str()) && eq_expr_value(cx, chars_recv, recv) => @@ -126,7 +129,7 @@ fn check_index_usage<'tcx>( /// but for `.get(..idx)` we want to consider the method call the consuming expression, /// which requires skipping past the range expression. fn index_consumed_at<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { - for (_, node) in cx.tcx.hir().parent_iter(expr.hir_id) { + for (_, node) in cx.tcx.hir_parent_iter(expr.hir_id) { match node { Node::Expr(expr) if higher::Range::hir(expr).is_some() => {}, Node::ExprField(_) => {}, diff --git a/tests/ui/char_indices_as_byte_indices.fixed b/tests/ui/char_indices_as_byte_indices.fixed index a7c6bcd2681..04c8f6782c5 100644 --- a/tests/ui/char_indices_as_byte_indices.fixed +++ b/tests/ui/char_indices_as_byte_indices.fixed @@ -54,6 +54,12 @@ fn good(prim: &str, prim2: &str) { // str method taking a usize that doesn't represent a byte index prim.splitn(idx, prim2); } + + let mut string = "äa".to_owned(); + for (idx, _) in string.clone().chars().enumerate() { + // Even though the receiver is the same expression, it should not be treated as the same value. + string.clone().remove(idx); + } } fn main() {} diff --git a/tests/ui/char_indices_as_byte_indices.rs b/tests/ui/char_indices_as_byte_indices.rs index bb0f5df19bc..773a4fc65f1 100644 --- a/tests/ui/char_indices_as_byte_indices.rs +++ b/tests/ui/char_indices_as_byte_indices.rs @@ -54,6 +54,12 @@ fn good(prim: &str, prim2: &str) { // str method taking a usize that doesn't represent a byte index prim.splitn(idx, prim2); } + + let mut string = "äa".to_owned(); + for (idx, _) in string.clone().chars().enumerate() { + // Even though the receiver is the same expression, it should not be treated as the same value. + string.clone().remove(idx); + } } fn main() {} diff --git a/tests/ui/char_indices_as_byte_indices.stderr b/tests/ui/char_indices_as_byte_indices.stderr index a3c84578392..e2b4c1db78c 100644 --- a/tests/ui/char_indices_as_byte_indices.stderr +++ b/tests/ui/char_indices_as_byte_indices.stderr @@ -14,8 +14,9 @@ LL | for (idx, _) in prim.chars().enumerate() { = help: to override `-D warnings` add `#[allow(clippy::char_indices_as_byte_indices)]` help: consider using `.char_indices()` instead | -LL | for (idx, _) in prim.char_indices() { - | ~~~~~~~~~~~~~~ +LL - for (idx, _) in prim.chars().enumerate() { +LL + for (idx, _) in prim.char_indices() { + | error: passing a character position to a method that expects a byte index --> tests/ui/char_indices_as_byte_indices.rs:15:23 @@ -31,8 +32,9 @@ LL | for (idx, _) in prim.chars().enumerate() { | ^^^ ^^^^^^^^^^^ help: consider using `.char_indices()` instead | -LL | for (idx, _) in prim.char_indices() { - | ~~~~~~~~~~~~~~ +LL - for (idx, _) in prim.chars().enumerate() { +LL + for (idx, _) in prim.char_indices() { + | error: passing a character position to a method that expects a byte index --> tests/ui/char_indices_as_byte_indices.rs:19:49 @@ -48,8 +50,9 @@ LL | for (idx, _) in prim.chars().enumerate() { | ^^^ ^^^^^^^^^^^ help: consider using `.char_indices()` instead | -LL | for (idx, _) in prim.char_indices() { - | ~~~~~~~~~~~~~~ +LL - for (idx, _) in prim.chars().enumerate() { +LL + for (idx, _) in prim.char_indices() { + | error: indexing into a string with a character position where a byte index is expected --> tests/ui/char_indices_as_byte_indices.rs:29:24 @@ -65,8 +68,9 @@ LL | for c in prim.chars().enumerate() { | ^ ^^^^^^^^^^^ help: consider using `.char_indices()` instead | -LL | for c in prim.char_indices() { - | ~~~~~~~~~~~~~~ +LL - for c in prim.chars().enumerate() { +LL + for c in prim.char_indices() { + | error: passing a character position to a method that expects a byte index --> tests/ui/char_indices_as_byte_indices.rs:31:23 @@ -82,8 +86,9 @@ LL | for c in prim.chars().enumerate() { | ^ ^^^^^^^^^^^ help: consider using `.char_indices()` instead | -LL | for c in prim.char_indices() { - | ~~~~~~~~~~~~~~ +LL - for c in prim.chars().enumerate() { +LL + for c in prim.char_indices() { + | error: indexing into a string with a character position where a byte index is expected --> tests/ui/char_indices_as_byte_indices.rs:36:26 @@ -99,8 +104,9 @@ LL | for (idx, _) in string.chars().enumerate() { | ^^^ ^^^^^^^^^^^ help: consider using `.char_indices()` instead | -LL | for (idx, _) in string.char_indices() { - | ~~~~~~~~~~~~~~ +LL - for (idx, _) in string.chars().enumerate() { +LL + for (idx, _) in string.char_indices() { + | error: passing a character position to a method that expects a byte index --> tests/ui/char_indices_as_byte_indices.rs:38:25 @@ -116,8 +122,9 @@ LL | for (idx, _) in string.chars().enumerate() { | ^^^ ^^^^^^^^^^^ help: consider using `.char_indices()` instead | -LL | for (idx, _) in string.char_indices() { - | ~~~~~~~~~~~~~~ +LL - for (idx, _) in string.chars().enumerate() { +LL + for (idx, _) in string.char_indices() { + | error: aborting due to 7 previous errors |
