mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
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.
This commit is contained in:
commit
5c7b383e59
@ -513,32 +513,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
let id = id.expect_local();
|
||||
let tables = tcx.typeck(id);
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(id);
|
||||
let (span, place) = &tables.closure_kind_origins()[hir_id];
|
||||
let reason = if let PlaceBase::Upvar(upvar_id) = place.base {
|
||||
let upvar = ty::place_to_string_for_capture(tcx, place);
|
||||
match tables.upvar_capture(upvar_id) {
|
||||
ty::UpvarCapture::ByRef(ty::UpvarBorrow {
|
||||
kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow,
|
||||
..
|
||||
}) => {
|
||||
format!("mutable borrow of `{}`", upvar)
|
||||
if let Some((span, place)) = tables.closure_kind_origins().get(hir_id) {
|
||||
let reason = if let PlaceBase::Upvar(upvar_id) = place.base {
|
||||
let upvar = ty::place_to_string_for_capture(tcx, place);
|
||||
match tables.upvar_capture(upvar_id) {
|
||||
ty::UpvarCapture::ByRef(ty::UpvarBorrow {
|
||||
kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow,
|
||||
..
|
||||
}) => {
|
||||
format!("mutable borrow of `{}`", upvar)
|
||||
}
|
||||
ty::UpvarCapture::ByValue(_) => {
|
||||
format!("possible mutation of `{}`", upvar)
|
||||
}
|
||||
val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val),
|
||||
}
|
||||
ty::UpvarCapture::ByValue(_) => {
|
||||
format!("possible mutation of `{}`", upvar)
|
||||
}
|
||||
val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val),
|
||||
}
|
||||
} else {
|
||||
bug!("not an upvar")
|
||||
};
|
||||
err.span_label(
|
||||
*span,
|
||||
format!(
|
||||
"calling `{}` requires mutable binding due to {}",
|
||||
self.describe_place(the_place_err).unwrap(),
|
||||
reason
|
||||
),
|
||||
);
|
||||
} else {
|
||||
bug!("not an upvar")
|
||||
};
|
||||
err.span_label(
|
||||
*span,
|
||||
format!(
|
||||
"calling `{}` requires mutable binding due to {}",
|
||||
self.describe_place(the_place_err).unwrap(),
|
||||
reason
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to search similar mutable associated items for suggestion.
|
||||
|
28
src/test/ui/closures/issue-82438-mut-without-upvar.rs
Normal file
28
src/test/ui/closures/issue-82438-mut-without-upvar.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use std::error::Error;
|
||||
struct A {
|
||||
}
|
||||
|
||||
impl A {
|
||||
pub fn new() -> A {
|
||||
A {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn f<'a>(
|
||||
&'a self,
|
||||
team_name: &'a str,
|
||||
c: &'a mut dyn FnMut(String, String, u64, u64)
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let A = A::new();
|
||||
let participant_name = "A";
|
||||
|
||||
let c = |a, b, c, d| {};
|
||||
|
||||
A.f(participant_name, &mut c); //~ ERROR cannot borrow
|
||||
}
|
12
src/test/ui/closures/issue-82438-mut-without-upvar.stderr
Normal file
12
src/test/ui/closures/issue-82438-mut-without-upvar.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0596]: cannot borrow `c` as mutable, as it is not declared as mutable
|
||||
--> $DIR/issue-82438-mut-without-upvar.rs:27:27
|
||||
|
|
||||
LL | let c = |a, b, c, d| {};
|
||||
| - help: consider changing this to be mutable: `mut c`
|
||||
LL |
|
||||
LL | A.f(participant_name, &mut c);
|
||||
| ^^^^^^ cannot borrow as mutable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0596`.
|
Loading…
Reference in New Issue
Block a user