Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't cast a pointer of a trait object newtype to a pointer of that trait object. #128625

Open
theemathas opened this issue Aug 4, 2024 · 2 comments · May be fixed by #136127
Open

Can't cast a pointer of a trait object newtype to a pointer of that trait object. #128625

theemathas opened this issue Aug 4, 2024 · 2 comments · May be fixed by #136127
Labels
A-raw-pointers Area: raw pointers, MaybeUninit, NonNull A-trait-objects Area: trait objects, vtable layout C-discussion Category: Discussion or questions that doesn't represent real issues. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@theemathas
Copy link
Contributor

theemathas commented Aug 4, 2024

I tried this code:

trait Trait {}

struct Wrap(dyn Trait);

fn cast(x: *mut Wrap) {
    x as *mut dyn Trait;
}

I expected the code to compile. Instead, I got the following error, where it appears that the compiler is trying to do an unsize coercion and failing:

   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `Wrap: Trait` is not satisfied
 --> src/lib.rs:6:5
  |
6 |     x as *mut dyn Trait;
  |     ^ the trait `Trait` is not implemented for `Wrap`
  |
help: this trait has no implementations, consider adding one
 --> src/lib.rs:1:1
  |
1 | trait Trait {}
  | ^^^^^^^^^^^
  = note: required for the cast from `*mut Wrap` to `*mut dyn Trait`

error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
 --> src/lib.rs:6:5
  |
6 |     x as *mut dyn Trait;
  |     ^ doesn't have a size known at compile-time
  |
  = help: within `Wrap`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`, which is required by `Wrap: Sized`
note: required because it appears within the type `Wrap`
 --> src/lib.rs:3:8
  |
3 | struct Wrap(dyn Trait);
  |        ^^^^
  = note: required for the cast from `*mut Wrap` to `*mut dyn Trait`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (lib) due to 2 previous errors

Of note, the following code compiles fine:

trait Trait {}

struct Wrap(dyn Trait);

fn cast(x: *mut Wrap) {
    x as *mut (dyn Trait,);
}

Probably related to #128621

Meta

This issue reproduces on the playground on stable (1.80.0), and nightly (2024-08-02 fd8d6fb).

@theemathas theemathas added the C-bug Category: This is a bug. label Aug 4, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Aug 4, 2024
@saethlin saethlin added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Aug 4, 2024
@theemathas
Copy link
Contributor Author

Another variant that compiles fine:

trait Trait {}

struct Wrap1(dyn Trait);
struct Wrap2(dyn Trait);

fn cast(x: *mut Wrap1) -> *mut Wrap2 {
    x as *mut Wrap2
}

@saethlin saethlin added the T-types Relevant to the types team, which will review and decide on the PR/issue. label Aug 4, 2024
@fmease fmease added A-raw-pointers Area: raw pointers, MaybeUninit, NonNull A-trait-objects Area: trait objects, vtable layout labels Dec 21, 2024
@theemathas
Copy link
Contributor Author

Oddly, doing the cast a roundabout way using a generic makes the code compile:

trait Trait {}

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

fn cast_specific(x: *mut Wrap<dyn Trait>) -> *mut dyn Trait {
    cast_generic::<dyn Trait>(x) // compiles fine
    // x as *mut dyn Trait // doesn't work
}

fn cast_generic<T: ?Sized>(x: *mut Wrap<T>) -> *mut T {
    x as *mut T
}

@theemathas theemathas linked a pull request Jan 28, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-raw-pointers Area: raw pointers, MaybeUninit, NonNull A-trait-objects Area: trait objects, vtable layout C-discussion Category: Discussion or questions that doesn't represent real issues. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants