-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ability to transmute with generic consts
Previously if the expression contained generic consts and did not have a directly equivalent type, transmuting the type in this way was forbidden, despite the two sizes being identical. Instead, we should be able to lazily tell if the two consts are identical, and if so allow them to be transmuted.
- Loading branch information
1 parent
82bfda8
commit 648a35e
Showing
5 changed files
with
268 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#![feature(generic_const_exprs)] | ||
#![allow(incomplete_features)] | ||
|
||
fn foo<const W: usize, const H: usize>(v: [[u32;H+1]; W]) -> [[u32; W+1]; H] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
//~^ ERROR cannot transmute | ||
} | ||
} | ||
|
||
fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] { | ||
//~^ ERROR mismatched types | ||
//~| ERROR mismatched types | ||
unsafe { | ||
std::mem::transmute(v) | ||
//~^ ERROR cannot transmute between types | ||
} | ||
} | ||
|
||
fn baz<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [u32; W * H * H] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
//~^ ERROR cannot transmute | ||
} | ||
} | ||
|
||
fn overflow(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 777777777]; 8888888] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
//~^ ERROR cannot transmute | ||
} | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types | ||
--> $DIR/transmute-fail.rs:6:5 | ||
| | ||
LL | std::mem::transmute(v) | ||
| ^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: source type: `[[u32; H+1]; W]` (generic size) | ||
= note: target type: `[[u32; W+1]; H]` (generic size) | ||
|
||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types | ||
--> $DIR/transmute-fail.rs:15:5 | ||
| | ||
LL | std::mem::transmute(v) | ||
| ^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: source type: `[[u32; H]; W]` (this type does not have a fixed size) | ||
= note: target type: `[[u32; W]; H]` (size can vary because of [u32; W]) | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/transmute-fail.rs:11:53 | ||
| | ||
LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] { | ||
| ^ expected `usize`, found `bool` | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/transmute-fail.rs:11:67 | ||
| | ||
LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] { | ||
| ^ expected `usize`, found `bool` | ||
|
||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types | ||
--> $DIR/transmute-fail.rs:22:5 | ||
| | ||
LL | std::mem::transmute(v) | ||
| ^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: source type: `[[u32; H]; W]` (generic size) | ||
= note: target type: `[u32; W * H * H]` (generic size) | ||
|
||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types | ||
--> $DIR/transmute-fail.rs:29:5 | ||
| | ||
LL | std::mem::transmute(v) | ||
| ^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type `[[[u32; 8888888]; 9999999]; 777777777]` are too big for the current architecture) | ||
= note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type `[[[u32; 9999999]; 777777777]; 8888888]` are too big for the current architecture) | ||
|
||
error: aborting due to 6 previous errors | ||
|
||
Some errors have detailed explanations: E0308, E0512. | ||
For more information about an error, try `rustc --explain E0308`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// run-pass | ||
#![feature(generic_const_exprs)] | ||
#![allow(incomplete_features)] | ||
|
||
fn transpose<const W: usize, const H: usize>(v: [[u32;H]; W]) -> [[u32; W]; H] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
} | ||
} | ||
|
||
fn ident<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [[u32; H]; W] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
} | ||
} | ||
|
||
fn flatten<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [u32; W * H] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
} | ||
} | ||
|
||
fn coagulate<const W: usize, const H: usize>(v: [u32; H*W]) -> [[u32; W];H] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
} | ||
} | ||
|
||
fn flatten_3d<const W: usize, const H: usize, const D: usize>( | ||
v: [[[u32; D]; H]; W] | ||
) -> [u32; D * W * H] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
} | ||
} | ||
|
||
fn flatten_somewhat<const W: usize, const H: usize, const D: usize>( | ||
v: [[[u32; D]; H]; W] | ||
) -> [[u32; D * W]; H] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
} | ||
} | ||
|
||
fn known_size<const L: usize>(v: [u16; L]) -> [u8; L * 2] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
} | ||
} | ||
|
||
fn condense_bytes<const L: usize>(v: [u8; L * 2]) -> [u16; L] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
} | ||
} | ||
|
||
fn singleton_each<const L: usize>(v: [u8; L]) -> [[u8;1]; L] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
} | ||
} | ||
|
||
fn transpose_with_const<const W: usize, const H: usize>( | ||
v: [[u32; 2 * H]; W + W] | ||
) -> [[u32; W + W]; 2 * H] { | ||
unsafe { | ||
std::mem::transmute(v) | ||
} | ||
} | ||
|
||
fn main() { | ||
let _ = transpose([[0; 8]; 16]); | ||
let _ = transpose_with_const::<8,4>([[0; 8]; 16]); | ||
let _ = ident([[0; 8]; 16]); | ||
let _ = flatten([[0; 13]; 5]); | ||
let _: [[_; 5]; 13] = coagulate([0; 65]); | ||
let _ = flatten_3d([[[0; 3]; 13]; 5]); | ||
let _ = flatten_somewhat([[[0; 3]; 13]; 5]); | ||
let _ = known_size([16; 13]); | ||
let _: [u16; 5] = condense_bytes([16u8; 10]); | ||
let _ = singleton_each([16; 10]); | ||
} |