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

For everyone unaware, this repo is a meme:

https://www.reddit.com/r/rust/comments/1q0kvn1/corroded_upda...

As a follow on to the corroded meme crate:

https://github.com/buyukakyuz/corroded

> What Is This

> The rust compiler thinks it knows better than you. It won't let you have two pointers to the same thing. It treats you like a mass of incompetence that can't be trusted with a pointer.

> We fix that.





It does seem like satire. The very first example is:

    fn main() {
        let a = String::from("hello");
        let b = a;
        println!("{a}");  // Works! Prints: hello
    }
This is not “I have correct code but Rust can’t tell it’s correct.” This is “wow, this code is intentionally outrageously wrong, obviously dereferences a pointer that is invalid, and happens to work anyway.”

> this code is intentionally outrageously wrong

Can you explain why? Why can't both a and b point at the same string object? Does `let b = a;` do something like a destructive move?


The rust way isn't intuitive if you're coming from C, but b = a does indeed transfer the ownership to b and a is now invalid/unusable. You would need to make a mutable reference if you want two variables that point to the same object.

    error[E0382]: borrow of moved value: `a`
     --> main.rs:4:16
      |
    2 |     let a = String::from("hello");
      |         - move occurs because `a` has type `String`, which does not implement the `Copy` trait
    3 |     let b = a;
      |             - value moved here
    4 |     println!("{a}");  // Works! Prints: hello
      |                ^ value borrowed here after move
      |
      = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
    help: consider cloning the value if the performance cost is acceptable
      |
    3 |     let b = a.clone();
      |              ++++++++

> Does `let b = a;` do something like a destructive move?

Yes. Semantically, Rust performs destructive moves by default, and as a result using `a` after `let b = a;` would normally result in a hard error [0].

The way destructive moves are (currently?) actually implemented, however, is as a shallow memcpy of the value in question coupled with compiler checks that the moved-from thing isn't used. As a result, if you disable the compiler check simple uses of the moved-from value immediately after the move could still work since the compiler doesn't take explicit steps to modify the moved-from value immediately after a move.

[0]: https://rust.godbolt.org/z/Wdr6G1GsK


I'm not 100% sure the semantics here are nailed down - but I think there's no guarantee that `a` continues to exist after assignment to `b`. The value in it has been moved out of it after all... The memory which was used for the variable `a` can probably be re-used for something else, e.g. for some inlined variable used by `println!`...

In normal rust `let a = b` where the variable is of a non-Copy type (including String) is "destructive" in the sense that you can no longer use b.

The question about semantics in normal rust turns to "so if I have a raw-pointer to a hanging around and use unsafe code to copy the value out of it what do I get" and I'm not 100% sure... but I think the answer is probably it's a use after free and you get undefined behavior. The rust-- version is basically just this except you don't have to explicitly make that raw pointer to read the old memory.




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

Search: