about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-04-13 16:06:14 +0000
committerbors <bors@rust-lang.org>2018-04-13 16:06:14 +0000
commit9c2bfcbea2d7fff10e608b495d76f24f441999b9 (patch)
tree7b2a03898bda8df0dd02494c51309779b965cd6b
parentb8f60f3fc47f0f94666721b9fdfebf95ab5fc444 (diff)
parent2c79f6458ea047c9aa2a768771ce210acf9394eb (diff)
downloadrust-9c2bfcbea2d7fff10e608b495d76f24f441999b9.tar.gz
rust-9c2bfcbea2d7fff10e608b495d76f24f441999b9.zip
Auto merge of #49808 - spastorino:dump_cause_ice, r=nikomatsakis
[NLL] Fix ICE when a borrow wrapped in a temporary is used after dropped

Fixes #47646

r? @nikomatsakis
-rw-r--r--src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs38
-rw-r--r--src/test/ui/issue-47646.rs26
-rw-r--r--src/test/ui/issue-47646.stderr18
3 files changed, 69 insertions, 13 deletions
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index 4031bd5369d..187bfc2bf90 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use borrow_check::{Context, MirBorrowckCtxt};
 use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
+use borrow_check::{Context, MirBorrowckCtxt};
 use dataflow::BorrowData;
-use rustc::mir::{Local, Location, Mir};
 use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
+use rustc::mir::{Local, Location, Mir};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::DiagnosticBuilder;
 use util::liveness::{self, DefUse, LivenessMode};
@@ -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!(
diff --git a/src/test/ui/issue-47646.rs b/src/test/ui/issue-47646.rs
new file mode 100644
index 00000000000..7a6d6dd3fe1
--- /dev/null
+++ b/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
+        }
+        _ => {}
+    };
+}
diff --git a/src/test/ui/issue-47646.stderr b/src/test/ui/issue-47646.stderr
new file mode 100644
index 00000000000..b1289146e0e
--- /dev/null
+++ b/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`.