diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs index d296ae46f43e7..ae2265b5d96b2 100644 --- a/compiler/rustc_lint/src/shadowed_into_iter.rs +++ b/compiler/rustc_lint/src/shadowed_into_iter.rs @@ -134,6 +134,8 @@ impl<'tcx> LateLintPass<'tcx> for ShadowedIntoIter { && let hir::ExprKind::Call(path, [_]) = &arg.kind && let hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoIterIntoIter, ..)) = &path.kind + && !receiver_arg.span.from_expansion() + && !expr.span.from_expansion() { Some(ShadowedIntoIterDiagSub::RemoveIntoIter { span: receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()), diff --git a/tests/ui/macros/macro-expansion-empty-span-147408.rs b/tests/ui/macros/macro-expansion-empty-span-147408.rs new file mode 100644 index 0000000000000..ef3f7b40abbf1 --- /dev/null +++ b/tests/ui/macros/macro-expansion-empty-span-147408.rs @@ -0,0 +1,23 @@ +//@ check-pass + +fn main() { + macro_rules! mac { + (iter $e:expr) => { + $e.iter() + }; + (into_iter $e:expr) => { + $e.into_iter() //~ WARN this method call resolves to + //~^ WARN this changes meaning in Rust 2021 + }; + (next $e:expr) => { + $e.iter().next() + }; + } + + for _ in dbg!([1, 2]).iter() {} + for _ in dbg!([1, 2]).into_iter() {} //~ WARN this method call resolves to + //~^ WARN this changes meaning in Rust 2021 + for _ in mac!(iter [1, 2]) {} + for _ in mac!(into_iter [1, 2]) {} + for _ in mac!(next [1, 2]) {} //~ WARN for loop over an +} diff --git a/tests/ui/macros/macro-expansion-empty-span-147408.stderr b/tests/ui/macros/macro-expansion-empty-span-147408.stderr new file mode 100644 index 0000000000000..420252bc6888e --- /dev/null +++ b/tests/ui/macros/macro-expansion-empty-span-147408.stderr @@ -0,0 +1,58 @@ + WARN rustc_errors::emitter Invalid span $SRC_DIR/std/src/macros.rs:LL:COL (#11), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/std/src/macros.rs" }) } +warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021 + --> $DIR/macro-expansion-empty-span-147408.rs:18:27 + | +LL | for _ in dbg!([1, 2]).into_iter() {} + | ^^^^^^^^^ + | + = warning: this changes meaning in Rust 2021 + = note: for more information, see + = note: `#[warn(array_into_iter)]` (part of `#[warn(rust_2021_compatibility)]`) on by default +help: use `.iter()` instead of `.into_iter()` to avoid ambiguity + | +LL - for _ in dbg!([1, 2]).into_iter() {} +LL + for _ in dbg!([1, 2]).iter() {} + | + +warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021 + --> $DIR/macro-expansion-empty-span-147408.rs:9:16 + | +LL | $e.into_iter() + | ^^^^^^^^^ +... +LL | for _ in mac!(into_iter [1, 2]) {} + | ---------------------- in this macro invocation + | + = warning: this changes meaning in Rust 2021 + = note: for more information, see + = note: this warning originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use `.iter()` instead of `.into_iter()` to avoid ambiguity + | +LL - $e.into_iter() +LL + $e.iter() + | +help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value + | +LL | IntoIterator::into_iter($e.into_iter()) + | ++++++++++++++++++++++++ + + +warning: for loop over an `Option`. This is more readably written as an `if let` statement + --> $DIR/macro-expansion-empty-span-147408.rs:22:14 + | +LL | for _ in mac!(next [1, 2]) {} + | ^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(for_loops_over_fallibles)]` on by default +help: to iterate over `$e.iter()` remove the call to `next` + | +LL - $e.iter().next() +LL + .by_ref().next() + | +help: consider using `if let` to clear intent + | +LL - for _ in mac!(next [1, 2]) {} +LL + if let Some(_) = mac!(next [1, 2]) {} + | + +warning: 3 warnings emitted +