@@ -261,9 +261,17 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
261261
262262 debug ! ( "mbcx.used_mut: {:?}" , mbcx. used_mut) ;
263263
264- for local in mbcx. mir . mut_vars_iter ( ) . filter ( |local| !mbcx. used_mut . contains ( local) ) {
264+ for local in mbcx. mir . mut_vars_and_args_iter ( ) . filter ( |local| !mbcx. used_mut . contains ( local) ) {
265265 if let ClearCrossCrate :: Set ( ref vsi) = mbcx. mir . visibility_scope_info {
266- let source_info = mbcx. mir . local_decls [ local] . source_info ;
266+ let local_decl = & mbcx. mir . local_decls [ local] ;
267+
268+ // Skip over locals that begin with an underscore
269+ match local_decl. name {
270+ Some ( name) if name. as_str ( ) . starts_with ( "_" ) => continue ,
271+ _ => { } ,
272+ }
273+
274+ let source_info = local_decl. source_info ;
267275 let mut_span = tcx. sess . codemap ( ) . span_until_non_whitespace ( source_info. span ) ;
268276
269277 tcx. struct_span_lint_node (
@@ -864,7 +872,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
864872 }
865873
866874 let mutability_error =
867- self . check_access_permissions( place_span, rw, is_local_mutation_allowed) ;
875+ self . check_access_permissions( place_span, rw, is_local_mutation_allowed, flow_state ) ;
868876 let conflict_error =
869877 self . check_access_for_conflict( context, place_span, sd, rw, flow_state) ;
870878
@@ -1656,6 +1664,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16561664 ( place, span) : ( & Place < ' tcx > , Span ) ,
16571665 kind : ReadOrWrite ,
16581666 is_local_mutation_allowed : LocalMutationIsAllowed ,
1667+ flow_state : & Flows < ' cx , ' gcx , ' tcx > ,
16591668 ) -> bool {
16601669 debug ! (
16611670 "check_access_permissions({:?}, {:?}, {:?})" ,
@@ -1691,7 +1700,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16911700 Reservation ( WriteKind :: Mutate ) | Write ( WriteKind :: Mutate ) => {
16921701 match place {
16931702 Place :: Local ( local) => {
1694- self . used_mut . insert ( * local) ;
1703+ // If the local may be initialized, and it is now currently being
1704+ // mutated, then it is justified to be annotated with the `mut` keyword,
1705+ // since the mutation may be a possible reassignment.
1706+ let mpi = self . move_data . rev_lookup . find_local ( * local) ;
1707+ if flow_state. inits . contains ( & mpi) {
1708+ self . used_mut . insert ( * local) ;
1709+ }
16951710 }
16961711 Place :: Projection ( ref proj) => {
16971712 if let Some ( field) = self . is_upvar_field_projection ( & proj. base ) {
0 commit comments