Skip to content

Commit 82f3fc5

Browse files
committed
fix handling of immutable variables
1 parent 210f768 commit 82f3fc5

File tree

1 file changed

+28
-16
lines changed
  • src/librustc_mir/borrow_check

1 file changed

+28
-16
lines changed

src/librustc_mir/borrow_check/mod.rs

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -655,8 +655,9 @@ enum WriteKind {
655655
/// - Take flow state into consideration in `is_assignable()` for local variables
656656
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
657657
enum LocalMutationIsAllowed {
658+
Move,
658659
Yes,
659-
No,
660+
No
660661
}
661662

662663
#[derive(Copy, Clone)]
@@ -946,7 +947,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
946947
context,
947948
(place, span),
948949
(Deep, Write(WriteKind::Move)),
949-
LocalMutationIsAllowed::Yes,
950+
LocalMutationIsAllowed::Move,
950951
flow_state,
951952
);
952953

@@ -1368,7 +1369,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13681369
let local = &self.mir.local_decls[local];
13691370
match local.mutability {
13701371
Mutability::Not => match is_local_mutation_allowed {
1371-
LocalMutationIsAllowed::Yes => Ok(()),
1372+
LocalMutationIsAllowed::Yes |
1373+
LocalMutationIsAllowed::Move => Ok(()),
13721374
LocalMutationIsAllowed::No => Err(place),
13731375
},
13741376
Mutability::Mut => Ok(()),
@@ -1393,10 +1395,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13931395
// Mutably borrowed data is mutable, but only if we have a
13941396
// unique path to the `&mut`
13951397
hir::MutMutable => {
1396-
if self.is_upvar_field_projection(&proj.base).is_some() {
1397-
self.is_mutable(&proj.base, is_local_mutation_allowed)
1398-
} else {
1399-
self.is_unique(&proj.base)
1398+
match self.is_upvar_field_projection(&proj.base) {
1399+
Some(field) if {
1400+
self.mir.upvar_decls[field.index()].by_ref
1401+
} => {
1402+
self.is_mutable(&proj.base,
1403+
is_local_mutation_allowed)
1404+
}
1405+
_ => self.is_unique(&proj.base)
14001406
}
14011407
}
14021408
}
@@ -1412,7 +1418,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
14121418
}
14131419
// `Box<T>` owns its content, so mutable if its location is mutable
14141420
_ if base_ty.is_box() => {
1415-
self.is_mutable(&proj.base, LocalMutationIsAllowed::No)
1421+
self.is_mutable(&proj.base, is_local_mutation_allowed)
14161422
}
14171423
// Deref should only be for reference, pointers or boxes
14181424
_ => bug!("Deref of unexpected type: {:?}", base_ty),
@@ -1429,14 +1435,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
14291435

14301436
if let Some(field) = field_projection {
14311437
let decl = &self.mir.upvar_decls[field.index()];
1432-
1433-
return match decl.mutability {
1434-
Mutability::Mut => self.is_unique(&proj.base),
1435-
Mutability::Not => Err(place),
1438+
debug!("decl.mutability={:?} local_mutation_is_allowed={:?} place={:?}",
1439+
decl, is_local_mutation_allowed, place);
1440+
return match (decl.mutability, is_local_mutation_allowed) {
1441+
(Mutability::Not, LocalMutationIsAllowed::No) |
1442+
(Mutability::Not, LocalMutationIsAllowed::Yes) => Err(place),
1443+
(Mutability::Not, LocalMutationIsAllowed::Move) |
1444+
(Mutability::Mut, _) => self.is_unique(&proj.base),
14361445
};
14371446
}
14381447

1439-
self.is_mutable(&proj.base, LocalMutationIsAllowed::No)
1448+
self.is_mutable(&proj.base, is_local_mutation_allowed)
14401449
}
14411450
}
14421451
}
@@ -1450,9 +1459,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
14501459
// Local variables are unique
14511460
Ok(())
14521461
}
1453-
Place::Static(..) => {
1454-
// Static variables are not
1455-
Err(place)
1462+
Place::Static(ref static_) => {
1463+
if !self.tcx.is_static_mut(static_.def_id) {
1464+
Err(place)
1465+
} else {
1466+
Ok(())
1467+
}
14561468
}
14571469
Place::Projection(ref proj) => {
14581470
match proj.elem {

0 commit comments

Comments
 (0)