mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-04 20:54:13 +00:00
clean up reassignment duplicate error prevention
This commit is contained in:
parent
5a3f7cdcc7
commit
733e95444f
@ -610,6 +610,12 @@ enum LocalMutationIsAllowed {
|
||||
No
|
||||
}
|
||||
|
||||
struct AccessErrorsReported {
|
||||
mutability_error: bool,
|
||||
#[allow(dead_code)]
|
||||
conflict_error: bool
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum InitializationRequiringAction {
|
||||
Update,
|
||||
@ -652,7 +658,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
kind: (ShallowOrDeep, ReadOrWrite),
|
||||
is_local_mutation_allowed: LocalMutationIsAllowed,
|
||||
flow_state: &Flows<'cx, 'gcx, 'tcx>,
|
||||
) {
|
||||
) -> AccessErrorsReported {
|
||||
let (sd, rw) = kind;
|
||||
|
||||
let storage_dead_or_drop_local = match (place_span.0, rw) {
|
||||
@ -663,14 +669,38 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
// Check if error has already been reported to stop duplicate reporting.
|
||||
if let Some(local) = storage_dead_or_drop_local {
|
||||
if self.storage_dead_or_drop_error_reported.contains(&local) {
|
||||
return;
|
||||
return AccessErrorsReported {
|
||||
mutability_error: false,
|
||||
conflict_error: true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Check permissions
|
||||
let mut error_reported =
|
||||
let mutability_error =
|
||||
self.check_access_permissions(place_span, rw, is_local_mutation_allowed);
|
||||
let conflict_error =
|
||||
self.check_access_for_conflict(context, place_span, sd, rw, flow_state);
|
||||
|
||||
// A conflict with a storagedead/drop is a "borrow does not live long enough"
|
||||
// error. Avoid reporting such an error multiple times for the same local.
|
||||
if conflict_error {
|
||||
if let Some(local) = storage_dead_or_drop_local {
|
||||
self.storage_dead_or_drop_error_reported.insert(local);
|
||||
}
|
||||
}
|
||||
|
||||
AccessErrorsReported { mutability_error, conflict_error }
|
||||
}
|
||||
|
||||
fn check_access_for_conflict(
|
||||
&mut self,
|
||||
context: Context,
|
||||
place_span: (&Place<'tcx>, Span),
|
||||
sd: ShallowOrDeep,
|
||||
rw: ReadOrWrite,
|
||||
flow_state: &Flows<'cx, 'gcx, 'tcx>,
|
||||
) -> bool {
|
||||
let mut error_reported = false;
|
||||
self.each_borrow_involving_path(
|
||||
context,
|
||||
(sd, place_span.0),
|
||||
@ -742,11 +772,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
},
|
||||
);
|
||||
|
||||
if error_reported {
|
||||
if let Some(local) = storage_dead_or_drop_local {
|
||||
self.storage_dead_or_drop_error_reported.insert(local);
|
||||
}
|
||||
}
|
||||
error_reported
|
||||
}
|
||||
|
||||
fn mutate_place(
|
||||
@ -772,7 +798,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
self.access_place(
|
||||
let errors_reported = self.access_place(
|
||||
context,
|
||||
place_span,
|
||||
(kind, Write(WriteKind::Mutate)),
|
||||
@ -780,8 +806,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
flow_state,
|
||||
);
|
||||
|
||||
// check for reassignments to immutable local variables
|
||||
self.check_if_reassignment_to_immutable_state(context, place_span, flow_state);
|
||||
if !errors_reported.mutability_error {
|
||||
// check for reassignments to immutable local variables
|
||||
self.check_if_reassignment_to_immutable_state(context, place_span, flow_state);
|
||||
}
|
||||
}
|
||||
|
||||
fn consume_rvalue(
|
||||
@ -988,10 +1016,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(_) = self.is_mutable(place, LocalMutationIsAllowed::Yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
match self.move_path_closest_to(place) {
|
||||
Ok(mpi) => for ii in &move_data.init_path_map[mpi] {
|
||||
if flow_state.ever_inits.contains(ii) {
|
||||
|
Loading…
Reference in New Issue
Block a user