@@ -1297,102 +1297,172 @@ impl LateLintPass for UnionsWithDropFields {
1297
1297
}
1298
1298
}
1299
1299
1300
- /// Lint for unions that contain fields with possibly non-trivial destructors.
1300
+ /// Lints for non-portable integer conversions.
1301
+ pub struct NonPortable1632 ;
1301
1302
pub struct NonPortable3264 ;
1303
+ pub struct NonPortable64128 ;
1302
1304
1305
+ declare_lint ! {
1306
+ NONPORTABLE_16_32 ,
1307
+ Allow ,
1308
+ "conversions not portable between 32-bit and 16-bit platforms"
1309
+ }
1303
1310
declare_lint ! {
1304
1311
NONPORTABLE_32_64 ,
1305
1312
Warn ,
1306
1313
"conversions not portable between 64-bit and 32-bit platforms"
1307
1314
}
1315
+ declare_lint ! {
1316
+ NONPORTABLE_64_128 ,
1317
+ Allow ,
1318
+ "conversions not portable between 64-bit and 128-bit platforms"
1319
+ }
1308
1320
1321
+ impl LintPass for NonPortable1632 {
1322
+ fn get_lints ( & self ) -> LintArray {
1323
+ lint_array ! ( NONPORTABLE_16_32 )
1324
+ }
1325
+ }
1309
1326
impl LintPass for NonPortable3264 {
1310
1327
fn get_lints ( & self ) -> LintArray {
1311
1328
lint_array ! ( NONPORTABLE_32_64 )
1312
1329
}
1313
1330
}
1331
+ impl LintPass for NonPortable64128 {
1332
+ fn get_lints ( & self ) -> LintArray {
1333
+ lint_array ! ( NONPORTABLE_64_128 )
1334
+ }
1335
+ }
1314
1336
1315
- fn is_nonportable_conv ( src : subst :: Kind , dst : subst :: Kind ) -> bool {
1316
- match ( src . as_type ( ) , dst . as_type ( ) ) {
1317
- ( Some ( src ) , Some ( dst ) ) => {
1318
- use syntax:: ast:: IntTy :: * ;
1319
- use syntax :: ast :: UintTy :: * ;
1320
- match ( & src. sty , & dst. sty ) {
1321
- // All conditional impls from libcore/num/mod.rs
1322
- // not including "32" and "64" at the same time.
1323
- ( & TyUint ( U64 ) , & TyUint ( Us ) ) |
1324
- ( & TyUint ( Us ) , & TyUint ( U16 ) ) |
1325
- ( & TyUint ( Us ) , & TyUint ( U32 ) ) |
1326
- ( & TyInt ( I64 ) , & TyInt ( Is ) ) |
1327
- ( & TyInt ( Is ) , & TyInt ( I16 ) ) |
1328
- ( & TyInt ( Is ) , & TyInt ( I32 ) ) |
1329
- ( & TyUint ( U32 ) , & TyInt ( Is ) ) |
1330
- ( & TyUint ( Us ) , & TyInt ( I32 ) ) |
1331
- ( & TyUint ( Us ) , & TyInt ( I64 ) ) => true ,
1332
- _ => false ,
1333
- }
1337
+ mod pred {
1338
+ use super :: * ;
1339
+ use syntax :: ast :: IntTy :: * ;
1340
+ use syntax:: ast:: UintTy :: * ;
1341
+
1342
+ pub fn is_nonportable_conv_32_64 ( src : & ty :: TypeVariants , dst : & ty :: TypeVariants ) -> bool {
1343
+ match ( src , dst ) {
1344
+ // All conditional impls from libcore/num/mod.rs
1345
+ // not including "32" and "64" at the same time.
1346
+ ( & TyUint ( U64 ) , & TyUint ( Us ) ) |
1347
+ ( & TyUint ( Us ) , & TyUint ( U16 ) ) |
1348
+ ( & TyUint ( Us ) , & TyUint ( U32 ) ) |
1349
+ ( & TyInt ( I64 ) , & TyInt ( Is ) ) |
1350
+ ( & TyInt ( Is ) , & TyInt ( I16 ) ) |
1351
+ ( & TyInt ( Is ) , & TyInt ( I32 ) ) |
1352
+ ( & TyUint ( U32 ) , & TyInt ( Is ) ) |
1353
+ ( & TyUint ( Us ) , & TyInt ( I32 ) ) |
1354
+ ( & TyUint ( Us ) , & TyInt ( I64 ) ) => true ,
1355
+ _ => false ,
1334
1356
}
1357
+ }
1358
+
1359
+ pub fn is_nonportable_conv_16_32 ( src : & ty:: TypeVariants , dst : & ty:: TypeVariants ) -> bool {
1360
+ match ( src, dst) {
1361
+ // All conditional impls from libcore/num/mod.rs
1362
+ // not including "16" and "32" at the same time.
1363
+ ( & TyUint ( U32 ) , & TyUint ( Us ) ) |
1364
+ ( & TyUint ( Us ) , & TyUint ( U16 ) ) |
1365
+ ( & TyInt ( I32 ) , & TyInt ( Is ) ) |
1366
+ ( & TyInt ( Is ) , & TyInt ( I16 ) ) |
1367
+ ( & TyUint ( U16 ) , & TyInt ( Is ) ) |
1368
+ ( & TyUint ( Us ) , & TyInt ( I32 ) ) => true ,
1369
+ _ => false ,
1370
+ }
1371
+ }
1372
+
1373
+ pub fn is_nonportable_conv_64_128 ( src : & ty:: TypeVariants , dst : & ty:: TypeVariants ) -> bool {
1374
+ match ( src, dst) {
1375
+ // All conditional impls from libcore/num/mod.rs
1376
+ // not including "64" and potentially "128" at the same time.
1377
+ ( & TyUint ( Us ) , & TyUint ( U64 ) ) |
1378
+ ( & TyInt ( Is ) , & TyInt ( I64 ) ) => true ,
1379
+ _ => false ,
1380
+ }
1381
+ }
1382
+ }
1383
+
1384
+ fn is_nonportable_conv < Pred > ( src : subst:: Kind , dst : subst:: Kind , pred : Pred ) -> bool
1385
+ where Pred : Fn ( & ty:: TypeVariants , & ty:: TypeVariants ) -> bool
1386
+ {
1387
+ match ( src. as_type ( ) , dst. as_type ( ) ) {
1388
+ ( Some ( src) , Some ( dst) ) => pred ( & src. sty , & dst. sty ) ,
1335
1389
_ => false ,
1336
1390
}
1337
1391
}
1338
1392
1339
- impl LateLintPass for NonPortable3264 {
1340
- fn check_expr ( & mut self , cx : & LateContext , e : & hir:: Expr ) {
1341
- let tcx = cx. tcx ;
1342
- let report_lint = |span, src : subst:: Kind , dst : subst:: Kind | {
1343
- let src_ty = src. as_type ( ) . unwrap ( ) ;
1344
- let dst_ty = dst. as_type ( ) . unwrap ( ) ;
1345
- cx. span_lint ( NONPORTABLE_32_64 , span,
1346
- & format ! ( "conversion `{}` -> `{}` is not portable \
1347
- between 64-bit and 32-bit platforms", src_ty, dst_ty) ) ;
1348
- } ;
1349
- match e. node {
1350
- hir:: ExprMethodCall ( name, ..) => {
1351
- if name. node . as_str ( ) == "into" {
1352
- if let Some ( callee) = tcx. tables . borrow ( ) . method_map
1353
- . get ( & ty:: MethodCall :: expr ( e. id ) ) . cloned ( ) {
1354
- if let ty:: TyFnDef ( def_id, substs, _) = callee. ty . sty {
1355
- let ti = tcx. impl_or_trait_item ( def_id) ;
1356
- if let ty:: TraitContainer ( trait_def_id) = ti. container ( ) {
1357
- if substs. len ( ) == 2 {
1358
- if tcx. item_name ( trait_def_id) . as_str ( ) == "Into" {
1359
- if is_nonportable_conv ( substs[ 0 ] , substs[ 1 ] ) {
1360
- report_lint ( name. span , substs[ 0 ] , substs[ 1 ] ) ;
1361
- }
1393
+ fn nonportable_check_expr < Pred > ( cx : & LateContext , e : & hir:: Expr , w1 : u8 , w2 : u8 ,
1394
+ lint : & ' static Lint , pred : Pred )
1395
+ where Pred : Fn ( & ty:: TypeVariants , & ty:: TypeVariants ) -> bool
1396
+ {
1397
+ let tcx = cx. tcx ;
1398
+ let report_lint = |span, src : subst:: Kind , dst : subst:: Kind | {
1399
+ let src_ty = src. as_type ( ) . unwrap ( ) ;
1400
+ let dst_ty = dst. as_type ( ) . unwrap ( ) ;
1401
+ cx. span_lint ( lint, span,
1402
+ & format ! ( "conversion `{}` -> `{}` is not portable \
1403
+ between {}-bit and {}-bit platforms", src_ty, dst_ty, w1, w2) ) ;
1404
+ } ;
1405
+ match e. node {
1406
+ hir:: ExprMethodCall ( name, ..) => {
1407
+ if name. node . as_str ( ) == "into" {
1408
+ if let Some ( callee) = tcx. tables . borrow ( ) . method_map
1409
+ . get ( & ty:: MethodCall :: expr ( e. id ) ) . cloned ( ) {
1410
+ if let ty:: TyFnDef ( def_id, substs, _) = callee. ty . sty {
1411
+ let ti = tcx. impl_or_trait_item ( def_id) ;
1412
+ if let ty:: TraitContainer ( trait_def_id) = ti. container ( ) {
1413
+ if substs. len ( ) == 2 {
1414
+ if tcx. item_name ( trait_def_id) . as_str ( ) == "Into" {
1415
+ if is_nonportable_conv ( substs[ 0 ] , substs[ 1 ] , pred) {
1416
+ report_lint ( name. span , substs[ 0 ] , substs[ 1 ] ) ;
1362
1417
}
1363
1418
}
1364
1419
}
1365
1420
}
1366
1421
}
1367
1422
}
1368
1423
}
1369
- hir :: ExprPath ( .. ) => {
1370
- if let Def :: Method ( def_id ) = tcx . expect_def ( e . id ) {
1371
- let ti = tcx. impl_or_trait_item ( def_id ) ;
1372
- if let ty :: MethodTraitItem ( ref method ) = ti {
1373
- if let ty:: TraitContainer ( trait_def_id ) = ti. container ( ) {
1374
- let substs = tcx . node_id_item_substs ( e . id ) . substs ;
1375
- if substs . len ( ) == 2 {
1376
- if method . name . as_str ( ) == "into" {
1377
- if tcx . item_name ( trait_def_id ) . as_str ( ) == "Into " {
1378
- if is_nonportable_conv ( substs [ 0 ] , substs [ 1 ] ) {
1379
- report_lint ( e . span , substs[ 0 ] , substs[ 1 ] ) ;
1380
- }
1424
+ }
1425
+ hir :: ExprPath ( .. ) => {
1426
+ if let Def :: Method ( def_id ) = tcx. expect_def ( e . id ) {
1427
+ let ti = tcx . impl_or_trait_item ( def_id ) ;
1428
+ if let ty:: MethodTraitItem ( ref method ) = ti {
1429
+ if let ty :: TraitContainer ( trait_def_id ) = ti . container ( ) {
1430
+ let substs = tcx . node_id_item_substs ( e . id ) . substs ;
1431
+ if substs . len ( ) == 2 {
1432
+ if method . name . as_str ( ) == "into " {
1433
+ if tcx . item_name ( trait_def_id ) . as_str ( ) == "Into" {
1434
+ if is_nonportable_conv ( substs[ 0 ] , substs[ 1 ] , pred ) {
1435
+ report_lint ( e . span , substs [ 0 ] , substs [ 1 ] ) ;
1381
1436
}
1382
1437
}
1383
- if method. name . as_str ( ) == "from" {
1384
- if tcx. item_name ( trait_def_id) . as_str ( ) == "From" {
1385
- if is_nonportable_conv ( substs[ 1 ] , substs[ 0 ] ) {
1386
- report_lint ( e. span , substs[ 1 ] , substs[ 0 ] ) ;
1387
- }
1438
+ } else if method. name . as_str ( ) == "from" {
1439
+ if tcx. item_name ( trait_def_id) . as_str ( ) == "From" {
1440
+ if is_nonportable_conv ( substs[ 1 ] , substs[ 0 ] , pred) {
1441
+ report_lint ( e. span , substs[ 1 ] , substs[ 0 ] ) ;
1388
1442
}
1389
1443
}
1390
1444
}
1391
1445
}
1392
1446
}
1393
1447
}
1394
1448
}
1395
- _ => { }
1396
1449
}
1450
+ _ => { }
1451
+ }
1452
+ }
1453
+
1454
+ impl LateLintPass for NonPortable1632 {
1455
+ fn check_expr ( & mut self , cx : & LateContext , e : & hir:: Expr ) {
1456
+ nonportable_check_expr ( cx, e, 32 , 16 , NONPORTABLE_16_32 , pred:: is_nonportable_conv_16_32)
1457
+ }
1458
+ }
1459
+ impl LateLintPass for NonPortable3264 {
1460
+ fn check_expr ( & mut self , cx : & LateContext , e : & hir:: Expr ) {
1461
+ nonportable_check_expr ( cx, e, 64 , 32 , NONPORTABLE_32_64 , pred:: is_nonportable_conv_32_64)
1462
+ }
1463
+ }
1464
+ impl LateLintPass for NonPortable64128 {
1465
+ fn check_expr ( & mut self , cx : & LateContext , e : & hir:: Expr ) {
1466
+ nonportable_check_expr ( cx, e, 64 , 128 , NONPORTABLE_64_128 , pred:: is_nonportable_conv_64_128)
1397
1467
}
1398
1468
}
0 commit comments