@@ -110,8 +110,9 @@ export ty_var_id;
110
110
export ty_to_def_id;
111
111
export ty_fn_args;
112
112
export type_constr;
113
- export kind, kind_sendable, kind_copyable, kind_noncopyable;
113
+ export kind, kind_sendable, kind_copyable, kind_noncopyable, kind_const ;
114
114
export kind_can_be_copied, kind_can_be_sent, proto_kind, kind_lteq, type_kind;
115
+ export operators;
115
116
export type_err, terr_vstore_kind;
116
117
export type_err_to_str;
117
118
export type_needs_drop;
@@ -431,7 +432,8 @@ fn param_bounds_to_kind(bounds: param_bounds) -> kind {
431
432
kind = raise_kind( kind, kind_copyable( ) ) ;
432
433
}
433
434
bound_send { kind = raise_kind( kind, kind_send_only( ) ) ; }
434
- _ { }
435
+ bound_const { kind = raise_kind( kind, kind_const( ) ) ; }
436
+ bound_iface( _) { }
435
437
}
436
438
}
437
439
kind
@@ -1266,8 +1268,9 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t,
1266
1268
1267
1269
enum kind { kind_( u32 ) }
1268
1270
1269
- const KIND_MASK_COPY : u32 = 0b00000000000000000000000000000001u32 ;
1270
- const KIND_MASK_SEND : u32 = 0b00000000000000000000000000000010u32 ;
1271
+ const KIND_MASK_COPY : u32 = 0b00000000000000000000000000000001u32 ;
1272
+ const KIND_MASK_SEND : u32 = 0b00000000000000000000000000000010u32 ;
1273
+ const KIND_MASK_CONST : u32 = 0b00000000000000000000000000000100u32 ;
1271
1274
1272
1275
fn kind_noncopyable( ) -> kind {
1273
1276
kind_( 0u32 )
@@ -1285,10 +1288,37 @@ fn kind_send_only() -> kind {
1285
1288
kind_( KIND_MASK_SEND )
1286
1289
}
1287
1290
1291
+ fn kind_const( ) -> kind {
1292
+ kind_( KIND_MASK_CONST )
1293
+ }
1294
+
1288
1295
fn kind_top( ) -> kind {
1289
1296
kind_( 0xffffffffu32 )
1290
1297
}
1291
1298
1299
+ fn remove_const( k: kind, tm: mt) -> kind {
1300
+ if tm. mutbl == ast:: m_mutbl {
1301
+ k - kind_const( )
1302
+ }
1303
+ else {
1304
+ k
1305
+ }
1306
+ }
1307
+
1308
+ impl operators for kind {
1309
+ fn & ( other: kind) -> kind {
1310
+ lower_kind( self , other)
1311
+ }
1312
+
1313
+ fn |( other: kind) -> kind {
1314
+ raise_kind( self , other)
1315
+ }
1316
+
1317
+ fn -( other: kind) -> kind {
1318
+ kind_( * self & !* other)
1319
+ }
1320
+ }
1321
+
1292
1322
// Using these query functons is preferable to direct comparison or matching
1293
1323
// against the kind constants, as we may modify the kind hierarchy in the
1294
1324
// future.
@@ -1306,7 +1336,7 @@ fn proto_kind(p: proto) -> kind {
1306
1336
ast:: proto_block { kind_noncopyable( ) }
1307
1337
ast:: proto_box { kind_copyable( ) }
1308
1338
ast:: proto_uniq { kind_sendable( ) }
1309
- ast:: proto_bare { kind_sendable( ) }
1339
+ ast:: proto_bare { kind_sendable( ) | kind_const ( ) }
1310
1340
}
1311
1341
}
1312
1342
@@ -1345,7 +1375,7 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
1345
1375
let result = alt get( ty) . struct {
1346
1376
// Scalar and unique types are sendable
1347
1377
ty_nil | ty_bot | ty_bool | ty_int( _) | ty_uint( _) | ty_float( _) |
1348
- ty_ptr( _) | ty_str { kind_sendable( ) }
1378
+ ty_ptr( _) | ty_str { kind_sendable( ) | kind_const ( ) }
1349
1379
ty_type { kind_copyable( ) }
1350
1380
ty_fn( f) { proto_kind( f. proto) }
1351
1381
@@ -1356,38 +1386,58 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
1356
1386
1357
1387
// Those with refcounts raise noncopyable to copyable,
1358
1388
// lower sendable to copyable. Therefore just set result to copyable.
1359
- ty_box( _) | ty_iface( _, _) | ty_opaque_box { kind_copyable( ) }
1389
+ ty_box( tm) {
1390
+ if tm. mutbl == ast:: m_mutbl {
1391
+ kind_copyable( )
1392
+ }
1393
+ else {
1394
+ let k = type_kind( cx, tm. ty) ;
1395
+ if kind_lteq( kind_const( ) , k) {
1396
+ kind_copyable( ) | kind_const( )
1397
+ }
1398
+ else { kind_copyable( ) }
1399
+ }
1400
+ }
1401
+ ty_iface( _, _) | ty_opaque_box { kind_copyable( ) }
1360
1402
ty_rptr( _, _) { kind_copyable( ) }
1361
1403
1362
1404
// Unique boxes and vecs have the kind of their contained type.
1363
- ty_vec( tm) | ty_uniq( tm) { type_kind( cx, tm. ty) }
1405
+ ty_vec( tm) | ty_uniq( tm) { remove_const ( type_kind( cx, tm. ty) , tm ) }
1364
1406
1365
1407
// Slice and refcounted evecs are copyable; uniques and interiors
1366
1408
// depend on the their contained type.
1367
- ty_evec( _, vstore_box) |
1368
- ty_evec( _, vstore_slice( _) ) { kind_copyable( ) }
1409
+ ty_evec( tm, vstore_box) |
1410
+ ty_evec( tm, vstore_slice( _) ) {
1411
+ if kind_lteq( kind_const( ) , type_kind( cx, tm. ty) ) {
1412
+ kind_copyable( ) | kind_const( )
1413
+ }
1414
+ else {
1415
+ kind_const( )
1416
+ }
1417
+ }
1369
1418
ty_evec( tm, vstore_uniq) |
1370
- ty_evec( tm, vstore_fixed( _) ) { type_kind( cx, tm. ty) }
1419
+ ty_evec( tm, vstore_fixed( _) ) { remove_const ( type_kind( cx, tm. ty) , tm ) }
1371
1420
1372
1421
// All estrs are copyable; uniques and interiors are sendable.
1373
1422
ty_estr( vstore_box) |
1374
- ty_estr( vstore_slice( _) ) { kind_copyable( ) }
1423
+ ty_estr( vstore_slice( _) ) { kind_copyable( ) | kind_const ( ) }
1375
1424
ty_estr( vstore_uniq) |
1376
- ty_estr( vstore_fixed( _) ) { kind_sendable( ) }
1425
+ ty_estr( vstore_fixed( _) ) { kind_sendable( ) | kind_const ( ) }
1377
1426
1378
1427
// Records lower to the lowest of their members.
1379
1428
ty_rec( flds) {
1380
- let mut lowest = kind_sendable ( ) ;
1429
+ let mut lowest = kind_top ( ) ;
1381
1430
for flds. each { |f|
1382
1431
lowest = lower_kind( lowest, type_kind( cx, f. mt. ty) ) ;
1432
+ lowest = remove_const( lowest, f. mt) ;
1383
1433
}
1384
1434
lowest
1385
1435
}
1386
1436
// FIXME: (tjc) there are rules about when classes are copyable/
1387
1437
// sendable, but I'm just treating them like records (#1726)
1388
1438
ty_class( did, substs) {
1389
1439
// also factor out this code, copied from the records case
1390
- let mut lowest = kind_sendable ( ) ;
1440
+ let mut lowest = kind_top ( ) ;
1391
1441
let flds = class_items_as_fields( cx, did, substs) ;
1392
1442
for flds. each { |f|
1393
1443
lowest = lower_kind( lowest, type_kind( cx, f. mt. ty) ) ;
@@ -1396,13 +1446,13 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
1396
1446
}
1397
1447
// Tuples lower to the lowest of their members.
1398
1448
ty_tup( tys) {
1399
- let mut lowest = kind_sendable ( ) ;
1449
+ let mut lowest = kind_top ( ) ;
1400
1450
for tys. each { |ty| lowest = lower_kind( lowest, type_kind( cx, ty) ) ; }
1401
1451
lowest
1402
1452
}
1403
1453
// Enums lower to the lowest of their variants.
1404
1454
ty_enum( did, substs) {
1405
- let mut lowest = kind_sendable ( ) ;
1455
+ let mut lowest = kind_top ( ) ;
1406
1456
let variants = enum_variants( cx, did) ;
1407
1457
if vec:: len( * variants) == 0 u {
1408
1458
lowest = kind_noncopyable( ) ;
@@ -1423,6 +1473,7 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
1423
1473
param_bounds_to_kind( cx. ty_param_bounds. get( did. node) )
1424
1474
}
1425
1475
ty_constr( t, _) { type_kind( cx, t) }
1476
+ // FIXME: is self ever const?
1426
1477
ty_self { kind_noncopyable( ) }
1427
1478
1428
1479
ty_var( _) { cx. sess. bug( "Asked to compute kind of a type variable") ; }
0 commit comments