Skip to content

Commit cd7737e

Browse files
authored
Rollup merge of #82442 - Aaron1011:fix/closure-mut-crash, r=matthewjasper
Skip emitting closure diagnostic when closure_kind_origins has no entry Fixes #82438 This map is not guarnateed to have an entry for a closure.
2 parents 13d8a56 + 46db4ba commit cd7737e

File tree

3 files changed

+66
-25
lines changed

3 files changed

+66
-25
lines changed

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

+26-25
Original file line numberDiff line numberDiff line change
@@ -513,32 +513,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
513513
let id = id.expect_local();
514514
let tables = tcx.typeck(id);
515515
let hir_id = tcx.hir().local_def_id_to_hir_id(id);
516-
let (span, place) = &tables.closure_kind_origins()[hir_id];
517-
let reason = if let PlaceBase::Upvar(upvar_id) = place.base {
518-
let upvar = ty::place_to_string_for_capture(tcx, place);
519-
match tables.upvar_capture(upvar_id) {
520-
ty::UpvarCapture::ByRef(ty::UpvarBorrow {
521-
kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow,
522-
..
523-
}) => {
524-
format!("mutable borrow of `{}`", upvar)
525-
}
526-
ty::UpvarCapture::ByValue(_) => {
527-
format!("possible mutation of `{}`", upvar)
516+
if let Some((span, place)) = tables.closure_kind_origins().get(hir_id) {
517+
let reason = if let PlaceBase::Upvar(upvar_id) = place.base {
518+
let upvar = ty::place_to_string_for_capture(tcx, place);
519+
match tables.upvar_capture(upvar_id) {
520+
ty::UpvarCapture::ByRef(ty::UpvarBorrow {
521+
kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow,
522+
..
523+
}) => {
524+
format!("mutable borrow of `{}`", upvar)
525+
}
526+
ty::UpvarCapture::ByValue(_) => {
527+
format!("possible mutation of `{}`", upvar)
528+
}
529+
val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val),
528530
}
529-
val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val),
530-
}
531-
} else {
532-
bug!("not an upvar")
533-
};
534-
err.span_label(
535-
*span,
536-
format!(
537-
"calling `{}` requires mutable binding due to {}",
538-
self.describe_place(the_place_err).unwrap(),
539-
reason
540-
),
541-
);
531+
} else {
532+
bug!("not an upvar")
533+
};
534+
err.span_label(
535+
*span,
536+
format!(
537+
"calling `{}` requires mutable binding due to {}",
538+
self.describe_place(the_place_err).unwrap(),
539+
reason
540+
),
541+
);
542+
}
542543
}
543544

544545
// Attempt to search similar mutable associated items for suggestion.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use std::error::Error;
2+
struct A {
3+
}
4+
5+
impl A {
6+
pub fn new() -> A {
7+
A {
8+
}
9+
}
10+
11+
pub fn f<'a>(
12+
&'a self,
13+
team_name: &'a str,
14+
c: &'a mut dyn FnMut(String, String, u64, u64)
15+
) -> Result<(), Box<dyn Error>> {
16+
Ok(())
17+
}
18+
}
19+
20+
21+
fn main() {
22+
let A = A::new();
23+
let participant_name = "A";
24+
25+
let c = |a, b, c, d| {};
26+
27+
A.f(participant_name, &mut c); //~ ERROR cannot borrow
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0596]: cannot borrow `c` as mutable, as it is not declared as mutable
2+
--> $DIR/issue-82438-mut-without-upvar.rs:27:27
3+
|
4+
LL | let c = |a, b, c, d| {};
5+
| - help: consider changing this to be mutable: `mut c`
6+
LL |
7+
LL | A.f(participant_name, &mut c);
8+
| ^^^^^^ cannot borrow as mutable
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0596`.

0 commit comments

Comments
 (0)