Skip to content

Two cases of confusing borrow over-extension #55085

Description

@yuriks

Using rustc nightly 2018-10-13 4699283 (from playpen).

I found two cases where lifetimes appear to be extended where they shouldn't:

use std::cell::RefCell;
use std::collections::binary_heap::PeekMut;
use std::collections::BinaryHeap;

fn main() {
    let heap: RefCell<BinaryHeap<u32>> = RefCell::new(BinaryHeap::new());

    let mut heap_ref = heap.borrow_mut();
    let entry = if let Some(entry) = heap_ref.peek_mut() {
        entry
    } else {
        panic!();
    };
    let task = PeekMut::pop(entry);

    //drop(entry);

    drop(heap_ref);
    println!("We made it {:?}, {:?}", heap.borrow_mut(), task);
}

Playpen link

Which gives this error:

error[E0505]: cannot move out of `heap_ref` because it is borrowed
  --> src/main.rs:18:10
   |
9  |     let entry = if let Some(entry) = heap_ref.peek_mut() {
   |                                      -------- borrow of `heap_ref` occurs here
...
18 |     drop(heap_ref);
   |          ^^^^^^^^ move out of `heap_ref` occurs here

Even though the only thing that could be borrowing heap_ref is entry, which has already been moved into the pop() call.


use std::cell::RefCell;
use std::collections::binary_heap::PeekMut;
use std::collections::BinaryHeap;

fn main() {
    let heap: RefCell<BinaryHeap<u32>> = RefCell::new(BinaryHeap::new());

    let task = {
        let mut heap_ref = heap.borrow_mut();
        if let Some(entry) = heap_ref.peek_mut() {
            PeekMut::pop(entry)
        } else {
            panic!();
        }
    };

    println!("We made it {:?}, {:?}", heap.borrow_mut(), task);
}

Playpen link

Which gives this error:

error[E0597]: `heap_ref` does not live long enough
  --> src/main.rs:10:30
   |
10 |         if let Some(entry) = heap_ref.peek_mut() {
   |                              ^^^^^^^^ borrowed value does not live long enough
...
15 |     };
   |     -- borrowed value needs to live until here
   |     |
   |     `heap_ref` dropped here while still borrowed

Where it's complaining that a borrow needs to live until the same point where it's dropped.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)A-diagnosticsArea: Messages for errors, warnings, and lintsfixed-by-NLLBugs fixed, but only when NLL is enabled.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions