From b523b2d51e74304ecacfca86bf60553c76ec1bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 27 Jul 2019 13:23:34 -0700 Subject: [PATCH 1/2] Avoid ICE when referencing desugared local binding in borrow error --- .../borrow_check/conflict_errors.rs | 25 +++++++++---------- src/test/ui/borrowck/issue-63026.rs | 18 +++++++++++++ src/test/ui/borrowck/issue-63026.stderr | 12 +++++++++ 3 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/borrowck/issue-63026.rs create mode 100644 src/test/ui/borrowck/issue-63026.stderr diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index 5d0e490ebea5a..77e5ac2f86514 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -1140,19 +1140,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { bug!("try_report_cannot_return_reference_to_local: not a local") }; match self.body.local_kind(*local) { - LocalKind::ReturnPointer | LocalKind::Temp => { - ( - "temporary value".to_string(), - "temporary value created here".to_string(), - ) - } - LocalKind::Arg => { - ( - "function parameter".to_string(), - "function parameter borrowed here".to_string(), - ) - }, - LocalKind::Var => bug!("local variable without a name"), + LocalKind::ReturnPointer | LocalKind::Temp => ( + "temporary value".to_string(), + "temporary value created here".to_string(), + ), + LocalKind::Arg => ( + "function parameter".to_string(), + "function parameter borrowed here".to_string(), + ), + LocalKind::Var => ( + "local binding".to_string(), + "local binding introduced here".to_string(), + ), } }; diff --git a/src/test/ui/borrowck/issue-63026.rs b/src/test/ui/borrowck/issue-63026.rs new file mode 100644 index 0000000000000..86240a6914871 --- /dev/null +++ b/src/test/ui/borrowck/issue-63026.rs @@ -0,0 +1,18 @@ +use std::collections::HashMap; +use std::hash::Hash; + +fn group_by(xs: &mut I, f: F) -> HashMap> +where + I: Iterator, + F: Fn(&I::Item) -> T, + T: Eq + Hash, +{ + let mut result = HashMap::new(); + for ref x in xs { + let key = f(x); + result.entry(key).or_insert(Vec::new()).push(x); + } + result //~ ERROR cannot return value referencing local binding +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-63026.stderr b/src/test/ui/borrowck/issue-63026.stderr new file mode 100644 index 0000000000000..2289a03e014ff --- /dev/null +++ b/src/test/ui/borrowck/issue-63026.stderr @@ -0,0 +1,12 @@ +error[E0515]: cannot return value referencing local binding + --> $DIR/issue-63026.rs:15:5 + | +LL | for ref x in xs { + | -- local binding introduced here +... +LL | result + | ^^^^^^ returns a value referencing data owned by the current function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0515`. From 01ba0e3718b9006030d2d5391176745547f7c9a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 27 Jul 2019 19:12:00 -0700 Subject: [PATCH 2/2] review comments --- src/test/ui/borrowck/issue-63026.rs | 18 ---------- .../return-local-binding-from-desugaring.rs | 33 +++++++++++++++++++ ...turn-local-binding-from-desugaring.stderr} | 2 +- 3 files changed, 34 insertions(+), 19 deletions(-) delete mode 100644 src/test/ui/borrowck/issue-63026.rs create mode 100644 src/test/ui/borrowck/return-local-binding-from-desugaring.rs rename src/test/ui/borrowck/{issue-63026.stderr => return-local-binding-from-desugaring.stderr} (86%) diff --git a/src/test/ui/borrowck/issue-63026.rs b/src/test/ui/borrowck/issue-63026.rs deleted file mode 100644 index 86240a6914871..0000000000000 --- a/src/test/ui/borrowck/issue-63026.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::collections::HashMap; -use std::hash::Hash; - -fn group_by(xs: &mut I, f: F) -> HashMap> -where - I: Iterator, - F: Fn(&I::Item) -> T, - T: Eq + Hash, -{ - let mut result = HashMap::new(); - for ref x in xs { - let key = f(x); - result.entry(key).or_insert(Vec::new()).push(x); - } - result //~ ERROR cannot return value referencing local binding -} - -fn main() {} diff --git a/src/test/ui/borrowck/return-local-binding-from-desugaring.rs b/src/test/ui/borrowck/return-local-binding-from-desugaring.rs new file mode 100644 index 0000000000000..b2dcd54ec2e90 --- /dev/null +++ b/src/test/ui/borrowck/return-local-binding-from-desugaring.rs @@ -0,0 +1,33 @@ +// To avoid leaking the names of local bindings from expressions like for loops, #60984 +// explicitly ignored them, but an assertion that `LocalKind::Var` *must* have a name would +// trigger an ICE. Before this change, this file's output would be: +// ``` +// error[E0515]: cannot return value referencing local variable `__next` +// --> return-local-binding-from-desugaring.rs:LL:CC +// | +// LL | for ref x in xs { +// | ----- `__next` is borrowed here +// ... +// LL | result +// | ^^^^^^ returns a value referencing data owned by the current function +// ``` +// FIXME: ideally `LocalKind` would carry more information to more accurately explain the problem. + +use std::collections::HashMap; +use std::hash::Hash; + +fn group_by(xs: &mut I, f: F) -> HashMap> +where + I: Iterator, + F: Fn(&I::Item) -> T, + T: Eq + Hash, +{ + let mut result = HashMap::new(); + for ref x in xs { + let key = f(x); + result.entry(key).or_insert(Vec::new()).push(x); + } + result //~ ERROR cannot return value referencing local binding +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-63026.stderr b/src/test/ui/borrowck/return-local-binding-from-desugaring.stderr similarity index 86% rename from src/test/ui/borrowck/issue-63026.stderr rename to src/test/ui/borrowck/return-local-binding-from-desugaring.stderr index 2289a03e014ff..293dbe6281313 100644 --- a/src/test/ui/borrowck/issue-63026.stderr +++ b/src/test/ui/borrowck/return-local-binding-from-desugaring.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing local binding - --> $DIR/issue-63026.rs:15:5 + --> $DIR/return-local-binding-from-desugaring.rs:30:5 | LL | for ref x in xs { | -- local binding introduced here