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

Odd loaning errors when similar code works #4666

Closed
alexcrichton opened this issue Jan 29, 2013 · 7 comments
Closed

Odd loaning errors when similar code works #4666

alexcrichton opened this issue Jan 29, 2013 · 7 comments
Assignees
Labels
A-lifetimes Area: Lifetimes / regions
Milestone

Comments

@alexcrichton
Copy link
Member

For this code

use core::hashmap::linear::LinearMap;

fn fun1() {
  let mut map = LinearMap::new();
  map.insert(1, 2);
  // ok
  let size;
  size = *map.get(&1);
  map.insert(2, size);
}

fn fun2() {
  let mut map = LinearMap::new();
  map.insert(1, 2);
  let size = *map.get(&1); // note: prior loan of immutable granted here
  map.insert(2, size); // error: loan of mutable local variable as mutable conflicts with prior loan
}

fn fun3() {
  let mut map = LinearMap::new();
  map.insert(1, 2);
  // more bad, same as fun2
  map.insert(2, *map.get(&1));
}

fn main() {}

fun1 passes through the compiler, but both fun2 and fun3 generate an error (listed in fun2) and I'm not sure why fun2 is invalid while fun1 is valid.

@nikomatsakis
Copy link
Contributor

This is probably caused by #3850

@ghost ghost assigned nikomatsakis Feb 1, 2013
@erickt
Copy link
Contributor

erickt commented Feb 2, 2013

I may or may be running into this same problem with this code:

struct A { a: int }

struct B { a: &A }

impl B {
    fn next1(&mut self) { }
    fn next2(self) -> B/&self { let B { a: a } = self; B { a: a } }
}

fn main() {
    let a = A { a: 0 };
    let mut b = B { a: &a };
    //b.next1(); b.next1();
    //for uint::range(0, 1) |_| { b.next1(); }
    //b = b.next2(); b = b.next2();
}

This errors with:

test.rs:13:15: 13:16 error: loan of mutable local variable as mutable conflicts with prior loan
test.rs:13     b.next1(); b.next1();
                          ^
test.rs:13:4: 13:5 note: prior loan as mutable granted here
test.rs:13     b.next1(); b.next1();
               ^
error: aborting due to previous error

However, if instead I use the commented out closure, it compiles fine. Likewise, if I move out of self, it also compiles fine.

@Dretch
Copy link
Contributor

Dretch commented Mar 24, 2013

I think I may be having the same issue.

I think this code should compile, but it doesn't:

struct MyStruct {}

impl MyStruct {

    fn takes_mut_self(&mut self, _x:int) {}

    fn takes_self(&self) -> int { 42 }

    fn also_takes_mut_self(&mut self) {
        self.takes_mut_self(self.takes_self());
    }

}

fn main() {}

The error rustc produces is:

mut-self-issues.rs:12:28: 12:32 error: loan of dereference of mutable & pointer as immutable conflicts with prior loan
mut-self-issues.rs:12         self.takes_mut_self(self.takes_self());
                                                  ^~~~
mut-self-issues.rs:12:8: 12:12 note: prior loan as mutable granted here
mut-self-issues.rs:12         self.takes_mut_self(self.takes_self());
                              ^~~~
error: aborting due to previous error

@jdm
Copy link
Contributor

jdm commented Mar 24, 2013

That's the general flow-control problem that currently exists. It's going away with the borrowchecker changes that haven't landed yet; until then, you can work around it by assigning the result of the takes_self calls to temporaries and passing those instead.

@nikomatsakis
Copy link
Contributor

Part of #5074 (fix coming soon)

This was referenced May 6, 2013
bors added a commit that referenced this issue May 7, 2013
…omatsakis

This rather sprawling branch refactors the borrow checker and much of the region code, addressing a number of outstanding issues. I will close them manually after validating that there are test cases for each one, but here is a (probably partial) list:

  - #4903: Flow sensitivity
  - #3387: Moves in overloaded operators
  - #3850: Region granularity
  - #4666: Odd loaning errors
  - #6021: borrow check errors with hashmaps
  - #5910: @mut broken

cc #5047

(take 5)
@nikomatsakis
Copy link
Contributor

This bug is mostly fixed. Some of the examples (Such as fun3 in the original code) still do not work, due to #6268. I will post a PR soon closing the issue and adding a test.

bors added a commit that referenced this issue May 8, 2013
existing tests. The bug itself was fixed as part of recent borrowck
reform.

Fixes #4666.
@alexcrichton
Copy link
Member Author

Awesome, thanks @nikomatsakis!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: Lifetimes / regions
Projects
None yet
Development

No branches or pull requests

5 participants