1
Fork 0

Return LocalMutationIsAllowed in is_mutable

This commit is contained in:
Keith Yeung 2018-03-20 12:58:38 -07:00
parent 71d221f294
commit 180e2426c9

View file

@ -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