Skip to content

cast() can not cast to pointer type of unknown size #120070

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

Closed
fredrik-hammar opened this issue Jan 17, 2024 · 3 comments
Closed

cast() can not cast to pointer type of unknown size #120070

fredrik-hammar opened this issue Jan 17, 2024 · 3 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.

Comments

@fredrik-hammar
Copy link

When using cast() to cast to pointer to type of unknown size the compiler fails due to the target type being constrained as Sized, but casting with as works fine.

/// A newtype with alignment of at least `A` bytes
#[repr(C)]
pub struct Aligned<A, T>
where
    T: ?Sized,
{
    _alignment: [A; 0],
    value: T,
}

fn foo(ptr: *mut [u8]) -> *mut Aligned<u16, [u8]> {
    ptr as *mut Aligned<u16, [u8]>  // Compiles
}

fn bar(ptr: *mut [u8]) -> *mut Aligned<u16, [u8]> {
    ptr.cast() // Fails with: the size for values of type `[u8]` cannot be known at compilation time
}

I suggest adding ?Sized to U in cast() signatures.

core::ptr::const_ptr
pub const fn cast<U>(self) -> *const U;
core::ptr::mut_ptr
pub const fn cast<U>(self) -> *mut U

Meta

Tested with 1.75., 1.76.0-beta.5, 1.77.0-nightly in Rust Playground

@fredrik-hammar fredrik-hammar added the C-bug Category: This is a bug. label Jan 17, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jan 17, 2024
@clubby789
Copy link
Contributor

clubby789 commented Jan 17, 2024

This isn't currently possible (#60602 (comment)). With this change applied, building the standard library gives you this error

error[E0606]: casting `*const T` as `*const U` is invalid
  --> library/core/src/ptr/const_ptr.rs:61:9
   |
61 |         self as _
   |         ^^^^^^^^^
   |
   = note: vtable kinds may not match

Casting works fine with as when not generic as the compiler knows how to construct the fat pointer

@clubby789 clubby789 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 Jan 17, 2024
@lukas-code
Copy link
Member

lukas-code commented Jan 17, 2024

This isn't currently possible

It's not possible with as in a generic context, but it is possible with transmute_unchecked which AFAIK is equal to as for pointer-to-pointer casts.

playground link

Edit: This hack only supports thin->thin and fat->fat casts, but not fat->thin casts. Since .cast() can already do fat->thin casts, we can't replace it like this.

@fredrik-hammar
Copy link
Author

Thanks for the explanations! I see this is more complicated than I realized, but at least I learned something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.
Projects
None yet
Development

No branches or pull requests

4 participants