]> git.lizzy.rs Git - rust.git/commitdiff
Return LocalMutationIsAllowed in is_mutable
authorKeith Yeung <kungfukeith11@gmail.com>
Tue, 20 Mar 2018 19:58:38 +0000 (12:58 -0700)
committerKeith Yeung <kungfukeith11@gmail.com>
Sat, 28 Apr 2018 08:55:25 +0000 (01:55 -0700)
src/librustc_mir/borrow_check/mod.rs

index 2498162d10fa185a31a31cde8ef6cc3cf54b46cf..9da5d1dcdcd4fac5f347a095f0f7f049608dce29 100644 (file)
@@ -1366,7 +1366,7 @@ fn check_if_reassignment_to_immutable_state(
     ) {
         debug!("check_if_reassignment_to_immutable_state({:?})", place);
         // 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;
         }
         debug!(
@@ -1681,24 +1681,23 @@ fn check_access_permissions(
             Reservation(WriteKind::MutableBorrow(BorrowKind::Mut { .. }))
             | Write(WriteKind::MutableBorrow(BorrowKind::Mut { .. })) => {
                 match self.is_mutable(place, is_local_mutation_allowed) {
-                    Ok(Place::Local(local))
-                        if is_local_mutation_allowed != LocalMutationIsAllowed::Yes =>
-                    {
-                        // If the local may be initialized, and it is now currently being
-                        // mutated, then it is justified to be annotated with the `mut` keyword,
-                        // since the mutation may be a possible reassignment.
-                        let mpi = self.move_data.rev_lookup.find_local(*local);
-                        if flow_state.inits.contains(&mpi) {
-                            self.used_mut.insert(*local);
+                    Ok((Place::Local(local), mut_allowed)) => {
+                        if mut_allowed != LocalMutationIsAllowed::Yes {
+                            // If the local may be initialized, and it is now currently being
+                            // mutated, then it is justified to be annotated with the `mut`
+                            // keyword, since the mutation may be a possible reassignment.
+                            let mpi = self.move_data.rev_lookup.find_local(*local);
+                            if flow_state.inits.contains(&mpi) {
+                                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) {
                             self.used_mut_upvars.push(field);
                         }
                     }
-                    Ok(Place::Local(_)) |
-                    Ok(Place::Static(..)) => {}
+                    Ok((Place::Static(..), _mut_allowed)) => {}
                     Err(place_err) => {
                         error_reported = true;
                         let item_msg = self.get_default_err_msg(place);
@@ -1719,24 +1718,23 @@ fn check_access_permissions(
             }
             Reservation(WriteKind::Mutate) | Write(WriteKind::Mutate) => {
                 match self.is_mutable(place, is_local_mutation_allowed) {
-                    Ok(Place::Local(local))
-                        if is_local_mutation_allowed != LocalMutationIsAllowed::Yes =>
-                    {
-                        // If the local may be initialized, and it is now currently being
-                        // mutated, then it is justified to be annotated with the `mut` keyword,
-                        // since the mutation may be a possible reassignment.
-                        let mpi = self.move_data.rev_lookup.find_local(*local);
-                        if flow_state.inits.contains(&mpi) {
-                            self.used_mut.insert(*local);
+                    Ok((Place::Local(local), mut_allowed)) => {
+                        if mut_allowed != LocalMutationIsAllowed::Yes {
+                            // If the local may be initialized, and it is now currently being
+                            // mutated, then it is justified to be annotated with the `mut`
+                            // keyword, since the mutation may be a possible reassignment.
+                            let mpi = self.move_data.rev_lookup.find_local(*local);
+                            if flow_state.inits.contains(&mpi) {
+                                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) {
                             self.used_mut_upvars.push(field);
                         }
                     }
-                    Ok(Place::Local(_)) |
-                    Ok(Place::Static(..)) => {}
+                    Ok((Place::Static(..), _mut_allowed)) => {}
                     Err(place_err) => {
                         error_reported = true;
 
@@ -1835,25 +1833,28 @@ fn is_mutable<'d>(
         &self,
         place: &'d Place<'tcx>,
         is_local_mutation_allowed: LocalMutationIsAllowed,
-    ) -> Result<&'d Place<'tcx>, &'d Place<'tcx>> {
+    ) -> Result<(&'d Place<'tcx>, LocalMutationIsAllowed), &'d Place<'tcx>> {
         match *place {
             Place::Local(local) => {
                 let local = &self.mir.local_decls[local];
                 match local.mutability {
                     Mutability::Not => match is_local_mutation_allowed {
-                        LocalMutationIsAllowed::Yes | LocalMutationIsAllowed::ExceptUpvars => {
-                            Ok(place)
+                        LocalMutationIsAllowed::Yes => {
+                            Ok((place, LocalMutationIsAllowed::Yes))
+                        }
+                        LocalMutationIsAllowed::ExceptUpvars => {
+                            Ok((place, LocalMutationIsAllowed::ExceptUpvars))
                         }
                         LocalMutationIsAllowed::No => Err(place),
                     },
-                    Mutability::Mut => Ok(place),
+                    Mutability::Mut => Ok((place, is_local_mutation_allowed)),
                 }
             }
             Place::Static(ref static_) =>
                 if self.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) {
                     Err(place)
                 } else {
-                    Ok(place)
+                    Ok((place, is_local_mutation_allowed))
                 },
             Place::Projection(ref proj) => {
                 match proj.elem {
@@ -1891,7 +1892,7 @@ fn is_mutable<'d>(
                                     hir::MutImmutable => return Err(place),
                                     // `*mut` raw pointers are always mutable, regardless of context
                                     // 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