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

Dereference of pointer does not end its life #6159

Closed
kalenedrael opened this issue May 1, 2013 · 7 comments
Closed

Dereference of pointer does not end its life #6159

kalenedrael opened this issue May 1, 2013 · 7 comments

Comments

@kalenedrael
Copy link

Compiling this:

struct Foo {
        x: int,
}

impl Foo {
        pub fn get_x(&self) -> &'self int { &self.x }
}

struct Bar {
        x: Foo,
}

impl Bar {
        pub fn do_shit(&mut self) -> () { }
        pub fn break_shit(&mut self) -> () {
                let x = *self.x.get_x();
                core::util::ignore(x);
                self.do_shit()
        }
}

fn main() {
        let mut x = Bar { x: Foo { x: 1 } };
        x.break_shit();
}

yields the error

shit.rs:20:2: 20:6 error: loan of dereference of mutable & pointer as mutable conflicts with prior loan
shit.rs:20              self.do_shit()
                        ^~~~
shit.rs:16:10: 16:14 note: prior loan as immutable granted here
shit.rs:16              let y = self.x.get_x();

The self pointer is considered loaned out from 'let x = *self.x.get_x()', even though it... isn't.

@thestinger
Copy link
Contributor

I don't think this is a bug. A pointer is still usable after being dereferenced, you're just copying out of the dereferenced location. You could dereference it again and copy out again.

@kalenedrael
Copy link
Author

In this case though, the pointer isn't used again. Why would it be live?

EDIT: Initially the failing case was 'let x = *self.x.get_x()', without the variable y that could be considered live until the end of the function. In that case it definitely should not be considered live.

EDIT #2: Using 'let x; { x = *self.x.get_x() }' does fix the issue.

@pnkfelix
Copy link
Member

pnkfelix commented May 1, 2013

In response to:

In this case though, the pointer isn't used again. Why would it be live?

because the scope of y is based on the block structure of the program, and not on which expressions happen to reference it?

@pnkfelix
Copy link
Member

pnkfelix commented May 1, 2013

Ah, okay, the variant where you do not pull out y into its own let-bound variable is more interesting. You should revise the report to say that instead, because someone reading the bug description as it stands is likely to react the way thestinger and I did..

@pnkfelix
Copy link
Member

pnkfelix commented May 1, 2013

In response to this:

EDIT #2: Using 'let x; { x = *self.x.get_x() }' does fix the issue.

An even simpler variant on that fix is:

                let x = { *self.x.get_x() };

which as far as I can tell, also fixes your issue.

@nikomatsakis is this handling of the results of sub-expressions by design, or is it a deficiency in the current borrow-check and/or lifetime semantics?

@kalenedrael
Copy link
Author

I've edited the bug description as suggested by pnkfelix.

@nikomatsakis
Copy link
Contributor

This works fine on my branch. I'd say it's a dup of #3387, but I don't want to spend a lot of time digging into why the old borrow checker reported an error. Closing as dup of #3387.

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

4 participants