@@ -111,7 +111,8 @@ export ty_to_def_id;
111
111
export ty_fn_args;
112
112
export type_constr;
113
113
export kind, kind_sendable, kind_copyable, kind_noncopyable, kind_const;
114
- export kind_can_be_copied, kind_can_be_sent, proto_kind, kind_lteq, type_kind;
114
+ export kind_can_be_copied, kind_can_be_sent, kind_can_be_implicitly_copied;
115
+ export proto_kind, kind_lteq, type_kind;
115
116
export operators;
116
117
export type_err, terr_vstore_kind;
117
118
export type_err_to_str;
@@ -1268,9 +1269,11 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t,
1268
1269
1269
1270
enum kind { kind_( u32 ) }
1270
1271
1271
- const KIND_MASK_COPY : u32 = 0b00000000000000000000000000000001u32 ;
1272
- const KIND_MASK_SEND : u32 = 0b00000000000000000000000000000010u32 ;
1273
- const KIND_MASK_CONST : u32 = 0b00000000000000000000000000000100u32 ;
1272
+ // *ALL* implicity copiable things must be copiable
1273
+ const KIND_MASK_COPY : u32 = 0b00000000000000000000000000000001u32 ;
1274
+ const KIND_MASK_SEND : u32 = 0b00000000000000000000000000000010u32 ;
1275
+ const KIND_MASK_CONST : u32 = 0b00000000000000000000000000000100u32 ;
1276
+ const KIND_MASK_IMPLICIT : u32 = 0b00000000000000000000000000001000u32 ;
1274
1277
1275
1278
fn kind_noncopyable( ) -> kind {
1276
1279
kind_( 0u32 )
@@ -1280,6 +1283,14 @@ fn kind_copyable() -> kind {
1280
1283
kind_( KIND_MASK_COPY )
1281
1284
}
1282
1285
1286
+ fn kind_implicitly_copyable( ) -> kind {
1287
+ kind_( KIND_MASK_IMPLICIT | KIND_MASK_COPY )
1288
+ }
1289
+
1290
+ fn kind_implicitly_sendable( ) -> kind {
1291
+ kind_( KIND_MASK_IMPLICIT | KIND_MASK_COPY | KIND_MASK_SEND )
1292
+ }
1293
+
1283
1294
fn kind_sendable( ) -> kind {
1284
1295
kind_( KIND_MASK_COPY | KIND_MASK_SEND )
1285
1296
}
@@ -1305,6 +1316,10 @@ fn remove_const(k: kind, tm: mt) -> kind {
1305
1316
}
1306
1317
}
1307
1318
1319
+ fn remove_implicit( k: kind) -> kind {
1320
+ k - kind_( KIND_MASK_IMPLICIT )
1321
+ }
1322
+
1308
1323
impl operators for kind {
1309
1324
fn & ( other: kind) -> kind {
1310
1325
lower_kind( self , other)
@@ -1319,9 +1334,13 @@ impl operators for kind {
1319
1334
}
1320
1335
}
1321
1336
1322
- // Using these query functons is preferable to direct comparison or matching
1337
+ // Using these query functions is preferable to direct comparison or matching
1323
1338
// against the kind constants, as we may modify the kind hierarchy in the
1324
1339
// future.
1340
+ pure fn kind_can_be_implicitly_copied( k: kind) -> bool {
1341
+ * k & KIND_MASK_IMPLICIT != 0u32
1342
+ }
1343
+
1325
1344
pure fn kind_can_be_copied( k: kind) -> bool {
1326
1345
* k & KIND_MASK_COPY != 0u32
1327
1346
}
@@ -1334,9 +1353,9 @@ fn proto_kind(p: proto) -> kind {
1334
1353
alt p {
1335
1354
ast:: proto_any { kind_noncopyable( ) }
1336
1355
ast:: proto_block { kind_noncopyable( ) }
1337
- ast:: proto_box { kind_copyable ( ) }
1356
+ ast:: proto_box { kind_implicitly_copyable ( ) }
1338
1357
ast:: proto_uniq { kind_sendable( ) }
1339
- ast:: proto_bare { kind_sendable ( ) | kind_const( ) }
1358
+ ast:: proto_bare { kind_implicitly_sendable ( ) | kind_const( ) }
1340
1359
}
1341
1360
}
1342
1361
@@ -1354,13 +1373,34 @@ fn raise_kind(a: kind, b: kind) -> kind {
1354
1373
1355
1374
#[ test]
1356
1375
fn test_kinds( ) {
1357
- // The kind "lattice" is nocopy <= copy <= send
1376
+ // The kind "lattice" is defined by the subset operation on the
1377
+ // set of permitted operations.
1358
1378
assert kind_lteq( kind_sendable( ) , kind_sendable( ) ) ;
1359
1379
assert kind_lteq( kind_copyable( ) , kind_sendable( ) ) ;
1360
1380
assert kind_lteq( kind_copyable( ) , kind_copyable( ) ) ;
1361
1381
assert kind_lteq( kind_noncopyable( ) , kind_sendable( ) ) ;
1362
1382
assert kind_lteq( kind_noncopyable( ) , kind_copyable( ) ) ;
1363
1383
assert kind_lteq( kind_noncopyable( ) , kind_noncopyable( ) ) ;
1384
+ assert kind_lteq( kind_copyable( ) , kind_implicitly_copyable( ) ) ;
1385
+ assert kind_lteq( kind_copyable( ) , kind_implicitly_sendable( ) ) ;
1386
+ assert kind_lteq( kind_sendable( ) , kind_implicitly_sendable( ) ) ;
1387
+ assert !kind_lteq( kind_sendable( ) , kind_implicitly_copyable( ) ) ;
1388
+ assert !kind_lteq( kind_copyable( ) , kind_send_only( ) ) ;
1389
+ }
1390
+
1391
+ // Return the most permissive kind that a composite object containing a field
1392
+ // with the given mutability can have.
1393
+ // This is used to prevent objects containing mutable state from being
1394
+ // implicitly copied.
1395
+ fn mutability_kind( m: mutability) -> kind {
1396
+ alt ( m) {
1397
+ m_mutbl | m_const { remove_implicit( kind_top( ) ) }
1398
+ m_imm { kind_top( ) }
1399
+ }
1400
+ }
1401
+
1402
+ fn mutable_type_kind( cx: ctxt, ty: mt) -> kind {
1403
+ lower_kind( mutability_kind( ty. mutbl) , type_kind( cx, ty. ty) )
1364
1404
}
1365
1405
1366
1406
fn type_kind( cx: ctxt, ty: t) -> kind {
@@ -1370,79 +1410,88 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
1370
1410
}
1371
1411
1372
1412
// Insert a default in case we loop back on self recursively.
1373
- cx. kind_cache. insert( ty, kind_sendable ( ) ) ;
1413
+ cx. kind_cache. insert( ty, kind_top ( ) ) ;
1374
1414
1375
1415
let result = alt get( ty) . struct {
1376
1416
// Scalar and unique types are sendable
1377
1417
ty_nil | ty_bot | ty_bool | ty_int( _) | ty_uint( _) | ty_float( _) |
1378
- ty_ptr( _) | ty_str { kind_sendable( ) | kind_const( ) }
1418
+ ty_ptr( _) { kind_implicitly_sendable( ) | kind_const( ) }
1419
+ // FIXME: this *shouldn't* be implicitly copyable (#2450)
1420
+ ty_str { kind_implicitly_sendable( ) | kind_const( ) }
1379
1421
ty_type { kind_copyable( ) }
1380
1422
ty_fn( f) { proto_kind( f. proto) }
1381
1423
1382
1424
// Closures have kind determined by capture mode
1383
1425
ty_opaque_closure_ptr( ck_block) { kind_noncopyable( ) }
1384
- ty_opaque_closure_ptr( ck_box) { kind_copyable ( ) }
1426
+ ty_opaque_closure_ptr( ck_box) { kind_implicitly_copyable ( ) }
1385
1427
ty_opaque_closure_ptr( ck_uniq) { kind_sendable( ) }
1386
1428
1387
1429
// Those with refcounts raise noncopyable to copyable,
1388
1430
// lower sendable to copyable. Therefore just set result to copyable.
1389
1431
ty_box( tm) {
1390
1432
if tm. mutbl == ast:: m_mutbl {
1391
- kind_copyable ( )
1433
+ kind_implicitly_copyable ( )
1392
1434
}
1393
1435
else {
1394
1436
let k = type_kind( cx, tm. ty) ;
1395
1437
if kind_lteq( kind_const( ) , k) {
1396
- kind_copyable ( ) | kind_const( )
1438
+ kind_implicitly_copyable ( ) | kind_const( )
1397
1439
}
1398
- else { kind_copyable ( ) }
1440
+ else { kind_implicitly_copyable ( ) }
1399
1441
}
1400
1442
}
1401
- ty_iface( _, _) | ty_opaque_box { kind_copyable ( ) }
1402
- ty_rptr( _, _) { kind_copyable ( ) }
1443
+ ty_iface( _, _) | ty_opaque_box { kind_implicitly_copyable ( ) }
1444
+ ty_rptr( _, _) { kind_implicitly_copyable ( ) }
1403
1445
1404
- // Unique boxes and vecs have the kind of their contained type.
1405
- ty_vec( tm) | ty_uniq( tm) { remove_const( type_kind( cx, tm. ty) , tm) }
1446
+ // Unique boxes and vecs have the kind of their contained type,
1447
+ // but unique boxes can't be implicitly copyable.
1448
+ ty_uniq( tm) {
1449
+ remove_implicit( remove_const( type_kind( cx, tm. ty) , tm) )
1450
+ }
1451
+ // FIXME: Vectors *shouldn't* be implicitly copyable but are (#2450)
1452
+ ty_vec( tm) { remove_const( mutable_type_kind( cx, tm) , tm) }
1406
1453
1407
1454
// Slice and refcounted evecs are copyable; uniques and interiors
1408
- // depend on the their contained type.
1455
+ // depend on the their contained type, but aren't implicitly copyable .
1409
1456
ty_evec( tm, vstore_box) |
1410
1457
ty_evec( tm, vstore_slice( _) ) {
1411
1458
if kind_lteq( kind_const( ) , type_kind( cx, tm. ty) ) {
1412
- kind_copyable ( ) | kind_const( )
1459
+ kind_implicitly_copyable ( ) | kind_const( )
1413
1460
}
1414
1461
else {
1415
- kind_const ( )
1462
+ kind_implicitly_copyable ( )
1416
1463
}
1417
1464
}
1418
1465
ty_evec( tm, vstore_uniq) |
1419
- ty_evec( tm, vstore_fixed( _) ) { remove_const( type_kind( cx, tm. ty) , tm) }
1466
+ ty_evec( tm, vstore_fixed( _) ) {
1467
+ remove_implicit( remove_const( type_kind( cx, tm. ty) , tm) )
1468
+ }
1420
1469
1421
1470
// All estrs are copyable; uniques and interiors are sendable.
1422
1471
ty_estr( vstore_box) |
1423
- ty_estr( vstore_slice( _) ) { kind_copyable ( ) | kind_const( ) }
1472
+ ty_estr( vstore_slice( _) ) { kind_implicitly_copyable ( ) | kind_const( ) }
1424
1473
ty_estr( vstore_uniq) |
1425
1474
ty_estr( vstore_fixed( _) ) { kind_sendable( ) | kind_const( ) }
1426
1475
1427
1476
// Records lower to the lowest of their members.
1428
1477
ty_rec( flds) {
1429
1478
let mut lowest = kind_top( ) ;
1430
1479
for flds. each { |f|
1431
- lowest = lower_kind( lowest, type_kind ( cx, f. mt. ty ) ) ;
1480
+ lowest = lower_kind( lowest, mutable_type_kind ( cx, f. mt) ) ;
1432
1481
lowest = remove_const( lowest, f. mt) ;
1433
1482
}
1434
1483
lowest
1435
1484
}
1436
1485
// FIXME: (tjc) there are rules about when classes are copyable/
1437
1486
// sendable, but I'm just treating them like records (#1726)
1438
1487
ty_class( did, substs) {
1439
- // also factor out this code, copied from the records case
1440
- let mut lowest = kind_top( ) ;
1441
- let flds = class_items_as_fields( cx, did, substs) ;
1442
- for flds. each { |f|
1443
- lowest = lower_kind( lowest, type_kind ( cx, f. mt. ty ) ) ;
1444
- }
1445
- lowest
1488
+ // also factor out this code, copied from the records case
1489
+ let mut lowest = kind_top( ) ;
1490
+ let flds = class_items_as_fields( cx, did, substs) ;
1491
+ for flds. each { |f|
1492
+ lowest = lower_kind( lowest, mutable_type_kind ( cx, f. mt) ) ;
1493
+ }
1494
+ lowest
1446
1495
}
1447
1496
// Tuples lower to the lowest of their members.
1448
1497
ty_tup( tys) {
@@ -1470,7 +1519,10 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
1470
1519
}
1471
1520
ty_res( did, inner, tps) { kind_send_only( ) }
1472
1521
ty_param( _, did) {
1473
- param_bounds_to_kind( cx. ty_param_bounds. get( did. node) )
1522
+ // FIXME: type params shouldn't be implicitly copyable (#2449)
1523
+ let k = param_bounds_to_kind( cx. ty_param_bounds. get( did. node) ) ;
1524
+ if kind_can_be_copied( k)
1525
+ { raise_kind( k, kind_implicitly_copyable( ) ) } else { k }
1474
1526
}
1475
1527
ty_constr( t, _) { type_kind( cx, t) }
1476
1528
// FIXME: is self ever const?
0 commit comments