From 2e87dbbde14b5939a47b3507660a2bab25ef93a9 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 9 Apr 2018 12:42:17 -0300 Subject: [PATCH 1/2] Fix ICE when a borrow is used after drop ht @nickfrostatx for the first initial patch --- .../borrow_check/nll/explain_borrow/mod.rs | 32 +++++++++++++------ src/test/ui/issue-47646.rs | 26 +++++++++++++++ src/test/ui/issue-47646.stderr | 18 +++++++++++ 3 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/issue-47646.rs create mode 100644 src/test/ui/issue-47646.stderr 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..b6efe884fc3 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -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(); + 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, - format!( - "borrow later used here, when `{}` is dropped", - local_name - ), - ); - } + 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 or the MIT license +// , 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 = 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`. From 2c79f6458ea047c9aa2a768771ce210acf9394eb Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 9 Apr 2018 16:34:05 -0300 Subject: [PATCH 2/2] rustfmt explain_borrow/mod --- src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 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 b6efe884fc3..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};