Skip to content

Two cases of confusing borrow over-extension #55085

Closed
@yuriks

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.

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