From 336f31432df03e4dbd635dddedad1c9e67271a0c Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 30 Aug 2021 21:19:24 +0200 Subject: [PATCH] Warn when [T; N].into_iter() is ambiguous in the new edition. --- Cargo.lock | 1 + compiler/rustc_lint/src/lib.rs | 2 ++ compiler/rustc_typeck/Cargo.toml | 1 + .../src/check/method/prelude2021.rs | 27 +++++++++++++++---- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74a316ed5f04..f47704bbf684 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4405,6 +4405,7 @@ dependencies = [ "rustc_hir_pretty", "rustc_index", "rustc_infer", + "rustc_lint", "rustc_macros", "rustc_middle", "rustc_session", diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 24ac723f2c91..ef4bda666ba0 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -62,6 +62,8 @@ mod traits; mod types; mod unused; +pub use array_into_iter::ARRAY_INTO_ITER; + use rustc_ast as ast; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; diff --git a/compiler/rustc_typeck/Cargo.toml b/compiler/rustc_typeck/Cargo.toml index fa5ef63f5c52..dd76a5e4b99b 100644 --- a/compiler/rustc_typeck/Cargo.toml +++ b/compiler/rustc_typeck/Cargo.toml @@ -26,3 +26,4 @@ rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_ty_utils = { path = "../rustc_ty_utils" } +rustc_lint = { path = "../rustc_lint" } diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index b5bc9d3599ac..d5881ad8a512 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -5,7 +5,7 @@ use rustc_ast::Mutability; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{Adt, Ref, Ty}; +use rustc_middle::ty::{Adt, Array, Ref, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::Underscore; use rustc_span::symbol::{sym, Ident}; @@ -38,11 +38,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - // These are the method names that were added to prelude in Rust 2021 - if !matches!(segment.ident.name, sym::try_into) { + // `try_into` was added to the prelude in Rust 2021. + // `into_iter` wasn't, but `[T; N].into_iter()` doesn't resolve to + // IntoIterator::into_iter before Rust 2021, which results in the same + // problem. + if !matches!(segment.ident.name, sym::try_into | sym::into_iter) { return; } + let prelude_or_array_lint = if segment.ident.name == sym::into_iter { + // The `into_iter` problem is only a thing for arrays. + if let Array(..) = self_ty.kind() { + // In this case, it wasn't really a prelude addition that was the problem. + // Instead, the problem is that the array-into_iter hack will no longer apply in Rust 2021. + rustc_lint::ARRAY_INTO_ITER + } else { + // No problem in this case. + return; + } + } else { + RUST_2021_PRELUDE_COLLISIONS + }; + // No need to lint if method came from std/core, as that will now be in the prelude if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { return; @@ -69,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Inherent impls only require not relying on autoref and autoderef in order to // ensure that the trait implementation won't be used self.tcx.struct_span_lint_hir( - RUST_2021_PRELUDE_COLLISIONS, + prelude_or_array_lint, self_expr.hir_id, self_expr.span, |lint| { @@ -130,7 +147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // trait implementations require full disambiguation to not clash with the new prelude // additions (i.e. convert from dot-call to fully-qualified call) self.tcx.struct_span_lint_hir( - RUST_2021_PRELUDE_COLLISIONS, + prelude_or_array_lint, call_expr.hir_id, call_expr.span, |lint| {