Return LocalMutationIsAllowed in is_mutable
This commit is contained in:
parent
71d221f294
commit
180e2426c9
1 changed files with 32 additions and 31 deletions
|
@ -1366,7 +1366,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||||
) {
|
) {
|
||||||
debug!("check_if_reassignment_to_immutable_state({:?})", place);
|
debug!("check_if_reassignment_to_immutable_state({:?})", place);
|
||||||
// determine if this path has a non-mut owner (and thus needs checking).
|
// determine if this path has a non-mut owner (and thus needs checking).
|
||||||
if let Ok(_) = self.is_mutable(place, LocalMutationIsAllowed::No) {
|
if let Ok(..) = self.is_mutable(place, LocalMutationIsAllowed::No) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -1681,24 +1681,23 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||||
Reservation(WriteKind::MutableBorrow(BorrowKind::Mut { .. }))
|
Reservation(WriteKind::MutableBorrow(BorrowKind::Mut { .. }))
|
||||||
| Write(WriteKind::MutableBorrow(BorrowKind::Mut { .. })) => {
|
| Write(WriteKind::MutableBorrow(BorrowKind::Mut { .. })) => {
|
||||||
match self.is_mutable(place, is_local_mutation_allowed) {
|
match self.is_mutable(place, is_local_mutation_allowed) {
|
||||||
Ok(Place::Local(local))
|
Ok((Place::Local(local), mut_allowed)) => {
|
||||||
if is_local_mutation_allowed != LocalMutationIsAllowed::Yes =>
|
if mut_allowed != LocalMutationIsAllowed::Yes {
|
||||||
{
|
// If the local may be initialized, and it is now currently being
|
||||||
// If the local may be initialized, and it is now currently being
|
// mutated, then it is justified to be annotated with the `mut`
|
||||||
// mutated, then it is justified to be annotated with the `mut` keyword,
|
// keyword, since the mutation may be a possible reassignment.
|
||||||
// since the mutation may be a possible reassignment.
|
let mpi = self.move_data.rev_lookup.find_local(*local);
|
||||||
let mpi = self.move_data.rev_lookup.find_local(*local);
|
if flow_state.inits.contains(&mpi) {
|
||||||
if flow_state.inits.contains(&mpi) {
|
self.used_mut.insert(*local);
|
||||||
self.used_mut.insert(*local);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Place::Projection(ref proj)) => {
|
Ok((Place::Projection(ref proj), _mut_allowed)) => {
|
||||||
if let Some(field) = self.is_upvar_field_projection(&proj.base) {
|
if let Some(field) = self.is_upvar_field_projection(&proj.base) {
|
||||||
self.used_mut_upvars.push(field);
|
self.used_mut_upvars.push(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Place::Local(_)) |
|
Ok((Place::Static(..), _mut_allowed)) => {}
|
||||||
Ok(Place::Static(..)) => {}
|
|
||||||
Err(place_err) => {
|
Err(place_err) => {
|
||||||
error_reported = true;
|
error_reported = true;
|
||||||
let item_msg = self.get_default_err_msg(place);
|
let item_msg = self.get_default_err_msg(place);
|
||||||
|
@ -1719,24 +1718,23 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
Reservation(WriteKind::Mutate) | Write(WriteKind::Mutate) => {
|
Reservation(WriteKind::Mutate) | Write(WriteKind::Mutate) => {
|
||||||
match self.is_mutable(place, is_local_mutation_allowed) {
|
match self.is_mutable(place, is_local_mutation_allowed) {
|
||||||
Ok(Place::Local(local))
|
Ok((Place::Local(local), mut_allowed)) => {
|
||||||
if is_local_mutation_allowed != LocalMutationIsAllowed::Yes =>
|
if mut_allowed != LocalMutationIsAllowed::Yes {
|
||||||
{
|
// If the local may be initialized, and it is now currently being
|
||||||
// If the local may be initialized, and it is now currently being
|
// mutated, then it is justified to be annotated with the `mut`
|
||||||
// mutated, then it is justified to be annotated with the `mut` keyword,
|
// keyword, since the mutation may be a possible reassignment.
|
||||||
// since the mutation may be a possible reassignment.
|
let mpi = self.move_data.rev_lookup.find_local(*local);
|
||||||
let mpi = self.move_data.rev_lookup.find_local(*local);
|
if flow_state.inits.contains(&mpi) {
|
||||||
if flow_state.inits.contains(&mpi) {
|
self.used_mut.insert(*local);
|
||||||
self.used_mut.insert(*local);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Place::Projection(ref proj)) => {
|
Ok((Place::Projection(ref proj), _mut_allowed)) => {
|
||||||
if let Some(field) = self.is_upvar_field_projection(&proj.base) {
|
if let Some(field) = self.is_upvar_field_projection(&proj.base) {
|
||||||
self.used_mut_upvars.push(field);
|
self.used_mut_upvars.push(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Place::Local(_)) |
|
Ok((Place::Static(..), _mut_allowed)) => {}
|
||||||
Ok(Place::Static(..)) => {}
|
|
||||||
Err(place_err) => {
|
Err(place_err) => {
|
||||||
error_reported = true;
|
error_reported = true;
|
||||||
|
|
||||||
|
@ -1835,25 +1833,28 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
place: &'d Place<'tcx>,
|
place: &'d Place<'tcx>,
|
||||||
is_local_mutation_allowed: LocalMutationIsAllowed,
|
is_local_mutation_allowed: LocalMutationIsAllowed,
|
||||||
) -> Result<&'d Place<'tcx>, &'d Place<'tcx>> {
|
) -> Result<(&'d Place<'tcx>, LocalMutationIsAllowed), &'d Place<'tcx>> {
|
||||||
match *place {
|
match *place {
|
||||||
Place::Local(local) => {
|
Place::Local(local) => {
|
||||||
let local = &self.mir.local_decls[local];
|
let local = &self.mir.local_decls[local];
|
||||||
match local.mutability {
|
match local.mutability {
|
||||||
Mutability::Not => match is_local_mutation_allowed {
|
Mutability::Not => match is_local_mutation_allowed {
|
||||||
LocalMutationIsAllowed::Yes | LocalMutationIsAllowed::ExceptUpvars => {
|
LocalMutationIsAllowed::Yes => {
|
||||||
Ok(place)
|
Ok((place, LocalMutationIsAllowed::Yes))
|
||||||
|
}
|
||||||
|
LocalMutationIsAllowed::ExceptUpvars => {
|
||||||
|
Ok((place, LocalMutationIsAllowed::ExceptUpvars))
|
||||||
}
|
}
|
||||||
LocalMutationIsAllowed::No => Err(place),
|
LocalMutationIsAllowed::No => Err(place),
|
||||||
},
|
},
|
||||||
Mutability::Mut => Ok(place),
|
Mutability::Mut => Ok((place, is_local_mutation_allowed)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Place::Static(ref static_) =>
|
Place::Static(ref static_) =>
|
||||||
if self.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) {
|
if self.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) {
|
||||||
Err(place)
|
Err(place)
|
||||||
} else {
|
} else {
|
||||||
Ok(place)
|
Ok((place, is_local_mutation_allowed))
|
||||||
},
|
},
|
||||||
Place::Projection(ref proj) => {
|
Place::Projection(ref proj) => {
|
||||||
match proj.elem {
|
match proj.elem {
|
||||||
|
@ -1891,7 +1892,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||||
hir::MutImmutable => return Err(place),
|
hir::MutImmutable => return Err(place),
|
||||||
// `*mut` raw pointers are always mutable, regardless of context
|
// `*mut` raw pointers are always mutable, regardless of context
|
||||||
// The users have to check by themselve.
|
// The users have to check by themselve.
|
||||||
hir::MutMutable => return Ok(place),
|
hir::MutMutable => return Ok((place, is_local_mutation_allowed)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// `Box<T>` owns its content, so mutable if its location is mutable
|
// `Box<T>` owns its content, so mutable if its location is mutable
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue