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

Const generics and transmute: cannot transmute between types of different sizes #62875

Closed
bgourlie opened this issue Jul 22, 2019 · 3 comments
Closed
Labels
A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. F-const_generics `#![feature(const_generics)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@bgourlie
Copy link

The following code should compile, but it doesn't:

#![feature(const_generics)]

use std::{
    mem::{self, MaybeUninit},
    ptr,
};

fn main() {
}

pub struct Foo<const SIZE: usize> {
    messages: [Option<String>; SIZE],
}

impl<const SIZE: usize> Default for Foo<{SIZE}> {
    fn default() -> Self {
        let arr = {
            let mut arr: [MaybeUninit<Option<String>>; {SIZE}] =
                unsafe { MaybeUninit::uninit().assume_init() };

            for elem in &mut arr[..] {
                unsafe { ptr::write(elem.as_mut_ptr(), None) }
            }

            unsafe { mem::transmute::<_, [Option<String>; {SIZE}]>(arr) }
        };
        Foo {
            messages: arr,
        }
    }
}

The error produced is

error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
  --> src\main.rs:25:22
   |
25 |             unsafe { mem::transmute::<_, [Option<String>; {SIZE}]>(arr) }
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: source type: `[std::mem::MaybeUninit<std::option::Option<std::string::String>>; _]` (this type does not have a fixed size)
   = note: target type: `[std::option::Option<std::string::String>; _]` (this type does not have a fixed size)
@jonas-schievink jonas-schievink added A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 22, 2019
@DutchGhost
Copy link
Contributor

Duplicate of #61956 .

To fix this for now, either use transmute_copy, or take a raw pointer to the MaybeUninit array, cast the ptr to the type you want, and ptr::read it, while making sure you mem::forget the MaybeUninit array!

@Centril Centril added requires-nightly This issue requires a nightly compiler in some way. F-const_generics `#![feature(const_generics)]` labels Aug 6, 2019
@varkor
Copy link
Member

varkor commented Apr 8, 2020

Closing as duplicate of #61956.

@varkor varkor closed this as completed Apr 8, 2020
@hniksic
Copy link
Contributor

hniksic commented May 10, 2021

@DutchGhost Why is it necessary to mem::forget() the array of MaybeUninit? AFAIK MaybeUninit doesn't implement Drop so mem::forget-ing it should be no-op.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. F-const_generics `#![feature(const_generics)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants