Skip to content

Commit 2e87dbb

Browse files
committed
Fix ICE when a borrow is used after drop
ht @nickfrostatx for the first initial patch
1 parent 4b9b70c commit 2e87dbb

File tree

3 files changed

+67
-11
lines changed

3 files changed

+67
-11
lines changed

src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs

+23-11
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,29 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
5959

6060
Cause::DropVar(local, location) => {
6161
match find_drop_use(mir, regioncx, borrow, location, local) {
62-
Some(p) => {
63-
let local_name = mir.local_decls[local].name.unwrap();
64-
65-
err.span_label(
66-
mir.source_info(p).span,
67-
format!(
68-
"borrow later used here, when `{}` is dropped",
69-
local_name
70-
),
71-
);
72-
}
62+
Some(p) => match &mir.local_decls[local].name {
63+
Some(local_name) => {
64+
err.span_label(
65+
mir.source_info(p).span,
66+
format!(
67+
"borrow later used here, when `{}` is dropped",
68+
local_name
69+
),
70+
);
71+
}
72+
None => {
73+
err.span_label(
74+
mir.local_decls[local].source_info.span,
75+
"borrow may end up in a temporary, created here",
76+
);
77+
78+
err.span_label(
79+
mir.source_info(p).span,
80+
"temporary later dropped here, \
81+
potentially using the reference",
82+
);
83+
}
84+
},
7385

7486
None => {
7587
span_bug!(

src/test/ui/issue-47646.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(warnings)]
12+
#![feature(nll)]
13+
14+
use std::collections::BinaryHeap;
15+
16+
fn main() {
17+
let mut heap: BinaryHeap<i32> = BinaryHeap::new();
18+
let borrow = heap.peek_mut();
19+
20+
match (borrow, ()) {
21+
(Some(_), ()) => {
22+
println!("{:?}", heap); //~ ERROR cannot borrow `heap` as immutable
23+
}
24+
_ => {}
25+
};
26+
}

src/test/ui/issue-47646.stderr

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0502]: cannot borrow `heap` as immutable because it is also borrowed as mutable
2+
--> $DIR/issue-47646.rs:22:30
3+
|
4+
LL | let borrow = heap.peek_mut();
5+
| ---- mutable borrow occurs here
6+
LL |
7+
LL | match (borrow, ()) {
8+
| ------------ borrow may end up in a temporary, created here
9+
LL | (Some(_), ()) => {
10+
LL | println!("{:?}", heap); //~ ERROR cannot borrow `heap` as immutable
11+
| ^^^^ immutable borrow occurs here
12+
...
13+
LL | };
14+
| - temporary later dropped here, potentially using the reference
15+
16+
error: aborting due to previous error
17+
18+
For more information about this error, try `rustc --explain E0502`.

0 commit comments

Comments
 (0)