diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index a40fa600c19..4165ccb1b80 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; @@ -186,7 +186,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pick = self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?; - self.lint_dot_call_from_2018(self_ty, segment, span, call_expr, self_expr, &pick, args); + self.lint_edition_dependent_dot_call( + self_ty, segment, span, call_expr, self_expr, &pick, args, + ); for &import_id in &pick.import_ids { debug!("used_trait_import: {:?}", import_id); diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs similarity index 90% rename from compiler/rustc_hir_typeck/src/method/prelude2021.rs rename to compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs index eca326892b5..e9eab6969b3 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs @@ -1,12 +1,12 @@ -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_lint::{ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER}; use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; @@ -17,7 +17,7 @@ use rustc_trait_selection::infer::InferCtxtExt; use std::fmt::Write; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub(super) fn lint_dot_call_from_2018( + pub(super) fn lint_edition_dependent_dot_call( &self, self_ty: Ty<'tcx>, segment: &hir::PathSegment<'_>, @@ -32,22 +32,32 @@ 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 boxed-slice-into_iter hack will no + // longer apply in Rust 2024. + (BOXED_SLICE_INTO_ITER, "2024") + } else { + return; + } } _ => return, }; @@ -81,7 +91,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 +144,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 10c2557baa7..64fcc7e46e0 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -81,7 +81,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 00000000000..d49fee55a05 --- /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 00000000000..e78f550d226 --- /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 00000000000..9cc79a7b129 --- /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 +