Skip to content

Commit bcb1403

Browse files
authored
Rollup merge of #82056 - b-naber:mut_for_loop_bug, r=oli-obk
fix ice (#82032) Fixes #82032
2 parents c8dacf9 + 26ca5fb commit bcb1403

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_hir as hir;
22
use rustc_hir::Node;
33
use rustc_index::vec::Idx;
4+
use rustc_middle::hir::map::Map;
45
use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
56
use rustc_middle::ty::{self, Ty, TyCtxt};
67
use rustc_middle::{
@@ -543,13 +544,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
543544
// Attempt to search similar mutable associated items for suggestion.
544545
// In the future, attempt in all path but initially for RHS of for_loop
545546
fn suggest_similar_mut_method_for_for_loop(&self, err: &mut DiagnosticBuilder<'_>) {
546-
let hir = self.infcx.tcx.hir();
547-
let node = hir.item(self.mir_hir_id());
548547
use hir::{
549-
Expr,
548+
BodyId, Expr,
550549
ExprKind::{Block, Call, DropTemps, Match, MethodCall},
550+
HirId, ImplItem, ImplItemKind, Item, ItemKind,
551551
};
552-
if let hir::ItemKind::Fn(_, _, body_id) = node.kind {
552+
553+
fn maybe_body_id_of_fn(hir_map: &Map<'tcx>, id: HirId) -> Option<BodyId> {
554+
match hir_map.find(id) {
555+
Some(Node::Item(Item { kind: ItemKind::Fn(_, _, body_id), .. }))
556+
| Some(Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })) => {
557+
Some(*body_id)
558+
}
559+
_ => None,
560+
}
561+
}
562+
let hir_map = self.infcx.tcx.hir();
563+
let mir_body_hir_id = self.mir_hir_id();
564+
if let Some(fn_body_id) = maybe_body_id_of_fn(&hir_map, mir_body_hir_id) {
553565
if let Block(
554566
hir::Block {
555567
expr:
@@ -579,7 +591,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
579591
..
580592
},
581593
_,
582-
) = hir.body(body_id).value.kind
594+
) = hir_map.body(fn_body_id).value.kind
583595
{
584596
let opt_suggestions = path_segment
585597
.hir_id

src/test/ui/borrowck/issue-82032.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use std::{fs, io::*};
2+
use std::collections::HashMap;
3+
4+
type Handle = BufWriter<fs::File>;
5+
struct Thing(HashMap<String, Handle>);
6+
7+
impl Thing {
8+
pub fn die_horribly(&mut self) {
9+
for v in self.0.values() {
10+
v.flush();
11+
//~^ ERROR cannot borrow
12+
}
13+
}
14+
}
15+
16+
fn main() {}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0596]: cannot borrow `*v` as mutable, as it is behind a `&` reference
2+
--> $DIR/issue-82032.rs:10:13
3+
|
4+
LL | for v in self.0.values() {
5+
| ---------------
6+
| | |
7+
| | help: use mutable method: `values_mut()`
8+
| this iterator yields `&` references
9+
LL | v.flush();
10+
| ^ `v` is a `&` reference, so the data it refers to cannot be borrowed as mutable
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0596`.

0 commit comments

Comments
 (0)