Skip to content

Commit a8a982b

Browse files
committed
treat local variables specially
1 parent 8928de7 commit a8a982b

File tree

1 file changed

+17
-32
lines changed
  • src/librustc_mir/borrow_check

1 file changed

+17
-32
lines changed

src/librustc_mir/borrow_check/mod.rs

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -798,12 +798,6 @@ enum LocalMutationIsAllowed {
798798
No,
799799
}
800800

801-
struct AccessErrorsReported {
802-
mutability_error: bool,
803-
#[allow(dead_code)]
804-
conflict_error: bool,
805-
}
806-
807801
#[derive(Copy, Clone)]
808802
enum InitializationRequiringAction {
809803
Update,
@@ -1072,7 +1066,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
10721066
kind: (ShallowOrDeep, ReadOrWrite),
10731067
is_local_mutation_allowed: LocalMutationIsAllowed,
10741068
flow_state: &Flows<'cx, 'gcx, 'tcx>,
1075-
) -> AccessErrorsReported {
1069+
) {
10761070
let (sd, rw) = kind;
10771071

10781072
if let Activation(_, borrow_index) = rw {
@@ -1082,10 +1076,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
10821076
place: {:?} borrow_index: {:?}",
10831077
place_span.0, borrow_index
10841078
);
1085-
return AccessErrorsReported {
1086-
mutability_error: false,
1087-
conflict_error: true,
1088-
};
1079+
return;
10891080
}
10901081
}
10911082

@@ -1097,10 +1088,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
10971088
"access_place: suppressing error place_span=`{:?}` kind=`{:?}`",
10981089
place_span, kind
10991090
);
1100-
return AccessErrorsReported {
1101-
mutability_error: false,
1102-
conflict_error: true,
1103-
};
1091+
return;
11041092
}
11051093

11061094
let mutability_error =
@@ -1122,11 +1110,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
11221110
self.access_place_error_reported
11231111
.insert((place_span.0.clone(), place_span.1));
11241112
}
1125-
1126-
AccessErrorsReported {
1127-
mutability_error,
1128-
conflict_error,
1129-
}
11301113
}
11311114

11321115
fn check_access_for_conflict(
@@ -1275,23 +1258,25 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
12751258
}
12761259
}
12771260

1278-
let errors_reported = self.access_place(
1261+
// Special case: you can assign a immutable local variable
1262+
// (e.g., `x = ...`) so long as it has never been initialized
1263+
// before (at this point in the flow).
1264+
if let &Place::Local(local) = place_span.0 {
1265+
if let Mutability::Not = self.mir.local_decls[local].mutability {
1266+
// check for reassignments to immutable local variables
1267+
self.check_if_reassignment_to_immutable_state(context, place_span, flow_state);
1268+
return;
1269+
}
1270+
}
1271+
1272+
// Otherwise, use the normal access permission rules.
1273+
self.access_place(
12791274
context,
12801275
place_span,
12811276
(kind, Write(WriteKind::Mutate)),
1282-
// We want immutable upvars to cause an "assignment to immutable var"
1283-
// error, not an "reassignment of immutable var" error, because the
1284-
// latter can't find a good previous assignment span.
1285-
//
1286-
// There's probably a better way to do this.
1287-
LocalMutationIsAllowed::ExceptUpvars,
1277+
LocalMutationIsAllowed::No,
12881278
flow_state,
12891279
);
1290-
1291-
if !errors_reported.mutability_error {
1292-
// check for reassignments to immutable local variables
1293-
self.check_if_reassignment_to_immutable_state(context, place_span, flow_state);
1294-
}
12951280
}
12961281

12971282
fn consume_rvalue(

0 commit comments

Comments
 (0)