Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misleading synopsis of self-references in readme #2

Open
dtolnay opened this issue Apr 13, 2021 · 0 comments
Open

Misleading synopsis of self-references in readme #2

dtolnay opened this issue Apr 13, 2021 · 0 comments

Comments

@dtolnay
Copy link

dtolnay commented Apr 13, 2021

The following excerpts from https://github.com/petrosagg/escher/tree/016f4c10491741690411d7b5a080218d8399b693#the-problem-with-self-references:

The main problem with self-referencial structs is that if such a struct was somehow constructed the compiler would then have to statically prove that it would not move again. [...]

[...] imagine we define a self-referencial struct that holds a Vec and a pointer to it at the same time:

struct Foo {
    s: Vec<u8>,
    p: &Vec<u8>,
}

Then, let's assume we had a way of getting an instance of this struct. [...]

This wording heavily implies that you can't already create or manipulate such a struct in safe Rust, which isn't accurate. In particular:

  • "if such a struct was somehow constructed" -- in fact it's totally possible to construct such a struct
  • "let's assume we had a way of getting an instance of this struct" -- we do have this
  • "the compiler would then have to statically prove that it would not move again" -- yes, the compiler does this
  • "We could then write the following code that creates a dangling pointer in safe rust!" -- this statement does not follow, specifically because the compiler statically proves that you don't move the struct

Example code:

#[derive(Debug)]
struct Foo<'a> {
    s: Vec<u8>,
    p: &'a Vec<u8>,
}

fn main() {
    let mut foo = Foo {
        s: vec![1, 1, 1, 1],
        p: &Vec::new(), // tmp
    };
    foo.p = &foo.s;
    println!("{:?}", foo);
}
Foo { s: [1, 1, 1, 1], p: [1, 1, 1, 1] }

This constructs the self-referential struct described in the readme, and runs its Debug impl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant