Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

While that was apparently true in 2015, it doesn't work on today's Rust: https://play.rust-lang.org/?version=stable&mode=debug&editio...

I'm not sure what the difference was, given that the representations haven't changed, and I'm doing this without invoking the optimizer.

EDIT: I had issues with Miri so I dug into the MIR myself:

  let uncopied : *const Uncopyable<*const B> =
    match magic {
      Magic::B(b) => &raw const b,

        StorageLive(_4);
        StorageLive(_5);
        _5 = move ((_3 as B).0: Uncopyable<*const B>);
        _4 = &raw const _5;
        StorageDead(_5);
_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.

Funny enough, if we take the critique in the forum as correct, and try with a union: https://play.rust-lang.org/?version=stable&mode=debug&editio...

Rust will:

  1. force us to use ManuallyDrop
  2. the API makes this move explicit, and we get a compile-time error!


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: