diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs index 45c32bfd1d5c5..cfb2a7fb61864 100644 --- a/compiler/rustc_lint/src/shadowed_into_iter.rs +++ b/compiler/rustc_lint/src/shadowed_into_iter.rs @@ -124,6 +124,11 @@ impl<'tcx> LateLintPass<'tcx> for ShadowedIntoIter { return; }; + // This check needs to avoid ICE from when `receiver_arg` is from macro expansion + // Which leads to empty span in span arithmetic below + // cc: https://github.com/rust-lang/rust/issues/147408 + let span = receiver_arg.span.find_ancestor_in_same_ctxt(expr.span); + // If this expression comes from the `IntoIter::into_iter` inside of a for loop, // we should just suggest removing the `.into_iter()` or changing it to `.iter()` // to disambiguate if we want to iterate by-value or by-ref. @@ -134,14 +139,15 @@ impl<'tcx> LateLintPass<'tcx> for ShadowedIntoIter { && let hir::ExprKind::Call(path, [_]) = &arg.kind && let hir::ExprKind::Path(qpath) = path.kind && cx.tcx.qpath_is_lang_item(qpath, LangItem::IntoIterIntoIter) + && let Some(span) = span { Some(ShadowedIntoIterDiagSub::RemoveIntoIter { - span: receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()), + span: span.shrink_to_hi().to(expr.span.shrink_to_hi()), }) - } else if can_suggest_ufcs { + } else if can_suggest_ufcs && let Some(span) = span { Some(ShadowedIntoIterDiagSub::UseExplicitIntoIter { start_span: expr.span.shrink_to_lo(), - end_span: receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()), + end_span: span.shrink_to_hi().to(expr.span.shrink_to_hi()), }) } else { None 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..6df96d7b05d45 --- /dev/null +++ b/tests/ui/macros/macro-expansion-empty-span-147408.rs @@ -0,0 +1,24 @@ +//@ check-pass +//@ compile-flags: -Afor_loops_over_fallibles -Warray_into_iter + +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]) {} +} 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..c4faaa20101d3 --- /dev/null +++ b/tests/ui/macros/macro-expansion-empty-span-147408.stderr @@ -0,0 +1,35 @@ +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:19:27 + | +LL | for _ in dbg!([1, 2]).into_iter() {} + | ^^^^^^^^^ + | + = warning: this changes meaning in Rust 2021 + = note: for more information, see + = note: requested on the command line with `-W array-into-iter` +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() {} + | +help: or remove `.into_iter()` to iterate by value + | +LL - for _ in dbg!([1, 2]).into_iter() {} +LL + for _ in dbg!([1, 2]) {} + | + +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:10:16 + | +LL | $e.into_iter() + | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `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) + +warning: 2 warnings emitted +