1
Fork 0

treat local variables specially

This commit is contained in:
Niko Matsakis 2018-08-10 17:34:56 -04:00
parent 8928de7439
commit a8a982bb61

View file

@ -798,12 +798,6 @@ enum LocalMutationIsAllowed {
No, No,
} }
struct AccessErrorsReported {
mutability_error: bool,
#[allow(dead_code)]
conflict_error: bool,
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
enum InitializationRequiringAction { enum InitializationRequiringAction {
Update, Update,
@ -1072,7 +1066,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
kind: (ShallowOrDeep, ReadOrWrite), kind: (ShallowOrDeep, ReadOrWrite),
is_local_mutation_allowed: LocalMutationIsAllowed, is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'cx, 'gcx, 'tcx>, flow_state: &Flows<'cx, 'gcx, 'tcx>,
) -> AccessErrorsReported { ) {
let (sd, rw) = kind; let (sd, rw) = kind;
if let Activation(_, borrow_index) = rw { if let Activation(_, borrow_index) = rw {
@ -1082,10 +1076,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
place: {:?} borrow_index: {:?}", place: {:?} borrow_index: {:?}",
place_span.0, borrow_index place_span.0, borrow_index
); );
return AccessErrorsReported { return;
mutability_error: false,
conflict_error: true,
};
} }
} }
@ -1097,10 +1088,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
"access_place: suppressing error place_span=`{:?}` kind=`{:?}`", "access_place: suppressing error place_span=`{:?}` kind=`{:?}`",
place_span, kind place_span, kind
); );
return AccessErrorsReported { return;
mutability_error: false,
conflict_error: true,
};
} }
let mutability_error = let mutability_error =
@ -1122,11 +1110,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
self.access_place_error_reported self.access_place_error_reported
.insert((place_span.0.clone(), place_span.1)); .insert((place_span.0.clone(), place_span.1));
} }
AccessErrorsReported {
mutability_error,
conflict_error,
}
} }
fn check_access_for_conflict( fn check_access_for_conflict(
@ -1275,23 +1258,25 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
} }
} }
let errors_reported = self.access_place( // Special case: you can assign a immutable local variable
// (e.g., `x = ...`) so long as it has never been initialized
// before (at this point in the flow).
if let &Place::Local(local) = place_span.0 {
if let Mutability::Not = self.mir.local_decls[local].mutability {
// check for reassignments to immutable local variables
self.check_if_reassignment_to_immutable_state(context, place_span, flow_state);
return;
}
}
// Otherwise, use the normal access permission rules.
self.access_place(
context, context,
place_span, place_span,
(kind, Write(WriteKind::Mutate)), (kind, Write(WriteKind::Mutate)),
// We want immutable upvars to cause an "assignment to immutable var" LocalMutationIsAllowed::No,
// error, not an "reassignment of immutable var" error, because the
// latter can't find a good previous assignment span.
//
// There's probably a better way to do this.
LocalMutationIsAllowed::ExceptUpvars,
flow_state, 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( fn consume_rvalue(