Skip to content

Commit

Permalink
Fix ICE when a borrow is used after drop
Browse files Browse the repository at this point in the history
ht @nickfrostatx for the first initial patch
  • Loading branch information
spastorino committed Apr 9, 2018
1 parent 4b9b70c commit 2e87dbb
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
34 changes: 23 additions & 11 deletions src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
Expand Up @@ -59,17 +59,29 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {

Cause::DropVar(local, location) => {
match find_drop_use(mir, regioncx, borrow, location, local) {
Some(p) => {
let local_name = mir.local_decls[local].name.unwrap();

err.span_label(
mir.source_info(p).span,
format!(
"borrow later used here, when `{}` is dropped",
local_name
),
);
}
Some(p) => match &mir.local_decls[local].name {
Some(local_name) => {
err.span_label(
mir.source_info(p).span,
format!(
"borrow later used here, when `{}` is dropped",
local_name
),
);
}
None => {
err.span_label(
mir.local_decls[local].source_info.span,
"borrow may end up in a temporary, created here",
);

err.span_label(
mir.source_info(p).span,
"temporary later dropped here, \
potentially using the reference",
);
}
},

None => {
span_bug!(
Expand Down
26 changes: 26 additions & 0 deletions src/test/ui/issue-47646.rs
@@ -0,0 +1,26 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(warnings)]
#![feature(nll)]

use std::collections::BinaryHeap;

fn main() {
let mut heap: BinaryHeap<i32> = BinaryHeap::new();
let borrow = heap.peek_mut();

match (borrow, ()) {
(Some(_), ()) => {
println!("{:?}", heap); //~ ERROR cannot borrow `heap` as immutable
}
_ => {}
};
}
18 changes: 18 additions & 0 deletions src/test/ui/issue-47646.stderr
@@ -0,0 +1,18 @@
error[E0502]: cannot borrow `heap` as immutable because it is also borrowed as mutable
--> $DIR/issue-47646.rs:22:30
|
LL | let borrow = heap.peek_mut();
| ---- mutable borrow occurs here
LL |
LL | match (borrow, ()) {
| ------------ borrow may end up in a temporary, created here
LL | (Some(_), ()) => {
LL | println!("{:?}", heap); //~ ERROR cannot borrow `heap` as immutable
| ^^^^ immutable borrow occurs here
...
LL | };
| - temporary later dropped here, potentially using the reference

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.

0 comments on commit 2e87dbb

Please sign in to comment.