As explained at your link, the example program that is not type-safe is based on a mistake of the 1983 Ada standard regarding the use of "aliased", which has been removed by a later Technical Corrigendum, where the program demonstrated at your link is explicitly classified as erroneous, so any compliant Ada compiler should fail to compile it.
As also explained at your link, the same type-safety breaking technique works in unsafe Rust. Both "unchecked" Ada and "unsafe" Rust do not provide type safety, while the safe subsets of the languages provide it.
_3 is magic, _4 is uncopied, and 5 is b. move here is like ptr::read, which means that uncopied points to a copy of magic, not aliasing magic, and is dangling. Because this is UB, it gets optimized straight into the panic.
After I figured that out, miri started working, I must have made a mistake earlier. It will tell us the same thing:
test test ... error: Undefined Behavior: memory access failed: alloc113986 has been freed, so this pointer is dangling
--> src/lib.rs:24:13
|
24 | assert!((*uncopied).value != std::ptr::null());
| ^^^^^^^^^^^^^^^^^ memory access failed: alloc113986 has been freed, so this pointer is dangling
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
help: alloc113986 was allocated here:
--> src/lib.rs:18:16
|
18 | Magic::B(b) => &b,
| ^
help: alloc113986 was deallocated here:
--> src/lib.rs:18:23
|
18 | Magic::B(b) => &b,
| ^
= note: BACKTRACE (of the first span) on thread `test`:
= note: inside `magic::<&str, &u8>` at src/lib.rs:24:13: 24:30
note: inside `test`
--> src/lib.rs:36:5
|
36 | magic::<&str, &u8>("magic string");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
--> src/lib.rs:35:10
|
34 | #[test]
| ------- in this procedural macro expansion
35 | fn test() {
| ^
= note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
This code started failing in Rust 1.12, when MIR happened, so that's exactly my guess as to what fixed it.
As also explained at your link, the same type-safety breaking technique works in unsafe Rust. Both "unchecked" Ada and "unsafe" Rust do not provide type safety, while the safe subsets of the languages provide it.