]> git.lizzy.rs Git - rust.git/commitdiff
Fix ICE when a borrow is used after drop
authorSantiago Pastorino <spastorino@gmail.com>
Mon, 9 Apr 2018 15:42:17 +0000 (12:42 -0300)
committerSantiago Pastorino <spastorino@gmail.com>
Mon, 9 Apr 2018 20:35:28 +0000 (17:35 -0300)
ht @nickfrostatx for the first initial patch

src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
src/test/ui/issue-47646.rs [new file with mode: 0644]
src/test/ui/issue-47646.stderr [new file with mode: 0644]

index 4031bd5369da637b537017cdc730601e5a62e05f..b6efe884fc33c642ee21b9365306564da8de2798 100644 (file)
@@ -59,17 +59,29 @@ pub(in borrow_check) fn explain_why_borrow_contains_point(
 
                     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 (file)
index 0000000..7a6d6dd
--- /dev/null
@@ -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 (file)
index 0000000..b128914
--- /dev/null
@@ -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`.