@@ -881,7 +881,6 @@ enum WriteKind {
881881/// local place can be mutated.
882882//
883883// FIXME: @nikomatsakis suggested that this flag could be removed with the following modifications:
884- // - Merge `check_access_permissions()` and `check_if_reassignment_to_immutable_state()`.
885884// - Split `is_mutable()` into `is_assignable()` (can be directly assigned) and
886885// `is_declared_mutable()`.
887886// - Take flow state into consideration in `is_assignable()` for local variables.
@@ -1150,20 +1149,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11501149 // Write of P[i] or *P requires P init'd.
11511150 self . check_if_assigned_path_is_moved ( location, place_span, flow_state) ;
11521151
1153- // Special case: you can assign an immutable local variable
1154- // (e.g., `x = ...`) so long as it has never been initialized
1155- // before (at this point in the flow).
1156- if let Some ( local) = place_span. 0 . as_local ( ) {
1157- if let Mutability :: Not = self . body . local_decls [ local] . mutability {
1158- // check for reassignments to immutable local variables
1159- self . check_if_reassignment_to_immutable_state (
1160- location, local, place_span, flow_state,
1161- ) ;
1162- return ;
1163- }
1164- }
1165-
1166- // Otherwise, use the normal access permission rules.
11671152 self . access_place (
11681153 location,
11691154 place_span,
@@ -1572,24 +1557,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
15721557 }
15731558 }
15741559
1575- fn check_if_reassignment_to_immutable_state (
1576- & mut self ,
1577- location : Location ,
1578- local : Local ,
1579- place_span : ( Place < ' tcx > , Span ) ,
1580- flow_state : & Flows < ' cx , ' tcx > ,
1581- ) {
1582- debug ! ( "check_if_reassignment_to_immutable_state({:?})" , local) ;
1583-
1584- // Check if any of the initializations of `local` have happened yet:
1585- if let Some ( init_index) = self . is_local_ever_initialized ( local, flow_state) {
1586- // And, if so, report an error.
1587- let init = & self . move_data . inits [ init_index] ;
1588- let span = init. span ( & self . body ) ;
1589- self . report_illegal_reassignment ( location, place_span, span, place_span. 0 ) ;
1590- }
1591- }
1592-
15931560 fn check_if_full_path_is_moved (
15941561 & mut self ,
15951562 location : Location ,
@@ -2056,12 +2023,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
20562023 // partial initialization, do not complain about mutability
20572024 // errors except for actual mutation (as opposed to an attempt
20582025 // to do a partial initialization).
2059- let previously_initialized =
2060- self . is_local_ever_initialized ( place. local , flow_state) . is_some ( ) ;
2026+ let previously_initialized = self . is_local_ever_initialized ( place. local , flow_state) ;
20612027
20622028 // at this point, we have set up the error reporting state.
2063- if previously_initialized {
2064- self . report_mutability_error ( place, span, the_place_err, error_access, location) ;
2029+ if let Some ( init_index) = previously_initialized {
2030+ match ( error_access, is_local_mutation_allowed, place. as_local ( ) ) {
2031+ // emit better diagnostic for reassignment to immutable local variables
2032+ ( AccessKind :: Mutate , LocalMutationIsAllowed :: No , Some ( _) ) => {
2033+ let init = & self . move_data . inits [ init_index] ;
2034+ let assigned_span = init. span ( & self . body ) ;
2035+ self . report_illegal_reassignment ( location, ( place, span) , assigned_span, place) ;
2036+ }
2037+ _ => {
2038+ self . report_mutability_error ( place, span, the_place_err, error_access, location)
2039+ }
2040+ }
20652041 true
20662042 } else {
20672043 false
0 commit comments