Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4405,6 +4405,7 @@ dependencies = [
"rustc_hir_pretty",
"rustc_index",
"rustc_infer",
"rustc_lint",
"rustc_macros",
"rustc_middle",
"rustc_session",
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_typeck/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
27 changes: 22 additions & 5 deletions compiler/rustc_typeck/src/check/method/prelude2021.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this test be merged with the previous one, for instance as a match?

// 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;
Expand All @@ -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| {
Expand Down Expand Up @@ -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| {
Expand Down
27 changes: 27 additions & 0 deletions src/test/ui/rust-2021/array-into-iter-ambiguous.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// See https://github.com/rust-lang/rust/issues/88475
// run-rustfix
// edition:2018
// check-pass
#![warn(array_into_iter)]
#![allow(unused)]

struct FooIter;

trait MyIntoIter {
fn into_iter(self) -> FooIter;
}

impl<T, const N: usize> MyIntoIter for [T; N] {
fn into_iter(self) -> FooIter {
FooIter
}
}

struct Point;

pub fn main() {
let points: [Point; 1] = [Point];
let y = MyIntoIter::into_iter(points);
//~^ WARNING trait method `into_iter` will become ambiguous in Rust 2021
//~| WARNING this changes meaning in Rust 2021
}
27 changes: 27 additions & 0 deletions src/test/ui/rust-2021/array-into-iter-ambiguous.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// See https://github.com/rust-lang/rust/issues/88475
// run-rustfix
// edition:2018
// check-pass
#![warn(array_into_iter)]
#![allow(unused)]

struct FooIter;

trait MyIntoIter {
fn into_iter(self) -> FooIter;
}

impl<T, const N: usize> MyIntoIter for [T; N] {
fn into_iter(self) -> FooIter {
FooIter
}
}

struct Point;

pub fn main() {
let points: [Point; 1] = [Point];
let y = points.into_iter();
//~^ WARNING trait method `into_iter` will become ambiguous in Rust 2021
//~| WARNING this changes meaning in Rust 2021
}
16 changes: 16 additions & 0 deletions src/test/ui/rust-2021/array-into-iter-ambiguous.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
warning: trait method `into_iter` will become ambiguous in Rust 2021
--> $DIR/array-into-iter-ambiguous.rs:24:13
|
LL | let y = points.into_iter();
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyIntoIter::into_iter(points)`
|
note: the lint level is defined here
--> $DIR/array-into-iter-ambiguous.rs:5:9
|
LL | #![warn(array_into_iter)]
| ^^^^^^^^^^^^^^^
= warning: this changes meaning in Rust 2021
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>

warning: 1 warning emitted