Repository: rust
Issue: `std::mem::transmute` doesn't compile even though both types are guaranteed to have the same size.
Labels: T-compiler,C-bug,A-const-generics,T-types

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

Let me preface that I'm actively looking into other options than transmute, but I expected this to work, because it could basically be an no-op. Also the doc on `transmute` says: "Compilation will fail if this is not guaranteed", and these types are essentially the same.

I'm working on a `Builder` derive and I'm working on the implementation of the setters. I was trying something new.

I tried this code:

```rust
impl<const SIZE: usize> FooBuilder<SIZE, false> {
    pub fn bar(mut self, bar: [usize; SIZE]) -> FooBuilder<SIZE, true> {
        self.data.bar = Some(bar);
        unsafe { std::mem::transmute(self) }
    }
}
```

It's part of a bigger piece of code:

```rust
// simplified macro expansion:
pub struct Foo<const SIZE: usize> {
    bar: [usize; SIZE],
}

pub struct FooData<const SIZE: usize> {
    pub bar: Option<[usize; SIZE]>,
}

impl<const SIZE: usize> Builder for Foo<SIZE> {
    type Builder = FooBuilder<SIZE, false>;
    fn builder() -> FooBuilder<SIZE, false> {
        self::Builder::new()
    }
}

pub struct FooBuilder<const SIZE: usize, const __BUILDER_CONST_0: bool> {
    data: FooData<SIZE>,
}

impl<const SIZE: usize> FooBuilder<SIZE, false> {
    pub fn new() -> FooBuilder<SIZE, false> {
        data: FooData<SIZE> {
            bar: None,
        }
    }
}

impl<const SIZE: usize> FooBuilder<SIZE, false> {
    pub fn bar(mut self, bar: [usize; SIZE]) -> FooBuilder<SIZE, true> {
        self.data.bar = Some(bar);
        unsafe { std::mem::transmute(self) } 
              // ^^^^^^^^^^^^^^^^^^^ Here I call the transmute
    }
}

impl<const SIZE: usize> FooBuilder<SIZE, true> {
    pub fn build(self) -> Foo<SIZE> {
        Foo<SIZE> {
            bar: self.data.bar.unwrap()
        }
    }
}
```

I expected to see this happen: Because both the input and the output are guaranteed to be the same size, I expected it to compile.

Instead, this happened: It didn't compile, and I got this error:

```
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
   --> const_typed_builder_test/src/lib.rs:693:32
    |
693 |     #[derive(Debug, PartialEq, Builder)]
    |                                ^^^^^^^
    |
    = note: source type: `test::const_generic::FooBuilder<SIZE, false>` (size can vary because of [usize; SIZE])
    = note: target type: `test::const_generic::FooBuilder<SIZE, true>` (size can vary because of [usize; SIZE])
    = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info)
```

### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
rustc 1.74.0-beta.1 (b5c050feb 2023-10-03)
binary: rustc
commit-hash: b5c050febf10c9bcc0459d41fe2a1e190ad30b8d
commit-date: 2023-10-03
host: x86_64-apple-darwin
release: 1.74.0-beta.1
LLVM version: 17.0.2
```
I also ran it on the latest nigthly and stable, with the same response
```
rustc 1.75.0-nightly (2e5a9dd6c 2023-10-02)
binary: rustc
commit-hash: 2e5a9dd6c9eaa42f0684b4b760bd68fc27cbe51b
commit-date: 2023-10-02
host: x86_64-apple-darwin
release: 1.75.0-nightly
LLVM version: 17.0.2
```
```
rustc 1.72.1 (d5c2e9c34 2023-09-13)
binary: rustc
commit-hash: d5c2e9c342b358556da91d61ed4133f6f50fc0c3
commit-date: 2023-09-13
host: x86_64-apple-darwin
release: 1.72.1
LLVM version: 16.0.5
```
<!--
Include a backtrace in the code block by setting `RUST_BACKTRACE=1` in your
environment. E.g. `RUST_BACKTRACE=1 cargo build`.
-->


<details><summary>Backtrace</summary>
<p>
I'm not sure what I'm doing wrong but if I run `cargo test --workspace -- -Z macro-backtrace` I only get this:

```
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
   --> const_typed_builder_test/src/lib.rs:693:32
    |
693 |     #[derive(Debug, PartialEq, Builder)]
    |                                ^^^^^^^
    |
    = note: source type: `test::const_generic::FooBuilder<SIZE, false>` (size can vary because of [usize; SIZE])
    = note: target type: `test::const_generic::FooBuilder<SIZE, true>` (size can vary because of [usize; SIZE])
    = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info)
```

</p>
</details>