@@ -1251,7 +1251,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1251
1251
let mut error_reported = false ;
1252
1252
match kind {
1253
1253
Write ( WriteKind :: MutableBorrow ( BorrowKind :: Unique ) ) => {
1254
- if let Err ( _place_err) = self . is_unique ( place) {
1254
+ if let Err ( _place_err) = self . is_mutable ( place, LocalMutationIsAllowed :: Yes ) {
1255
1255
span_bug ! ( span, "&unique borrow for {:?} should not fail" , place) ;
1256
1256
}
1257
1257
}
@@ -1358,25 +1358,24 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1358
1358
// Mutably borrowed data is mutable, but only if we have a
1359
1359
// unique path to the `&mut`
1360
1360
hir:: MutMutable => {
1361
- match self . is_upvar_field_projection ( & proj. base ) {
1361
+ let mode = match self . is_upvar_field_projection ( & proj. base ) {
1362
1362
Some ( field) if {
1363
1363
self . mir . upvar_decls [ field. index ( ) ] . by_ref
1364
- } => {
1365
- self . is_mutable ( & proj. base ,
1366
- is_local_mutation_allowed)
1367
- }
1368
- _ => self . is_unique ( & proj. base )
1369
- }
1364
+ } => is_local_mutation_allowed,
1365
+ _ => LocalMutationIsAllowed :: Yes
1366
+ } ;
1367
+
1368
+ self . is_mutable ( & proj. base , mode)
1370
1369
}
1371
1370
}
1372
1371
}
1373
1372
ty:: TyRawPtr ( tnm) => {
1374
1373
match tnm. mutbl {
1375
1374
// `*const` raw pointers are not mutable
1376
- hir:: MutImmutable => Err ( place) ,
1375
+ hir:: MutImmutable => return Err ( place) ,
1377
1376
// `*mut` raw pointers are always mutable, regardless of context
1378
1377
// The users have to check by themselve.
1379
- hir:: MutMutable => Ok ( ( ) ) ,
1378
+ hir:: MutMutable => return Ok ( ( ) ) ,
1380
1379
}
1381
1380
}
1382
1381
// `Box<T>` owns its content, so mutable if its location is mutable
@@ -1394,80 +1393,22 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1394
1393
ProjectionElem :: ConstantIndex { .. } |
1395
1394
ProjectionElem :: Subslice { .. } |
1396
1395
ProjectionElem :: Downcast ( ..) => {
1397
- let field_projection = self . is_upvar_field_projection ( place) ;
1398
-
1399
- if let Some ( field) = field_projection {
1396
+ if let Some ( field) = self . is_upvar_field_projection ( place) {
1400
1397
let decl = & self . mir . upvar_decls [ field. index ( ) ] ;
1401
1398
debug ! ( "decl.mutability={:?} local_mutation_is_allowed={:?} place={:?}" ,
1402
1399
decl, is_local_mutation_allowed, place) ;
1403
- return match ( decl. mutability , is_local_mutation_allowed) {
1400
+ match ( decl. mutability , is_local_mutation_allowed) {
1404
1401
( Mutability :: Not , LocalMutationIsAllowed :: No ) |
1405
1402
( Mutability :: Not , LocalMutationIsAllowed :: ExceptUpvars )
1406
1403
=> Err ( place) ,
1407
1404
( Mutability :: Not , LocalMutationIsAllowed :: Yes ) |
1408
- ( Mutability :: Mut , _) => self . is_unique ( & proj. base ) ,
1409
- } ;
1410
- }
1411
-
1412
- self . is_mutable ( & proj. base , is_local_mutation_allowed)
1413
- }
1414
- }
1415
- }
1416
- }
1417
- }
1418
-
1419
- /// Does this place have a unique path
1420
- fn is_unique < ' d > ( & self , place : & ' d Place < ' tcx > ) -> Result < ( ) , & ' d Place < ' tcx > > {
1421
- match * place {
1422
- Place :: Local ( ..) => {
1423
- // Local variables are unique
1424
- Ok ( ( ) )
1425
- }
1426
- Place :: Static ( ref static_) => {
1427
- if !self . tcx . is_static_mut ( static_. def_id ) {
1428
- Err ( place)
1429
- } else {
1430
- Ok ( ( ) )
1431
- }
1432
- }
1433
- Place :: Projection ( ref proj) => {
1434
- match proj. elem {
1435
- ProjectionElem :: Deref => {
1436
- let base_ty = proj. base . ty ( self . mir , self . tcx ) . to_ty ( self . tcx ) ;
1437
-
1438
- // `Box<T>` referent is unique if box is a unique spot
1439
- if base_ty. is_box ( ) {
1440
- return self . is_unique ( & proj. base ) ;
1441
- }
1442
-
1443
- // Otherwise we check the kind of deref to decide
1444
- match base_ty. sty {
1445
- ty:: TyRef ( _, tnm) => {
1446
- match tnm. mutbl {
1447
- // place represent an aliased location
1448
- hir:: MutImmutable => Err ( place) ,
1449
- // `&mut T` is as unique as the context in which it is found
1450
- hir:: MutMutable => self . is_unique ( & proj. base ) ,
1451
- }
1452
- }
1453
- ty:: TyRawPtr ( tnm) => {
1454
- match tnm. mutbl {
1455
- // `*mut` can be aliased, but we leave it to user
1456
- hir:: MutMutable => Ok ( ( ) ) ,
1457
- // `*const` is treated the same as `*mut`
1458
- hir:: MutImmutable => Ok ( ( ) ) ,
1459
- }
1405
+ ( Mutability :: Mut , _) =>
1406
+ self . is_mutable ( & proj. base , is_local_mutation_allowed)
1460
1407
}
1461
- // Deref should only be for reference, pointers or boxes
1462
- _ => bug ! ( "Deref of unexpected type: {:?}" , base_ty ) ,
1408
+ } else {
1409
+ self . is_mutable ( & proj . base , is_local_mutation_allowed )
1463
1410
}
1464
1411
}
1465
- // Other projections are unique if the base is unique
1466
- ProjectionElem :: Field ( ..) |
1467
- ProjectionElem :: Index ( ..) |
1468
- ProjectionElem :: ConstantIndex { .. } |
1469
- ProjectionElem :: Subslice { .. } |
1470
- ProjectionElem :: Downcast ( ..) => self . is_unique ( & proj. base ) ,
1471
1412
}
1472
1413
}
1473
1414
}
0 commit comments