mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 20:46:07 +03:00
Various macro fixes for loop lints (#14631)
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. changelog: [`explicit_into_iter_loop`, `explicit_iter_loop`, `iter_next_loop`]: behave in macro context Fixes rust-lang/rust-clippy#14630
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -909,7 +909,9 @@ fn check_for_loop<'tcx>(
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -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]) {}
|
||||
}
|
||||
|
||||
@@ -73,3 +73,16 @@ fn next(&mut self) -> Option<Self::Item> {
|
||||
|
||||
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]) {}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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]) {}
|
||||
}
|
||||
|
||||
@@ -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]) {}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -15,3 +15,16 @@ fn next(&self) -> std::slice::Iter<u8> {
|
||||
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]) {}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user