Skip to content

Commit 336f314

Browse files
committed
Warn when [T; N].into_iter() is ambiguous in the new edition.
1 parent 13edc17 commit 336f314

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4405,6 +4405,7 @@ dependencies = [
44054405
"rustc_hir_pretty",
44064406
"rustc_index",
44074407
"rustc_infer",
4408+
"rustc_lint",
44084409
"rustc_macros",
44094410
"rustc_middle",
44104411
"rustc_session",

compiler/rustc_lint/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ mod traits;
6262
mod types;
6363
mod unused;
6464

65+
pub use array_into_iter::ARRAY_INTO_ITER;
66+
6567
use rustc_ast as ast;
6668
use rustc_hir as hir;
6769
use rustc_hir::def_id::LocalDefId;

compiler/rustc_typeck/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ rustc_index = { path = "../rustc_index" }
2626
rustc_infer = { path = "../rustc_infer" }
2727
rustc_trait_selection = { path = "../rustc_trait_selection" }
2828
rustc_ty_utils = { path = "../rustc_ty_utils" }
29+
rustc_lint = { path = "../rustc_lint" }

compiler/rustc_typeck/src/check/method/prelude2021.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_ast::Mutability;
55
use rustc_errors::Applicability;
66
use rustc_hir as hir;
77
use rustc_middle::ty::subst::InternalSubsts;
8-
use rustc_middle::ty::{Adt, Ref, Ty};
8+
use rustc_middle::ty::{Adt, Array, Ref, Ty};
99
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
1010
use rustc_span::symbol::kw::Underscore;
1111
use rustc_span::symbol::{sym, Ident};
@@ -38,11 +38,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3838
return;
3939
}
4040

41-
// These are the method names that were added to prelude in Rust 2021
42-
if !matches!(segment.ident.name, sym::try_into) {
41+
// `try_into` was added to the prelude in Rust 2021.
42+
// `into_iter` wasn't, but `[T; N].into_iter()` doesn't resolve to
43+
// IntoIterator::into_iter before Rust 2021, which results in the same
44+
// problem.
45+
if !matches!(segment.ident.name, sym::try_into | sym::into_iter) {
4346
return;
4447
}
4548

49+
let prelude_or_array_lint = if segment.ident.name == sym::into_iter {
50+
// The `into_iter` problem is only a thing for arrays.
51+
if let Array(..) = self_ty.kind() {
52+
// In this case, it wasn't really a prelude addition that was the problem.
53+
// Instead, the problem is that the array-into_iter hack will no longer apply in Rust 2021.
54+
rustc_lint::ARRAY_INTO_ITER
55+
} else {
56+
// No problem in this case.
57+
return;
58+
}
59+
} else {
60+
RUST_2021_PRELUDE_COLLISIONS
61+
};
62+
4663
// No need to lint if method came from std/core, as that will now be in the prelude
4764
if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
4865
return;
@@ -69,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6986
// Inherent impls only require not relying on autoref and autoderef in order to
7087
// ensure that the trait implementation won't be used
7188
self.tcx.struct_span_lint_hir(
72-
RUST_2021_PRELUDE_COLLISIONS,
89+
prelude_or_array_lint,
7390
self_expr.hir_id,
7491
self_expr.span,
7592
|lint| {
@@ -130,7 +147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
130147
// trait implementations require full disambiguation to not clash with the new prelude
131148
// additions (i.e. convert from dot-call to fully-qualified call)
132149
self.tcx.struct_span_lint_hir(
133-
RUST_2021_PRELUDE_COLLISIONS,
150+
prelude_or_array_lint,
134151
call_expr.hir_id,
135152
call_expr.span,
136153
|lint| {

0 commit comments

Comments
 (0)