Fix ICE with let...else
and ref mut
This commit is contained in:
parent
7fbd4ce276
commit
bf7c32a447
3 changed files with 27 additions and 8 deletions
|
@ -45,12 +45,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
let item_msg;
|
let item_msg;
|
||||||
let reason;
|
let reason;
|
||||||
let mut opt_source = None;
|
let mut opt_source = None;
|
||||||
let access_place_desc = self.describe_place(access_place.as_ref());
|
let access_place_desc = self.describe_any_place(access_place.as_ref());
|
||||||
debug!("report_mutability_error: access_place_desc={:?}", access_place_desc);
|
debug!("report_mutability_error: access_place_desc={:?}", access_place_desc);
|
||||||
|
|
||||||
match the_place_err {
|
match the_place_err {
|
||||||
PlaceRef { local, projection: [] } => {
|
PlaceRef { local, projection: [] } => {
|
||||||
item_msg = format!("`{}`", access_place_desc.unwrap());
|
item_msg = access_place_desc;
|
||||||
if access_place.as_local().is_some() {
|
if access_place.as_local().is_some() {
|
||||||
reason = ", as it is not declared as mutable".to_string();
|
reason = ", as it is not declared as mutable".to_string();
|
||||||
} else {
|
} else {
|
||||||
|
@ -83,7 +83,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
// If we deref an immutable ref then the suggestion here doesn't help.
|
// If we deref an immutable ref then the suggestion here doesn't help.
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
item_msg = format!("`{}`", access_place_desc.unwrap());
|
item_msg = access_place_desc;
|
||||||
if self.is_upvar_field_projection(access_place.as_ref()).is_some() {
|
if self.is_upvar_field_projection(access_place.as_ref()).is_some() {
|
||||||
reason = ", as it is not declared as mutable".to_string();
|
reason = ", as it is not declared as mutable".to_string();
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,17 +96,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
PlaceRef { local, projection: [ProjectionElem::Deref] }
|
PlaceRef { local, projection: [ProjectionElem::Deref] }
|
||||||
if self.body.local_decls[local].is_ref_for_guard() =>
|
if self.body.local_decls[local].is_ref_for_guard() =>
|
||||||
{
|
{
|
||||||
item_msg = format!("`{}`", access_place_desc.unwrap());
|
item_msg = access_place_desc;
|
||||||
reason = ", as it is immutable for the pattern guard".to_string();
|
reason = ", as it is immutable for the pattern guard".to_string();
|
||||||
}
|
}
|
||||||
PlaceRef { local, projection: [ProjectionElem::Deref] }
|
PlaceRef { local, projection: [ProjectionElem::Deref] }
|
||||||
if self.body.local_decls[local].is_ref_to_static() =>
|
if self.body.local_decls[local].is_ref_to_static() =>
|
||||||
{
|
{
|
||||||
if access_place.projection.len() == 1 {
|
if access_place.projection.len() == 1 {
|
||||||
item_msg = format!("immutable static item `{}`", access_place_desc.unwrap());
|
item_msg = format!("immutable static item {}", access_place_desc);
|
||||||
reason = String::new();
|
reason = String::new();
|
||||||
} else {
|
} else {
|
||||||
item_msg = format!("`{}`", access_place_desc.unwrap());
|
item_msg = access_place_desc;
|
||||||
let local_info = &self.body.local_decls[local].local_info;
|
let local_info = &self.body.local_decls[local].local_info;
|
||||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) = *local_info {
|
if let Some(box LocalInfo::StaticRef { def_id, .. }) = *local_info {
|
||||||
let static_name = &self.infcx.tcx.item_name(def_id);
|
let static_name = &self.infcx.tcx.item_name(def_id);
|
||||||
|
@ -121,7 +121,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
&& proj_base.is_empty()
|
&& proj_base.is_empty()
|
||||||
&& !self.upvars.is_empty()
|
&& !self.upvars.is_empty()
|
||||||
{
|
{
|
||||||
item_msg = format!("`{}`", access_place_desc.unwrap());
|
item_msg = access_place_desc;
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_region_ptr()
|
self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_region_ptr()
|
||||||
);
|
);
|
||||||
|
@ -147,7 +147,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
});
|
});
|
||||||
let pointer_type = source.describe_for_immutable_place(self.infcx.tcx);
|
let pointer_type = source.describe_for_immutable_place(self.infcx.tcx);
|
||||||
opt_source = Some(source);
|
opt_source = Some(source);
|
||||||
if let Some(desc) = access_place_desc {
|
if let Some(desc) = self.describe_place(access_place.as_ref()) {
|
||||||
item_msg = format!("`{}`", desc);
|
item_msg = format!("`{}`", desc);
|
||||||
reason = match error_access {
|
reason = match error_access {
|
||||||
AccessKind::Mutate => format!(", which is behind {}", pointer_type),
|
AccessKind::Mutate => format!(", which is behind {}", pointer_type),
|
||||||
|
|
7
src/test/ui/let-else/issue-89960.rs
Normal file
7
src/test/ui/let-else/issue-89960.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#![feature(let_else)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// FIXME: more precise diagnostics
|
||||||
|
let Some(ref mut meow) = Some(()) else { return };
|
||||||
|
//~^ ERROR: cannot borrow value as mutable, as `val` is not declared as mutable
|
||||||
|
}
|
12
src/test/ui/let-else/issue-89960.stderr
Normal file
12
src/test/ui/let-else/issue-89960.stderr
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0596]: cannot borrow value as mutable, as `val` is not declared as mutable
|
||||||
|
--> $DIR/issue-89960.rs:5:14
|
||||||
|
|
|
||||||
|
LL | let Some(ref mut meow) = Some(()) else { return };
|
||||||
|
| ---------^^^^^^^^^^^^-----------------------------
|
||||||
|
| | |
|
||||||
|
| | cannot borrow as mutable
|
||||||
|
| help: consider changing this to be mutable: `mut val`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0596`.
|
Loading…
Add table
Add a link
Reference in a new issue