Skip to content

"Cannot root managed value long enough" with recursion and returning borrowed pointers #4325

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

Closed
ttaubert opened this issue Jan 1, 2013 · 4 comments
Labels
A-lifetimes Area: Lifetimes / regions

Comments

@ttaubert
Copy link
Contributor

ttaubert commented Jan 1, 2013

I wonder if this shouldn't work?

struct Node<T> {
  val: T,
  next: Option<@Node<T>>
}

impl<T> Node<T> {
  pure fn get(&self) -> &self/T {
    match self.next {
      Some(next) => next.get(),
      None => &self.val
    }
  }
}

fn main() {}

The failure is:

19:20: 19:24 error: illegal borrow: cannot root managed value long enough
19       Some(next) => next.get(),
                       ^~~~
17:32: 22:3 note: managed value would have to be rooted for the lifetime &self as defined on the block at 17:32...
17   pure fn get(&self) -> &self/T {
18     match self.next {
19       Some(next) => next.get(),
20       None => &self.val
21     }
22   }
17:32: 22:3 note: ...but can only be rooted for the block at 17:32
17   pure fn get(&self) -> &self/T {
18     match self.next {
19       Some(next) => next.get(),
20       None => &self.val
21     }
22   }

https://github.com/mozilla/rust/blob/incoming/src/librustc/middle/borrowck/preserve.rs#L333

attempt_root() expects a ty::re_scope but self.scope_region is a ty::re_free. self.scope_region's id is the same as self.root_ub (root_region's id).

CC'ing @nikomatsakis because he's the borrowed pointer specialist.

@catamorphism
Copy link
Contributor

I think this never should have worked, since the Node struct is declared to contain a managed box. The error message isn't the clearest, but is saying the compiler doesn't know that the lifetime of the contents of a node's next field is the same as the lifetime of the contents of the node itself.

I'll check in a modified run-pass test case (where the next field contains a pointer with a lifetime annotation).

catamorphism added a commit to catamorphism/rust that referenced this issue Mar 29, 2013
@catamorphism
Copy link
Contributor

Pending #5620

@brson
Copy link
Contributor

brson commented Mar 31, 2013

Doesn't look critical for 0.6

@graydon
Copy link
Contributor

graydon commented May 15, 2013

Yeah, this is working-as-intended. The associated test (which landed) shows how this needs to be written if you want to use borrowed pointers here. Closing.

@graydon graydon closed this as completed May 15, 2013
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

4 participants