diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2025-04-16 20:43:23 +0200 |
|---|---|---|
| committer | Samuel Tardieu <sam@rfc1149.net> | 2025-05-20 00:48:19 +0200 |
| commit | 8224956dffb1b296841c2e31c5496ab1a53b2d83 (patch) | |
| tree | f4901b6ecc91ff565768fff0d848ef8faa9f9f67 | |
| parent | b87e90b28f474c64a753e65b81a973f7b1a15d52 (diff) | |
| download | rust-8224956dffb1b296841c2e31c5496ab1a53b2d83.tar.gz rust-8224956dffb1b296841c2e31c5496ab1a53b2d83.zip | |
Various macro fixes for loop lints
The `explicit_into_iter_loop`, `explicit_iter_loop` and `iter_next_loop` will now: - trigger only when the triggering expression is not located into macro code; - properly expose code rewrite proposal with code coming from the root context.
| -rw-r--r-- | clippy_lints/src/loops/explicit_into_iter_loop.rs | 4 | ||||
| -rw-r--r-- | clippy_lints/src/loops/explicit_iter_loop.rs | 4 | ||||
| -rw-r--r-- | clippy_lints/src/loops/mod.rs | 4 | ||||
| -rw-r--r-- | tests/ui/explicit_into_iter_loop.fixed | 13 | ||||
| -rw-r--r-- | tests/ui/explicit_into_iter_loop.rs | 13 | ||||
| -rw-r--r-- | tests/ui/explicit_into_iter_loop.stderr | 8 | ||||
| -rw-r--r-- | tests/ui/explicit_iter_loop.fixed | 13 | ||||
| -rw-r--r-- | tests/ui/explicit_iter_loop.rs | 13 | ||||
| -rw-r--r-- | tests/ui/explicit_iter_loop.stderr | 8 | ||||
| -rw-r--r-- | tests/ui/iter_next_loop.rs | 13 | ||||
| -rw-r--r-- | tests/ui/iter_next_loop.stderr | 8 |
11 files changed, 93 insertions, 8 deletions
diff --git a/clippy_lints/src/loops/explicit_into_iter_loop.rs b/clippy_lints/src/loops/explicit_into_iter_loop.rs index d5ddc33e928..4aa1c2e211d 100644 --- a/clippy_lints/src/loops/explicit_into_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_into_iter_loop.rs @@ -1,7 +1,7 @@ use super::EXPLICIT_INTO_ITER_LOOP; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_trait_method; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; @@ -76,7 +76,7 @@ pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr< }; let mut applicability = Applicability::MachineApplicable; - let object = snippet_with_applicability(cx, self_arg.span, "_", &mut applicability); + let object = snippet_with_context(cx, self_arg.span, call_expr.span.ctxt(), "_", &mut applicability).0; span_lint_and_sugg( cx, EXPLICIT_INTO_ITER_LOOP, diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs index d0b26c91ffa..010652e1cb9 100644 --- a/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_iter_loop.rs @@ -1,7 +1,7 @@ use super::EXPLICIT_ITER_LOOP; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::sym; use clippy_utils::ty::{ implements_trait, implements_trait_with_env, is_copy, is_type_lang_item, make_normalized_projection, @@ -36,7 +36,7 @@ pub(super) fn check( } let mut applicability = Applicability::MachineApplicable; - let object = snippet_with_applicability(cx, self_arg.span, "_", &mut applicability); + let object = snippet_with_context(cx, self_arg.span, call_expr.span.ctxt(), "_", &mut applicability).0; span_lint_and_sugg( cx, EXPLICIT_ITER_LOOP, diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 22cab317e3d..01c36b8cb12 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -909,7 +909,9 @@ impl Loops { } fn check_for_loop_arg(&self, cx: &LateContext<'_>, _: &Pat<'_>, arg: &Expr<'_>) { - if let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind { + if !arg.span.from_expansion() + && let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind + { match method.ident.name { sym::iter | sym::iter_mut => { explicit_iter_loop::check(cx, self_arg, arg, self.msrv, self.enforce_iter_loop_reborrow); diff --git a/tests/ui/explicit_into_iter_loop.fixed b/tests/ui/explicit_into_iter_loop.fixed index 2b68906ae39..c1b3c478eeb 100644 --- a/tests/ui/explicit_into_iter_loop.fixed +++ b/tests/ui/explicit_into_iter_loop.fixed @@ -73,3 +73,16 @@ fn main() { for _ in S.into_iter::<u32>() {} } + +fn issue14630() { + macro_rules! mac { + (into_iter $e:expr) => { + $e.into_iter() + }; + } + + for _ in dbg!([1, 2]) {} + //~^ explicit_into_iter_loop + + for _ in mac!(into_iter [1, 2]) {} +} diff --git a/tests/ui/explicit_into_iter_loop.rs b/tests/ui/explicit_into_iter_loop.rs index ca335b62d90..581e0dadcec 100644 --- a/tests/ui/explicit_into_iter_loop.rs +++ b/tests/ui/explicit_into_iter_loop.rs @@ -73,3 +73,16 @@ fn main() { for _ in S.into_iter::<u32>() {} } + +fn issue14630() { + macro_rules! mac { + (into_iter $e:expr) => { + $e.into_iter() + }; + } + + for _ in dbg!([1, 2]).into_iter() {} + //~^ explicit_into_iter_loop + + for _ in mac!(into_iter [1, 2]) {} +} diff --git a/tests/ui/explicit_into_iter_loop.stderr b/tests/ui/explicit_into_iter_loop.stderr index 1c3156755d4..26fb11e0048 100644 --- a/tests/ui/explicit_into_iter_loop.stderr +++ b/tests/ui/explicit_into_iter_loop.stderr @@ -37,5 +37,11 @@ error: it is more concise to loop over containers instead of using explicit iter LL | for _ in mr.into_iter() {} | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *mr` -error: aborting due to 6 previous errors +error: it is more concise to loop over containers instead of using explicit iteration methods + --> tests/ui/explicit_into_iter_loop.rs:84:14 + | +LL | for _ in dbg!([1, 2]).into_iter() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `dbg!([1, 2])` + +error: aborting due to 7 previous errors diff --git a/tests/ui/explicit_iter_loop.fixed b/tests/ui/explicit_iter_loop.fixed index cd0898dfc36..f246ec61800 100644 --- a/tests/ui/explicit_iter_loop.fixed +++ b/tests/ui/explicit_iter_loop.fixed @@ -183,3 +183,16 @@ pub fn issue_13184() { let rvalues = &values; for _ in rvalues.iter() {} } + +fn issue14630() { + macro_rules! mac { + (iter $e:expr) => { + $e.into_iter() + }; + } + + for _ in &dbg!([1, 2]) {} + //~^ explicit_iter_loop + + for _ in mac!(iter [1, 2]) {} +} diff --git a/tests/ui/explicit_iter_loop.rs b/tests/ui/explicit_iter_loop.rs index 02405280ce4..35f4fb7097d 100644 --- a/tests/ui/explicit_iter_loop.rs +++ b/tests/ui/explicit_iter_loop.rs @@ -183,3 +183,16 @@ pub fn issue_13184() { let rvalues = &values; for _ in rvalues.iter() {} } + +fn issue14630() { + macro_rules! mac { + (iter $e:expr) => { + $e.into_iter() + }; + } + + for _ in dbg!([1, 2]).iter() {} + //~^ explicit_iter_loop + + for _ in mac!(iter [1, 2]) {} +} diff --git a/tests/ui/explicit_iter_loop.stderr b/tests/ui/explicit_iter_loop.stderr index 3816bb4db98..575dbe7813d 100644 --- a/tests/ui/explicit_iter_loop.stderr +++ b/tests/ui/explicit_iter_loop.stderr @@ -112,5 +112,11 @@ error: it is more concise to loop over references to containers instead of using LL | for _ in r.iter() {} | ^^^^^^^^ help: to write this more concisely, try: `r` -error: aborting due to 18 previous errors +error: it is more concise to loop over references to containers instead of using explicit iteration methods + --> tests/ui/explicit_iter_loop.rs:194:14 + | +LL | for _ in dbg!([1, 2]).iter() {} + | ^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&dbg!([1, 2])` + +error: aborting due to 19 previous errors diff --git a/tests/ui/iter_next_loop.rs b/tests/ui/iter_next_loop.rs index 32711c7ef62..8e62ed963b9 100644 --- a/tests/ui/iter_next_loop.rs +++ b/tests/ui/iter_next_loop.rs @@ -15,3 +15,16 @@ fn main() { let u = Unrelated(&[0]); for _v in u.next() {} // no error } + +fn issue14630() { + macro_rules! mac { + (next $e:expr) => { + $e.iter().next() + }; + } + + for _ in dbg!([1, 2].iter()).next() {} + //~^ iter_next_loop + + for _ in mac!(next [1, 2]) {} +} diff --git a/tests/ui/iter_next_loop.stderr b/tests/ui/iter_next_loop.stderr index acc55031c3b..c076e86db93 100644 --- a/tests/ui/iter_next_loop.stderr +++ b/tests/ui/iter_next_loop.stderr @@ -7,5 +7,11 @@ LL | for _ in x.iter().next() {} = note: `-D clippy::iter-next-loop` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::iter_next_loop)]` -error: aborting due to 1 previous error +error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want + --> tests/ui/iter_next_loop.rs:26:14 + | +LL | for _ in dbg!([1, 2].iter()).next() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors |
