Skip to content

transmute-ptr-to-ptr suggested path does not work #15835

@matthiaskrgr

Description

@matthiaskrgr

Using the following flags

--force-warn clippy::transmute-ptr-to-ptr

this code:

fn bidirectional_subtyping() {
    // Test that transmuting between subtypes of dyn traits is fine, even in the
    // "wrong direction", i.e. going from a lower-ranked to a higher-ranked dyn trait.
    // Note that compared to the `dyn-transmute-inner-binder` test, the `for` is on the
    // *outside* here!

    trait Trait<U: ?Sized> {}
    impl<T, U: ?Sized> Trait<U> for T {}

    struct Wrapper<T: ?Sized>(T);

    let x: &dyn Trait<fn(&'static ())> = &();
    let _y: &dyn for<'a> Trait<fn(&'a ())> = unsafe { std::mem::transmute(x) };

    let x: &dyn for<'a> Trait<fn(&'a ())> = &();
    let _y: &dyn Trait<fn(&'static ())> = unsafe { std::mem::transmute(x) };

    let x: &dyn Trait<dyn Trait<fn(&'static ())>> = &();
    let _y: &dyn for<'a> Trait<dyn Trait<fn(&'a ())>> = unsafe { std::mem::transmute(x) };

    let x: &dyn for<'a> Trait<dyn Trait<fn(&'a ())>> = &();
    let _y: &dyn Trait<dyn Trait<fn(&'static ())>> = unsafe { std::mem::transmute(x) };

    // This lowers to a ptr-to-ptr cast (which behaves like a transmute)
    // and not an unsizing coercion:
    let x: *const dyn for<'a> Trait<&'a ()> = &();
    let _y: *const Wrapper<dyn Trait<&'static ()>> = x as _;
}

caused the following diagnostics:

    Checking _a v0.1.0 (/tmp/icemaker_global_tempdir.OhkT1XoKk8t8/icemaker_clippyfix_tempdir.sfnw4ze5vQKV/_a)
warning: transmute from a reference to a reference
  --> src/lib.rs:13:55
   |
13 |     let _y: &dyn for<'a> Trait<fn(&'a ())> = unsafe { std::mem::transmute(x) };
   |                                                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const dyn bidirectional_subtyping::Trait<fn(&())> as *const dyn for<'a> bidirectional_subtyping::Trait<fn(&'a ())>)`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ptr
   = note: requested on the command line with `--force-warn clippy::transmute-ptr-to-ptr`

warning: transmute from a reference to a reference
  --> src/lib.rs:16:52
   |
16 |     let _y: &dyn Trait<fn(&'static ())> = unsafe { std::mem::transmute(x) };
   |                                                    ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const dyn for<'a> bidirectional_subtyping::Trait<fn(&'a ())> as *const dyn bidirectional_subtyping::Trait<fn(&())>)`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ptr

warning: transmute from a reference to a reference
  --> src/lib.rs:19:66
   |
19 |     let _y: &dyn for<'a> Trait<dyn Trait<fn(&'a ())>> = unsafe { std::mem::transmute(x) };
   |                                                                  ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const dyn bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&())>> as *const dyn for<'a> bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&'a ())>>)`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ptr

warning: transmute from a reference to a reference
  --> src/lib.rs:22:63
   |
22 |     let _y: &dyn Trait<dyn Trait<fn(&'static ())>> = unsafe { std::mem::transmute(x) };
   |                                                               ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const dyn for<'a> bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&'a ())>> as *const dyn bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&())>>)`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ptr

warning: `_a` (lib) generated 4 warnings
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.23s

However after applying these diagnostics, the resulting code:

fn bidirectional_subtyping() {
    // Test that transmuting between subtypes of dyn traits is fine, even in the
    // "wrong direction", i.e. going from a lower-ranked to a higher-ranked dyn trait.
    // Note that compared to the `dyn-transmute-inner-binder` test, the `for` is on the
    // *outside* here!

    trait Trait<U: ?Sized> {}
    impl<T, U: ?Sized> Trait<U> for T {}

    struct Wrapper<T: ?Sized>(T);

    let x: &dyn Trait<fn(&'static ())> = &();
    let _y: &dyn for<'a> Trait<fn(&'a ())> = unsafe { &*(x as *const dyn bidirectional_subtyping::Trait<fn(&())> as *const dyn for<'a> bidirectional_subtyping::Trait<fn(&'a ())>) };

    let x: &dyn for<'a> Trait<fn(&'a ())> = &();
    let _y: &dyn Trait<fn(&'static ())> = unsafe { &*(x as *const dyn for<'a> bidirectional_subtyping::Trait<fn(&'a ())> as *const dyn bidirectional_subtyping::Trait<fn(&())>) };

    let x: &dyn Trait<dyn Trait<fn(&'static ())>> = &();
    let _y: &dyn for<'a> Trait<dyn Trait<fn(&'a ())>> = unsafe { &*(x as *const dyn bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&())>> as *const dyn for<'a> bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&'a ())>>) };

    let x: &dyn for<'a> Trait<dyn Trait<fn(&'a ())>> = &();
    let _y: &dyn Trait<dyn Trait<fn(&'static ())>> = unsafe { &*(x as *const dyn for<'a> bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&'a ())>> as *const dyn bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&())>>) };

    // This lowers to a ptr-to-ptr cast (which behaves like a transmute)
    // and not an unsizing coercion:
    let x: *const dyn for<'a> Trait<&'a ()> = &();
    let _y: *const Wrapper<dyn Trait<&'static ()>> = x as _;
}

no longer compiled:

    Checking _a v0.1.0 (/tmp/icemaker_global_tempdir.OhkT1XoKk8t8/icemaker_clippyfix_tempdir.sfnw4ze5vQKV/_a)
error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:13:74
   |
13 | ...afe { &*(x as *const dyn bidirectional_subtyping::Trait<fn(&())> as *const dyn for<'a> bidirectional_subtyping::Trait<fn(&'a ())>) };
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:13:136
   |
13 | ...)> as *const dyn for<'a> bidirectional_subtyping::Trait<fn(&'a ())>) };
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:16:79
   |
16 | ...(x as *const dyn for<'a> bidirectional_subtyping::Trait<fn(&'a ())> as *const dyn bidirectional_subtyping::Trait<fn(&())>) };
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:16:136
   |
16 | ...n(&'a ())> as *const dyn bidirectional_subtyping::Trait<fn(&())>) };
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:19:85
   |
19 | ...afe { &*(x as *const dyn bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&())>> as *const dyn for<'a> bidirection...
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:19:120
   |
19 | ...nal_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&())>> as *const dyn for<'a> bidirectional_subtyping::Trait<dyn bidirection...
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:19:183
   |
19 | ...>> as *const dyn for<'a> bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&'a ())>>) };
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:19:218
   |
19 | ...nal_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&'a ())>>) };
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:22:90
   |
22 | ...(x as *const dyn for<'a> bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&'a ())>> as *const dyn bidirectional_su...
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:22:125
   |
22 | ...nal_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&'a ())>> as *const dyn bidirectional_subtyping::Trait<dyn bidirectional_su...
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:22:183
   |
22 | ...(&'a ())>> as *const dyn bidirectional_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&())>>) };
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

error[E0433]: failed to resolve: function `bidirectional_subtyping` is not a crate or module
  --> src/lib.rs:22:218
   |
22 | ...nal_subtyping::Trait<dyn bidirectional_subtyping::Trait<fn(&())>>) };
   |                             ^^^^^^^^^^^^^^^^^^^^^^^ function `bidirectional_subtyping` is not a crate or module

For more information about this error, try `rustc --explain E0433`.
error: could not compile `_a` (lib test) due to 12 previous errors
warning: build failed, waiting for other jobs to finish...
error: could not compile `_a` (lib) due to 12 previous errors

Version:

rustc 1.92.0-nightly (4a54b26d3 2025-10-07)
binary: rustc
commit-hash: 4a54b26d30dac43778afb0e503524b763fce0eee
commit-date: 2025-10-07
host: x86_64-unknown-linux-gnu
release: 1.92.0-nightly
LLVM version: 21.1.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-suggestion-causes-errorIssue: The suggestions provided by this Lint cause an ICE/error when applied

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions