@@ -610,6 +610,12 @@ enum LocalMutationIsAllowed {
610610 No
611611}
612612
613+ struct AccessErrorsReported {
614+ mutability_error : bool ,
615+ #[ allow( dead_code) ]
616+ conflict_error : bool
617+ }
618+
613619#[ derive( Copy , Clone ) ]
614620enum InitializationRequiringAction {
615621 Update ,
@@ -652,7 +658,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
652658 kind : ( ShallowOrDeep , ReadOrWrite ) ,
653659 is_local_mutation_allowed : LocalMutationIsAllowed ,
654660 flow_state : & Flows < ' cx , ' gcx , ' tcx > ,
655- ) {
661+ ) -> AccessErrorsReported {
656662 let ( sd, rw) = kind;
657663
658664 let storage_dead_or_drop_local = match ( place_span. 0 , rw) {
@@ -663,14 +669,38 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
663669 // Check if error has already been reported to stop duplicate reporting.
664670 if let Some ( local) = storage_dead_or_drop_local {
665671 if self . storage_dead_or_drop_error_reported . contains ( & local) {
666- return ;
672+ return AccessErrorsReported {
673+ mutability_error : false ,
674+ conflict_error : true
675+ } ;
667676 }
668677 }
669678
670- // Check permissions
671- let mut error_reported =
679+ let mutability_error =
672680 self . check_access_permissions ( place_span, rw, is_local_mutation_allowed) ;
681+ let conflict_error =
682+ self . check_access_for_conflict ( context, place_span, sd, rw, flow_state) ;
673683
684+ // A conflict with a storagedead/drop is a "borrow does not live long enough"
685+ // error. Avoid reporting such an error multiple times for the same local.
686+ if conflict_error {
687+ if let Some ( local) = storage_dead_or_drop_local {
688+ self . storage_dead_or_drop_error_reported . insert ( local) ;
689+ }
690+ }
691+
692+ AccessErrorsReported { mutability_error, conflict_error }
693+ }
694+
695+ fn check_access_for_conflict (
696+ & mut self ,
697+ context : Context ,
698+ place_span : ( & Place < ' tcx > , Span ) ,
699+ sd : ShallowOrDeep ,
700+ rw : ReadOrWrite ,
701+ flow_state : & Flows < ' cx , ' gcx , ' tcx > ,
702+ ) -> bool {
703+ let mut error_reported = false ;
674704 self . each_borrow_involving_path (
675705 context,
676706 ( sd, place_span. 0 ) ,
@@ -742,11 +772,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
742772 } ,
743773 ) ;
744774
745- if error_reported {
746- if let Some ( local) = storage_dead_or_drop_local {
747- self . storage_dead_or_drop_error_reported . insert ( local) ;
748- }
749- }
775+ error_reported
750776 }
751777
752778 fn mutate_place (
@@ -772,16 +798,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
772798 }
773799 }
774800
775- self . access_place (
801+ let errors_reported = self . access_place (
776802 context,
777803 place_span,
778804 ( kind, Write ( WriteKind :: Mutate ) ) ,
779805 LocalMutationIsAllowed :: Yes ,
780806 flow_state,
781807 ) ;
782808
783- // check for reassignments to immutable local variables
784- self . check_if_reassignment_to_immutable_state ( context, place_span, flow_state) ;
809+ if !errors_reported. mutability_error {
810+ // check for reassignments to immutable local variables
811+ self . check_if_reassignment_to_immutable_state ( context, place_span, flow_state) ;
812+ }
785813 }
786814
787815 fn consume_rvalue (
@@ -988,10 +1016,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
9881016 return ;
9891017 }
9901018
991- if let Err ( _) = self . is_mutable ( place, LocalMutationIsAllowed :: Yes ) {
992- return ;
993- }
994-
9951019 match self . move_path_closest_to ( place) {
9961020 Ok ( mpi) => for ii in & move_data. init_path_map [ mpi] {
9971021 if flow_state. ever_inits . contains ( ii) {
0 commit comments