@@ -655,8 +655,9 @@ enum WriteKind {
655
655
/// - Take flow state into consideration in `is_assignable()` for local variables
656
656
#[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
657
657
enum LocalMutationIsAllowed {
658
+ Move ,
658
659
Yes ,
659
- No ,
660
+ No
660
661
}
661
662
662
663
#[ derive( Copy , Clone ) ]
@@ -946,7 +947,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
946
947
context,
947
948
( place, span) ,
948
949
( Deep , Write ( WriteKind :: Move ) ) ,
949
- LocalMutationIsAllowed :: Yes ,
950
+ LocalMutationIsAllowed :: Move ,
950
951
flow_state,
951
952
) ;
952
953
@@ -1368,7 +1369,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1368
1369
let local = & self . mir . local_decls [ local] ;
1369
1370
match local. mutability {
1370
1371
Mutability :: Not => match is_local_mutation_allowed {
1371
- LocalMutationIsAllowed :: Yes => Ok ( ( ) ) ,
1372
+ LocalMutationIsAllowed :: Yes |
1373
+ LocalMutationIsAllowed :: Move => Ok ( ( ) ) ,
1372
1374
LocalMutationIsAllowed :: No => Err ( place) ,
1373
1375
} ,
1374
1376
Mutability :: Mut => Ok ( ( ) ) ,
@@ -1393,10 +1395,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1393
1395
// Mutably borrowed data is mutable, but only if we have a
1394
1396
// unique path to the `&mut`
1395
1397
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 )
1400
1406
}
1401
1407
}
1402
1408
}
@@ -1412,7 +1418,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1412
1418
}
1413
1419
// `Box<T>` owns its content, so mutable if its location is mutable
1414
1420
_ if base_ty. is_box ( ) => {
1415
- self . is_mutable ( & proj. base , LocalMutationIsAllowed :: No )
1421
+ self . is_mutable ( & proj. base , is_local_mutation_allowed )
1416
1422
}
1417
1423
// Deref should only be for reference, pointers or boxes
1418
1424
_ => bug ! ( "Deref of unexpected type: {:?}" , base_ty) ,
@@ -1429,14 +1435,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1429
1435
1430
1436
if let Some ( field) = field_projection {
1431
1437
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 ) ,
1436
1445
} ;
1437
1446
}
1438
1447
1439
- self . is_mutable ( & proj. base , LocalMutationIsAllowed :: No )
1448
+ self . is_mutable ( & proj. base , is_local_mutation_allowed )
1440
1449
}
1441
1450
}
1442
1451
}
@@ -1450,9 +1459,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1450
1459
// Local variables are unique
1451
1460
Ok ( ( ) )
1452
1461
}
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
+ }
1456
1468
}
1457
1469
Place :: Projection ( ref proj) => {
1458
1470
match proj. elem {
0 commit comments