about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0804.md41
-rw-r--r--compiler/rustc_error_codes/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl9
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs28
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs9
-rw-r--r--compiler/rustc_lint/src/lib.rs5
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs53
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-add-auto.rs14
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-add-auto.stderr44
-rw-r--r--tests/ui/lint/removed-lints/README.md4
-rw-r--r--tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs5
-rw-r--r--tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr10
12 files changed, 110 insertions, 113 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0804.md b/compiler/rustc_error_codes/src/error_codes/E0804.md
new file mode 100644
index 00000000000..9a6937c0b52
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0804.md
@@ -0,0 +1,41 @@
+An auto trait cannot be added to the bounds of a `dyn Trait` type via
+a pointer cast.
+
+Erroneous code example:
+
+```rust,edition2021,compile_fail,E0804
+let ptr: *const dyn core::any::Any = &();
+_ = ptr as *const (dyn core::any::Any + Send);
+```
+
+Adding an auto trait can make the vtable invalid, potentially causing
+UB in safe code afterwards. For example:
+
+```rust,edition2021,no_run
+use core::{mem::transmute, ptr::NonNull};
+
+trait Trait {
+    fn f(&self)
+    where
+        Self: Send;
+}
+
+impl Trait for NonNull<()> {
+    fn f(&self) {
+        unreachable!()
+    }
+}
+
+fn main() {
+    let unsend: &dyn Trait = &NonNull::dangling();
+    let bad: &(dyn Trait + Send) = unsafe { transmute(unsend) };
+    // This crashes, since the vtable for `NonNull as dyn Trait` does
+    // not have an entry for `Trait::f`.
+    bad.f();
+}
+```
+
+To fix this error, you can use `transmute` rather than pointer casts,
+but you must ensure that the vtable is valid for the pointer's type
+before calling a method on the trait object or allowing other code to
+do so.
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index 098ca42be2b..d53d5678832 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -547,6 +547,7 @@ E0800: 0800,
 E0801: 0801,
 E0802: 0802,
 E0803: 0803,
+E0804: 0804,
         );
     )
 }
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index ed80bc3e7be..872861d6289 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -171,10 +171,13 @@ hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function
     .suggestion = cast the value to `{$cast_ty}`
     .teach_help = certain types, like `{$ty}`, must be casted before passing them to a variadic function, because of arcane ABI rules dictated by the C standard
 
-hir_typeck_ptr_cast_add_auto_to_object = adding {$traits_len ->
-    [1] an auto trait {$traits}
+hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len ->
+    [1] auto trait {$traits}
     *[other] auto traits {$traits}
-} to a trait object in a pointer cast may cause UB later on
+} to dyn bound via pointer cast
+    .note = this could allow UB elsewhere
+    .help = use `transmute` if you're sure this is sound
+    .label = unsupported cast
 
 hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression
 hir_typeck_remove_semi_for_coerce_expr = this could be implicitly returned but it is a statement, not a tail expression
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index ea4ec345ad0..70b49fea34f 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -940,23 +940,19 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                             .collect::<Vec<_>>();
 
                         if !added.is_empty() {
-                            tcx.emit_node_span_lint(
-                                lint::builtin::PTR_CAST_ADD_AUTO_TO_OBJECT,
-                                self.expr.hir_id,
-                                self.span,
-                                errors::PtrCastAddAutoToObject {
-                                    traits_len: added.len(),
-                                    traits: {
-                                        let mut traits: Vec<_> = added
-                                            .into_iter()
-                                            .map(|trait_did| tcx.def_path_str(trait_did))
-                                            .collect();
-
-                                        traits.sort();
-                                        traits.into()
-                                    },
+                            tcx.dcx().emit_err(errors::PtrCastAddAutoToObject {
+                                span: self.span,
+                                traits_len: added.len(),
+                                traits: {
+                                    let mut traits: Vec<_> = added
+                                        .into_iter()
+                                        .map(|trait_did| tcx.def_path_str(trait_did))
+                                        .collect();
+
+                                    traits.sort();
+                                    traits.into()
                                 },
-                            )
+                            });
                         }
 
                         Ok(CastKind::PtrPtrCast)
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 20688a5b949..b73cd26927a 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -373,9 +373,14 @@ pub(crate) struct LossyProvenanceInt2Ptr<'tcx> {
     pub sugg: LossyProvenanceInt2PtrSuggestion,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(hir_typeck_ptr_cast_add_auto_to_object)]
+#[derive(Diagnostic)]
+#[diag(hir_typeck_ptr_cast_add_auto_to_object, code = E0804)]
+#[note]
+#[help]
 pub(crate) struct PtrCastAddAutoToObject {
+    #[primary_span]
+    #[label]
+    pub span: Span,
     pub traits_len: usize,
     pub traits: DiagSymbolList<String>,
 }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 5c5b3b350dd..7018774e5c6 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -599,6 +599,11 @@ fn register_builtins(store: &mut LintStore) {
         "converted into hard error, \
          see <https://github.com/rust-lang/rust/issues/73333> for more information",
     );
