Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn when [T; N].into_iter() is ambiguous in the new edition. #88503

Merged
merged 3 commits into from
Aug 31, 2021
Merged
Show file tree
Hide file tree
Changes from all 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" }
24 changes: 17 additions & 7 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,10 +38,20 @@ 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) {
return;
}
let prelude_or_array_lint = match segment.ident.name {
// `try_into` was added to the prelude in Rust 2021.
sym::try_into => RUST_2021_PRELUDE_COLLISIONS,
// `into_iter` wasn't added to the prelude,
// but `[T; N].into_iter()` doesn't resolve to IntoIterator::into_iter
// before Rust 2021, which results in the same problem.
// It is only a problem for arrays.
sym::into_iter 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
}
_ => return,
};

// 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) {
Expand Down Expand Up @@ -69,7 +79,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 +140,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