Skip to content

Commit 2c0bc3d

Browse files
estebankMark-Simulacrum
authored andcommitted
Avoid ICE when referencing desugared local binding in borrow error
1 parent c24cb35 commit 2c0bc3d

File tree

3 files changed

+57
-13
lines changed

3 files changed

+57
-13
lines changed

src/librustc_mir/borrow_check/conflict_errors.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,19 +1116,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11161116
bug!("try_report_cannot_return_reference_to_local: not a local")
11171117
};
11181118
match self.body.local_kind(local) {
1119-
LocalKind::ReturnPointer | LocalKind::Temp => {
1120-
(
1121-
"temporary value".to_string(),
1122-
"temporary value created here".to_string(),
1123-
)
1124-
}
1125-
LocalKind::Arg => {
1126-
(
1127-
"function parameter".to_string(),
1128-
"function parameter borrowed here".to_string(),
1129-
)
1130-
},
1131-
LocalKind::Var => bug!("local variable without a name"),
1119+
LocalKind::ReturnPointer | LocalKind::Temp => (
1120+
"temporary value".to_string(),
1121+
"temporary value created here".to_string(),
1122+
),
1123+
LocalKind::Arg => (
1124+
"function parameter".to_string(),
1125+
"function parameter borrowed here".to_string(),
1126+
),
1127+
LocalKind::Var => (
1128+
"local binding".to_string(),
1129+
"local binding introduced here".to_string(),
1130+
),
11321131
}
11331132
};
11341133

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// To avoid leaking the names of local bindings from expressions like for loops, #60984
2+
// explicitly ignored them, but an assertion that `LocalKind::Var` *must* have a name would
3+
// trigger an ICE. Before this change, this file's output would be:
4+
// ```
5+
// error[E0515]: cannot return value referencing local variable `__next`
6+
// --> return-local-binding-from-desugaring.rs:LL:CC
7+
// |
8+
// LL | for ref x in xs {
9+
// | ----- `__next` is borrowed here
10+
// ...
11+
// LL | result
12+
// | ^^^^^^ returns a value referencing data owned by the current function
13+
// ```
14+
// FIXME: ideally `LocalKind` would carry more information to more accurately explain the problem.
15+
16+
use std::collections::HashMap;
17+
use std::hash::Hash;
18+
19+
fn group_by<I, F, T>(xs: &mut I, f: F) -> HashMap<T, Vec<&I::Item>>
20+
where
21+
I: Iterator,
22+
F: Fn(&I::Item) -> T,
23+
T: Eq + Hash,
24+
{
25+
let mut result = HashMap::new();
26+
for ref x in xs {
27+
let key = f(x);
28+
result.entry(key).or_insert(Vec::new()).push(x);
29+
}
30+
result //~ ERROR cannot return value referencing local binding
31+
}
32+
33+
fn main() {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0515]: cannot return value referencing local binding
2+
--> $DIR/return-local-binding-from-desugaring.rs:30:5
3+
|
4+
LL | for ref x in xs {
5+
| -- local binding introduced here
6+
...
7+
LL | result
8+
| ^^^^^^ returns a value referencing data owned by the current function
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0515`.

0 commit comments

Comments
 (0)