diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 39d54f1a25e0b..4fc7109df1e2e 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -3,7 +3,7 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/method-lookup.html mod confirm; -mod prelude2021; +mod prelude_edition_lints; pub mod probe; mod suggest; diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs similarity index 91% rename from compiler/rustc_hir_typeck/src/method/prelude2021.rs rename to compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs index 22eef8e53dae0..04f71603ee6ca 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs @@ -1,13 +1,13 @@ -use crate::{ - method::probe::{self, Pick}, - FnCtxt, -}; +use crate::method::probe::{self, Pick}; +use crate::FnCtxt; + use hir::def_id::DefId; use hir::HirId; use hir::ItemKind; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_infer::infer::type_variable::TypeVariableOrigin; +use rustc_lint::{ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER}; use rustc_middle::ty::{self, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::{Empty, Underscore}; @@ -32,22 +32,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { segment.ident, self_ty, call_expr, self_expr ); - // Rust 2021 and later is already using the new prelude - if span.at_least_rust_2021() { - return; - } - - let prelude_or_array_lint = match segment.ident.name { + let (prelude_or_array_lint, edition) = match segment.ident.name { // `try_into` was added to the prelude in Rust 2021. - sym::try_into => RUST_2021_PRELUDE_COLLISIONS, + sym::try_into if !span.at_least_rust_2021() => (RUST_2021_PRELUDE_COLLISIONS, "2021"), // `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 ty::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 + sym::into_iter => { + if let ty::Array(..) = self_ty.kind() + && !span.at_least_rust_2021() + { + // 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. + (ARRAY_INTO_ITER, "2021") + } else if self_ty.is_box() + && self_ty.boxed_ty().is_slice() + && !span.at_least_rust_2024() + { + // 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. + (BOXED_SLICE_INTO_ITER, "2024") + } else { + return; + } } _ => return, }; @@ -81,7 +89,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prelude_or_array_lint, self_expr.hir_id, self_expr.span, - format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name), + format!( + "trait method `{}` will become ambiguous in Rust {edition}", + segment.ident.name + ), |lint| { let sp = self_expr.span; @@ -131,7 +142,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prelude_or_array_lint, call_expr.hir_id, call_expr.span, - format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name), + format!( + "trait method `{}` will become ambiguous in Rust {edition}", + segment.ident.name + ), |lint| { let sp = call_expr.span; let trait_name = self.trait_path_or_bare_name( diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index fa84184497434..961aed6a81a8c 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -85,7 +85,7 @@ mod types; mod unit_bindings; mod unused; -pub use shadowed_into_iter::ARRAY_INTO_ITER; +pub use shadowed_into_iter::{ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER}; use rustc_hir::def_id::LocalModDefId; use rustc_middle::query::Providers; diff --git a/tests/ui/rust-2024/box-slice-into-iter-ambiguous.fixed b/tests/ui/rust-2024/box-slice-into-iter-ambiguous.fixed new file mode 100644 index 0000000000000..d49fee55a05bf --- /dev/null +++ b/tests/ui/rust-2024/box-slice-into-iter-ambiguous.fixed @@ -0,0 +1,27 @@ +// See https://github.com/rust-lang/rust/issues/88475 +//@ run-rustfix +//@ edition:2021 +//@ check-pass +#![warn(boxed_slice_into_iter)] +#![allow(unused)] + +struct FooIter; + +trait MyIntoIter { + fn into_iter(self) -> FooIter; +} + +impl MyIntoIter for Box<[T]> { + fn into_iter(self) -> FooIter { + FooIter + } +} + +struct Point; + +pub fn main() { + let points: Box<[_]> = vec![Point].into_boxed_slice(); + let y = MyIntoIter::into_iter(points); + //~^ WARNING trait method `into_iter` will become ambiguous in Rust 2024 + //~| WARNING this changes meaning in Rust 2024 +} diff --git a/tests/ui/rust-2024/box-slice-into-iter-ambiguous.rs b/tests/ui/rust-2024/box-slice-into-iter-ambiguous.rs new file mode 100644 index 0000000000000..e78f550d226f2 --- /dev/null +++ b/tests/ui/rust-2024/box-slice-into-iter-ambiguous.rs @@ -0,0 +1,27 @@ +// See https://github.com/rust-lang/rust/issues/88475 +//@ run-rustfix +//@ edition:2021 +//@ check-pass +#![warn(boxed_slice_into_iter)] +#![allow(unused)] + +struct FooIter; + +trait MyIntoIter { + fn into_iter(self) -> FooIter; +} + +impl MyIntoIter for Box<[T]> { + fn into_iter(self) -> FooIter { + FooIter + } +} + +struct Point; + +pub fn main() { + let points: Box<[_]> = vec![Point].into_boxed_slice(); + let y = points.into_iter(); + //~^ WARNING trait method `into_iter` will become ambiguous in Rust 2024 + //~| WARNING this changes meaning in Rust 2024 +} diff --git a/tests/ui/rust-2024/box-slice-into-iter-ambiguous.stderr b/tests/ui/rust-2024/box-slice-into-iter-ambiguous.stderr new file mode 100644 index 0000000000000..9cc79a7b12947 --- /dev/null +++ b/tests/ui/rust-2024/box-slice-into-iter-ambiguous.stderr @@ -0,0 +1,15 @@ +warning: trait method `into_iter` will become ambiguous in Rust 2024 + --> $DIR/box-slice-into-iter-ambiguous.rs:24:13 + | +LL | let y = points.into_iter(); + | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyIntoIter::into_iter(points)` + | + = warning: this changes meaning in Rust 2024 +note: the lint level is defined here + --> $DIR/box-slice-into-iter-ambiguous.rs:5:9 + | +LL | #![warn(boxed_slice_into_iter)] + | ^^^^^^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted +