Rollup merge of #63051 - estebank:borrow-ice, r=matthewjasper
Avoid ICE when referencing desugared local binding in borrow error 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, the binding generated by desugaring the for loop would leak into the diagnostic (#63027): ``` 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 ``` Ideally `LocalKind` would carry more information to more accurately explain the problem, but for now, in order to avoid the ICE (fix #63026), we accept `LocalKind::Var` without a name and produce the following output: ``` error[E0515]: cannot return value referencing local binding --> $DIR/return-local-binding-from-desugaring.rs:30:5 | LL | for ref x in xs { | -- local binding introduced here ... LL | result | ^^^^^^ returns a value referencing data owned by the current function ```
This commit is contained in:
commit
a558668cf2
@ -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(),
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
|
33
src/test/ui/borrowck/return-local-binding-from-desugaring.rs
Normal file
33
src/test/ui/borrowck/return-local-binding-from-desugaring.rs
Normal file
@ -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<I, F, T>(xs: &mut I, f: F) -> HashMap<T, Vec<&I::Item>>
|
||||
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() {}
|
@ -0,0 +1,12 @@
|
||||
error[E0515]: cannot return value referencing local binding
|
||||
--> $DIR/return-local-binding-from-desugaring.rs:30: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`.
|
Loading…
x
Reference in New Issue
Block a user