Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge borrowck permission checks #106451

Merged
merged 1 commit into from
Jan 5, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 11 additions & 37 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,6 @@ enum WriteKind {
/// local place can be mutated.
//
// FIXME: @nikomatsakis suggested that this flag could be removed with the following modifications:
// - Merge `check_access_permissions()` and `check_if_reassignment_to_immutable_state()`.
// - Split `is_mutable()` into `is_assignable()` (can be directly assigned) and
// `is_declared_mutable()`.
// - Take flow state into consideration in `is_assignable()` for local variables.
Expand Down Expand Up @@ -1132,20 +1131,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// Write of P[i] or *P requires P init'd.
self.check_if_assigned_path_is_moved(location, place_span, flow_state);

// Special case: you can assign an immutable local variable
// (e.g., `x = ...`) so long as it has never been initialized
// before (at this point in the flow).
if let Some(local) = place_span.0.as_local() {
if let Mutability::Not = self.body.local_decls[local].mutability {
// check for reassignments to immutable local variables
self.check_if_reassignment_to_immutable_state(
location, local, place_span, flow_state,
);
return;
}
}

// Otherwise, use the normal access permission rules.
self.access_place(
location,
place_span,
Expand Down Expand Up @@ -1554,24 +1539,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}

fn check_if_reassignment_to_immutable_state(
&mut self,
location: Location,
local: Local,
place_span: (Place<'tcx>, Span),
flow_state: &Flows<'cx, 'tcx>,
) {
debug!("check_if_reassignment_to_immutable_state({:?})", local);

// Check if any of the initializations of `local` have happened yet:
if let Some(init_index) = self.is_local_ever_initialized(local, flow_state) {
// And, if so, report an error.
let init = &self.move_data.inits[init_index];
let span = init.span(&self.body);
self.report_illegal_reassignment(location, place_span, span, place_span.0);
}
}

fn check_if_full_path_is_moved(
&mut self,
location: Location,
Expand Down Expand Up @@ -2037,12 +2004,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// partial initialization, do not complain about mutability
// errors except for actual mutation (as opposed to an attempt
// to do a partial initialization).
let previously_initialized =
self.is_local_ever_initialized(place.local, flow_state).is_some();
let previously_initialized = self.is_local_ever_initialized(place.local, flow_state);

// at this point, we have set up the error reporting state.
if previously_initialized {
self.report_mutability_error(place, span, the_place_err, error_access, location);
if let Some(init_index) = previously_initialized {
if let (AccessKind::Mutate, Some(_)) = (error_access, place.as_local()) {
// If this is a mutate access to an immutable local variable with no projections
// report the error as an illegal reassignment
let init = &self.move_data.inits[init_index];
let assigned_span = init.span(&self.body);
self.report_illegal_reassignment(location, (place, span), assigned_span, place);
} else {
self.report_mutability_error(place, span, the_place_err, error_access, location)
}
true
} else {
false
Expand Down