Skip to content

Commit 8224956

Browse files
committed
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.
1 parent b87e90b commit 8224956

11 files changed

+93
-8
lines changed

clippy_lints/src/loops/explicit_into_iter_loop.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::EXPLICIT_INTO_ITER_LOOP;
22
use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::is_trait_method;
4-
use clippy_utils::source::snippet_with_applicability;
4+
use clippy_utils::source::snippet_with_context;
55
use rustc_errors::Applicability;
66
use rustc_hir::Expr;
77
use rustc_lint::LateContext;
@@ -76,7 +76,7 @@ pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<
7676
};
7777

7878
let mut applicability = Applicability::MachineApplicable;
79-
let object = snippet_with_applicability(cx, self_arg.span, "_", &mut applicability);
79+
let object = snippet_with_context(cx, self_arg.span, call_expr.span.ctxt(), "_", &mut applicability).0;
8080
span_lint_and_sugg(
8181
cx,
8282
EXPLICIT_INTO_ITER_LOOP,

clippy_lints/src/loops/explicit_iter_loop.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::EXPLICIT_ITER_LOOP;
22
use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::msrvs::{self, Msrv};
4-
use clippy_utils::source::snippet_with_applicability;
4+
use clippy_utils::source::snippet_with_context;
55
use clippy_utils::sym;
66
use clippy_utils::ty::{
77
implements_trait, implements_trait_with_env, is_copy, is_type_lang_item, make_normalized_projection,
@@ -36,7 +36,7 @@ pub(super) fn check(
3636
}
3737

3838
let mut applicability = Applicability::MachineApplicable;
39-
let object = snippet_with_applicability(cx, self_arg.span, "_", &mut applicability);
39+
let object = snippet_with_context(cx, self_arg.span, call_expr.span.ctxt(), "_", &mut applicability).0;
4040
span_lint_and_sugg(
4141
cx,
4242
EXPLICIT_ITER_LOOP,

clippy_lints/src/loops/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,9 @@ impl Loops {
909909
}
910910

911911
fn check_for_loop_arg(&self, cx: &LateContext<'_>, _: &Pat<'_>, arg: &Expr<'_>) {
912-
if let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind {
912+
if !arg.span.from_expansion()
913+
&& let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind
914+
{
913915
match method.ident.name {
914916
sym::iter | sym::iter_mut => {
915917
explicit_iter_loop::check(cx, self_arg, arg, self.msrv, self.enforce_iter_loop_reborrow);

tests/ui/explicit_into_iter_loop.fixed

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,16 @@ fn main() {
7373

7474
for _ in S.into_iter::<u32>() {}
7575
}
76+
77+
fn issue14630() {
78+
macro_rules! mac {
79+
(into_iter $e:expr) => {
80+
$e.into_iter()
81+
};
82+
}
83+
84+
for _ in dbg!([1, 2]) {}
85+
//~^ explicit_into_iter_loop
86+
87+
for _ in mac!(into_iter [1, 2]) {}
88+
}

tests/ui/explicit_into_iter_loop.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,16 @@ fn main() {
7373

7474
for _ in S.into_iter::<u32>() {}
7575
}
76+
77+
fn issue14630() {
78+
macro_rules! mac {
79+
(into_iter $e:expr) => {
80+
$e.into_iter()
81+
};
82+
}
83+
84+
for _ in dbg!([1, 2]).into_iter() {}
85+
//~^ explicit_into_iter_loop
86+
87+
for _ in mac!(into_iter [1, 2]) {}
88+
}

tests/ui/explicit_into_iter_loop.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,11 @@ error: it is more concise to loop over containers instead of using explicit iter
3737
LL | for _ in mr.into_iter() {}
3838
| ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *mr`
3939

40-
error: aborting due to 6 previous errors
40+
error: it is more concise to loop over containers instead of using explicit iteration methods
41+
--> tests/ui/explicit_into_iter_loop.rs:84:14
42+
|
43+
LL | for _ in dbg!([1, 2]).into_iter() {}
44+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `dbg!([1, 2])`
45+
46+
error: aborting due to 7 previous errors
4147

tests/ui/explicit_iter_loop.fixed

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,16 @@ pub fn issue_13184() {
183183
let rvalues = &values;
184184
for _ in rvalues.iter() {}
185185
}
186+
187+
fn issue14630() {
188+
macro_rules! mac {
189+
(iter $e:expr) => {
190+
$e.into_iter()
191+
};
192+
}
193+
194+
for _ in &dbg!([1, 2]) {}
195+
//~^ explicit_iter_loop
196+
197+
for _ in mac!(iter [1, 2]) {}
198+
}

tests/ui/explicit_iter_loop.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,16 @@ pub fn issue_13184() {
183183
let rvalues = &values;
184184
for _ in rvalues.iter() {}
185185
}
186+
187+
fn issue14630() {
188+
macro_rules! mac {
189+
(iter $e:expr) => {
190+
$e.into_iter()
191+
};
192+
}
193+
194+
for _ in dbg!([1, 2]).iter() {}
195+
//~^ explicit_iter_loop
196+
197+
for _ in mac!(iter [1, 2]) {}
198+
}

tests/ui/explicit_iter_loop.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,5 +112,11 @@ error: it is more concise to loop over references to containers instead of using
112112
LL | for _ in r.iter() {}
113113
| ^^^^^^^^ help: to write this more concisely, try: `r`
114114

115-
error: aborting due to 18 previous errors
115+
error: it is more concise to loop over references to containers instead of using explicit iteration methods
116+
--> tests/ui/explicit_iter_loop.rs:194:14
117+
|
118+
LL | for _ in dbg!([1, 2]).iter() {}
119+
| ^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&dbg!([1, 2])`
120+
121+
error: aborting due to 19 previous errors
116122

tests/ui/iter_next_loop.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,16 @@ fn main() {
1515
let u = Unrelated(&[0]);
1616
for _v in u.next() {} // no error
1717
}
18+
19+
fn issue14630() {
20+
macro_rules! mac {
21+
(next $e:expr) => {
22+
$e.iter().next()
23+
};
24+
}
25+
26+
for _ in dbg!([1, 2].iter()).next() {}
27+
//~^ iter_next_loop
28+
29+
for _ in mac!(next [1, 2]) {}
30+
}

tests/ui/iter_next_loop.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,11 @@ LL | for _ in x.iter().next() {}
77
= note: `-D clippy::iter-next-loop` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::iter_next_loop)]`
99

10-
error: aborting due to 1 previous error
10+
error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want
11+
--> tests/ui/iter_next_loop.rs:26:14
12+
|
13+
LL | for _ in dbg!([1, 2].iter()).next() {}
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
16+
error: aborting due to 2 previous errors
1117

0 commit comments

Comments
 (0)