From 87e4a3dad1321d26ce25f223e89fd6511ce52b71 Mon Sep 17 00:00:00 2001 From: Albab-Hasan Date: Tue, 24 Feb 2026 18:56:08 +0600 Subject: [PATCH] fix: detect E0804 when casting raw ptr-to-dyn adds auto traits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the `check_ptr_ptr_cast` function had an early return when the source and destination dyn trait objects shared the same principal trait def id: if src_principal == dst_principal { return Ok(()); } this bypassed all three remaining checks that the code comment explicitly listed as required: generic argument equality, projection equality, and the auto-trait superset check. as a result, casts like `*mut dyn Trait as *mut (dyn Trait + Send)` were silently accepted instead of emitting E0804. the fix removes the early return. `CastError::PtrPtrAddingAutoTraits` and its diagnostic were already implemented — they just couldn't be reached. the supertrait case (`trait Trait: Send`) continues to work correctly because the auto-trait check already accounts for implied auto traits via supertrait elaboration. --- src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs | 6 +----- .../crates/ide-diagnostics/src/handlers/invalid_cast.rs | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs index d69b00adb7f7..fc38361d7e41 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs @@ -328,11 +328,7 @@ fn check_ptr_ptr_cast( // // Note that trait upcasting goes through a different mechanism (`coerce_unsized`) // and is unaffected by this check. - (Some(src_principal), Some(dst_principal)) => { - if src_principal == dst_principal { - return Ok(()); - } - + (Some(src_principal), Some(_)) => { // We need to reconstruct trait object types. // `m_src` and `m_dst` won't work for us here because they will potentially // contain wrappers, which we do not care about. diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs index 7479f8147d2e..405d8df6854d 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs @@ -517,11 +517,13 @@ trait Trait<'a> {} fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) { x as _ + //^^^^^^ error: cannot add auto trait to dyn bound via pointer cast } // (to test diagnostic list formatting) fn add_multiple_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send + Sync + Unpin) { x as _ + //^^^^^^ error: cannot add auto trait to dyn bound via pointer cast } "#, );