+    store.register_removed(
+        "ptr_cast_add_auto_to_object",
+        "converted into hard error, see issue #127323 \
+         <https://github.com/rust-lang/rust/issues/127323> for more information",
+    );
 }
 
 fn register_internals(store: &mut LintStore) {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 3d63ea82053..10b85be2cfb 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -80,7 +80,6 @@ declare_lint_pass! {
         PRIVATE_BOUNDS,
         PRIVATE_INTERFACES,
         PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
-        PTR_CAST_ADD_AUTO_TO_OBJECT,
         PTR_TO_INTEGER_TRANSMUTE_IN_CONSTS,
         PUB_USE_OF_PRIVATE_EXTERN_CRATE,
         REDUNDANT_IMPORTS,
@@ -4828,58 +4827,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `ptr_cast_add_auto_to_object` lint detects casts of raw pointers to trait
-    /// objects, which add auto traits.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,edition2021,compile_fail
-    /// let ptr: *const dyn core::any::Any = &();
-    /// _ = ptr as *const dyn core::any::Any + Send;
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// Adding an auto trait can make the vtable invalid, potentially causing
-    /// UB in safe code afterwards. For example:
-    ///
-    /// ```ignore (causes a warning)
-    /// #![feature(arbitrary_self_types)]
-    ///
-    /// trait Trait {
-    ///     fn f(self: *const Self)
-    ///     where
-    ///         Self: Send;
-    /// }
-    ///
-    /// impl Trait for *const () {
-    ///     fn f(self: *const Self) {
-    ///         unreachable!()
-    ///     }
-    /// }
-    ///
-    /// fn main() {
-    ///     let unsend: *const () = &();
-    ///     let unsend: *const dyn Trait = &unsend;
-    ///     let send_bad: *const (dyn Trait + Send) = unsend as _;
-    ///     send_bad.f(); // this crashes, since vtable for `*const ()` does not have an entry for `f`
-    /// }
-    /// ```
-    ///
-    /// Generally you must ensure that vtable is right for the pointer's type,
-    /// before passing the pointer to safe code.
-    pub PTR_CAST_ADD_AUTO_TO_OBJECT,
-    Warn,
-    "detects `as` casts from pointers to `dyn Trait` to pointers to `dyn Trait + Auto`",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
-        reference: "issue #127323 <https://github.com/rust-lang/rust/issues/127323>",
-    };
-}
-
-declare_lint! {
     /// The `out_of_scope_macro_calls` lint detects `macro_rules` called when they are not in scope,
     /// above their definition, which may happen in key-value attributes.
     ///
diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs
index 46e72ea0877..3a1e667d03a 100644
--- a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs
+++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs
@@ -1,18 +1,20 @@
-//@ check-pass
-
 trait Trait<'a> {}
 
 fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) {
     x as _
-    //~^ warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on
-    //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //~^ ERROR cannot add auto trait `Send` to dyn bound via pointer cast
+    //~| NOTE unsupported cast
+    //~| NOTE this could allow UB elsewhere
+    //~| HELP use `transmute` if you're sure this is sound
 }
 
 // (to test diagnostic list formatting)
 fn add_multiple_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send + Sync + Unpin) {
     x as _
-    //~^ warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on
-    //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //~^ ERROR cannot add auto traits `Send`, `Sync`, and `Unpin` to dyn bound via pointer cast
+    //~| NOTE unsupported cast
+    //~| NOTE this could allow UB elsewhere
+    //~| HELP use `transmute` if you're sure this is sound
 }
 
 fn main() {}
diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr
index e5ef8bf76b4..b64ca9b32bf 100644
--- a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr
+++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr
@@ -1,43 +1,21 @@
-warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on
-  --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5
+error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
+  --> $DIR/ptr-to-trait-obj-add-auto.rs:4:5
    |
 LL |     x as _
-   |     ^^^^^^
+   |     ^^^^^^ unsupported cast
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #127323 <https://github.com/rust-lang/rust/issues/127323>
-   = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default
+   = note: this could allow UB elsewhere
+   = help: use `transmute` if you're sure this is sound
 
-warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on
+error[E0804]: cannot add auto traits `Send`, `Sync`, and `Unpin` to dyn bound via pointer cast
   --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5
    |
 LL |     x as _
-   |     ^^^^^^
+   |     ^^^^^^ unsupported cast
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #127323 <https://github.com/rust-lang/rust/issues/127323>
+   = note: this could allow UB elsewhere
+   = help: use `transmute` if you're sure this is sound
 
-warning: 2 warnings emitted
-
-Future incompatibility report: Future breakage diagnostic:
-warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on
-  --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5
-   |
-LL |     x as _
-   |     ^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #127323 <https://github.com/rust-lang/rust/issues/127323>
-   = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default
-
-Future breakage diagnostic:
-warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on
-  --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5
-   |
-LL |     x as _
-   |     ^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #127323 <https://github.com/rust-lang/rust/issues/127323>
-   = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0804`.
diff --git a/tests/ui/lint/removed-lints/README.md b/tests/ui/lint/removed-lints/README.md
new file mode 100644
index 00000000000..abe7ee04115
--- /dev/null
+++ b/tests/ui/lint/removed-lints/README.md
@@ -0,0 +1,4 @@
+# Removed lints
+
+This directory contains tests to confirm that lints that have been
+removed do not cause errors and produce the appropriate warnings.
diff --git a/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs
new file mode 100644
index 00000000000..7fb635487ff
--- /dev/null
+++ b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs
@@ -0,0 +1,5 @@
+//@ check-pass
+
+#![deny(ptr_cast_add_auto_to_object)]
+//~^ WARN  lint `ptr_cast_add_auto_to_object` has been removed
+fn main() {}
diff --git a/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr
new file mode 100644
index 00000000000..36b5e847d80
--- /dev/null
+++ b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr
@@ -0,0 +1,10 @@
+warning: lint `ptr_cast_add_auto_to_object` has been removed: converted into hard error, see issue #127323 <https://github.com/rust-lang/rust/issues/127323> for more information
+  --> $DIR/ptr_cast_add_auto_to_object.rs:3:9
+   |
+LL | #![deny(ptr_cast_add_auto_to_object)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(renamed_and_removed_lints)]` on by default
+
+warning: 1 warning emitted
+