about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs17
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs41
2 files changed, 57 insertions, 1 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs
index 3ee10f74d98..3a902390fcf 100644
--- a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs
+++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs
@@ -9,7 +9,7 @@ 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;
+use rustc_session::lint::builtin::{RUST_2021_PRELUDE_COLLISIONS, RUST_2024_PRELUDE_COLLISIONS};
 use rustc_span::symbol::kw::{Empty, Underscore};
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
@@ -35,6 +35,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let (prelude_or_array_lint, edition) = match segment.ident.name {
             // `try_into` was added to the prelude in Rust 2021.
             sym::try_into if !span.at_least_rust_2021() => (RUST_2021_PRELUDE_COLLISIONS, "2021"),
+            // `Future::poll` was added to the prelude in Rust 2024.
+            sym::poll
+                // We check that the self type is `Pin<&mut _>` to avoid false positives for this common name.
+                if !span.at_least_rust_2024()
+                    && let ty::Adt(adt_def, args) = self_ty.kind()
+                    && self.tcx.is_lang_item(adt_def.did(), hir::LangItem::Pin)
+                    && let ty::Ref(_, _, ty::Mutability::Mut) =
+                        args[0].as_type().unwrap().kind() =>
+            {
+                (RUST_2024_PRELUDE_COLLISIONS, "2024")
+            }
+            // `IntoFuture::into_future` was added to the prelude in Rust 2024.
+            sym::into_future if !span.at_least_rust_2024() => {
+                (RUST_2024_PRELUDE_COLLISIONS, "2024")
+            }
             // `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.
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index c4158cccca4..06d6a6cd612 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -91,6 +91,7 @@ declare_lint_pass! {
         RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
         RUST_2021_PRELUDE_COLLISIONS,
         RUST_2024_INCOMPATIBLE_PAT,
+        RUST_2024_PRELUDE_COLLISIONS,
         SELF_CONSTRUCTOR_FROM_OUTER_ITEM,
         SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
         SINGLE_USE_LIFETIMES,
@@ -3755,6 +3756,46 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `rust_2024_prelude_collisions` lint detects the usage of trait methods which are ambiguous
+    /// with traits added to the prelude in future editions.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,edition2021,compile_fail
+    /// #![deny(rust_2024_prelude_collisions)]
+    /// trait Meow {
+    ///     fn poll(&self) {}
+    /// }
+    /// impl<T> Meow for T {}
+    ///
+    /// fn main() {
+    ///     core::pin::pin!(async {}).poll();
+    ///     //                        ^^^^^^
+    ///     // This call to try_into matches both Future::poll and Meow::poll as
+    ///     // `Future` has been added to the Rust prelude in 2024 edition.
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Rust 2024, introduces two new additions to the standard library's prelude:
+    /// `Future` and `IntoFuture`. This results in an ambiguity as to which method/function
+    /// to call when an existing `poll`/`into_future` method is called via dot-call syntax or
+    /// a `poll`/`into_future` associated function is called directly on a type.
+    ///
+    pub RUST_2024_PRELUDE_COLLISIONS,
+    Allow,
+    "detects the usage of trait methods which are ambiguous with traits added to the \
+        prelude in future editions",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
+        reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>",
+    };
+}
+
+declare_lint! {
     /// The `rust_2021_prefixes_incompatible_syntax` lint detects identifiers that will be parsed as a
     /// prefix instead in Rust 2021.
     ///