@@ -1159,83 +1159,97 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Casts {
1159
1159
}
1160
1160
}
1161
1161
if cast_from. is_numeric ( ) && cast_to. is_numeric ( ) && !in_external_macro ( cx. sess ( ) , expr. span ) {
1162
- match ( cast_from. is_integral ( ) , cast_to. is_integral ( ) ) {
1163
- ( true , false ) => {
1164
- let from_nbits = int_ty_to_nbits ( cast_from, cx. tcx ) ;
1165
- let to_nbits = if let ty:: Float ( FloatTy :: F32 ) = cast_to. sty {
1166
- 32
1167
- } else {
1168
- 64
1169
- } ;
1170
- if is_isize_or_usize ( cast_from) || from_nbits >= to_nbits {
1171
- span_precision_loss_lint ( cx, expr, cast_from, to_nbits == 64 ) ;
1172
- }
1173
- if from_nbits < to_nbits {
1174
- span_lossless_lint ( cx, expr, ex, cast_from, cast_to) ;
1175
- }
1176
- } ,
1177
- ( false , true ) => {
1178
- span_lint (
1179
- cx,
1180
- CAST_POSSIBLE_TRUNCATION ,
1181
- expr. span ,
1182
- & format ! ( "casting {} to {} may truncate the value" , cast_from, cast_to) ,
1183
- ) ;
1184
- if !cast_to. is_signed ( ) {
1185
- span_lint (
1186
- cx,
1187
- CAST_SIGN_LOSS ,
1188
- expr. span ,
1189
- & format ! ( "casting {} to {} may lose the sign of the value" , cast_from, cast_to) ,
1190
- ) ;
1191
- }
1192
- } ,
1193
- ( true , true ) => {
1194
- check_loss_of_sign ( cx, expr, ex, cast_from, cast_to) ;
1195
- check_truncation_and_wrapping ( cx, expr, cast_from, cast_to) ;
1196
- check_lossless ( cx, expr, ex, cast_from, cast_to) ;
1197
- } ,
1198
- ( false , false ) => {
1199
- if let ( & ty:: Float ( FloatTy :: F64 ) , & ty:: Float ( FloatTy :: F32 ) ) = ( & cast_from. sty , & cast_to. sty ) {
1200
- span_lint (
1201
- cx,
1202
- CAST_POSSIBLE_TRUNCATION ,
1203
- expr. span ,
1204
- "casting f64 to f32 may truncate the value" ,
1205
- ) ;
1206
- }
1207
- if let ( & ty:: Float ( FloatTy :: F32 ) , & ty:: Float ( FloatTy :: F64 ) ) = ( & cast_from. sty , & cast_to. sty ) {
1208
- span_lossless_lint ( cx, expr, ex, cast_from, cast_to) ;
1209
- }
1210
- } ,
1211
- }
1162
+ lint_numeric_casts ( cx, expr, ex, cast_from, cast_to) ;
1212
1163
}
1213
1164
1214
- if_chain ! {
1215
- if let ty:: RawPtr ( from_ptr_ty) = & cast_from. sty;
1216
- if let ty:: RawPtr ( to_ptr_ty) = & cast_to. sty;
1217
- if let Ok ( from_layout) = cx. layout_of( from_ptr_ty. ty) ;
1218
- if let Ok ( to_layout) = cx. layout_of( to_ptr_ty. ty) ;
1219
- if from_layout. align. abi < to_layout. align. abi;
1220
- // with c_void, we inherently need to trust the user
1221
- if !is_c_void( cx, from_ptr_ty. ty) ;
1222
- // when casting from a ZST, we don't know enough to properly lint
1223
- if !from_layout. is_zst( ) ;
1224
- then {
1225
- span_lint(
1226
- cx,
1227
- CAST_PTR_ALIGNMENT ,
1228
- expr. span,
1229
- & format!(
1230
- "casting from `{}` to a more-strictly-aligned pointer (`{}`) ({} < {} bytes)" ,
1231
- cast_from,
1232
- cast_to,
1233
- from_layout. align. abi. bytes( ) ,
1234
- to_layout. align. abi. bytes( ) ,
1235
- ) ,
1236
- ) ;
1237
- }
1165
+ lint_cast_ptr_alignment ( cx, expr, cast_from, cast_to) ;
1166
+ }
1167
+ }
1168
+ }
1169
+
1170
+ fn lint_numeric_casts < ' tcx > (
1171
+ cx : & LateContext < ' _ , ' tcx > ,
1172
+ expr : & Expr ,
1173
+ cast_expr : & Expr ,
1174
+ cast_from : Ty < ' tcx > ,
1175
+ cast_to : Ty < ' tcx > ,
1176
+ ) {
1177
+ match ( cast_from. is_integral ( ) , cast_to. is_integral ( ) ) {
1178
+ ( true , false ) => {
1179
+ let from_nbits = int_ty_to_nbits ( cast_from, cx. tcx ) ;
1180
+ let to_nbits = if let ty:: Float ( FloatTy :: F32 ) = cast_to. sty {
1181
+ 32
1182
+ } else {
1183
+ 64
1184
+ } ;
1185
+ if is_isize_or_usize ( cast_from) || from_nbits >= to_nbits {
1186
+ span_precision_loss_lint ( cx, expr, cast_from, to_nbits == 64 ) ;
1238
1187
}
1188
+ if from_nbits < to_nbits {
1189
+ span_lossless_lint ( cx, expr, cast_expr, cast_from, cast_to) ;
1190
+ }
1191
+ } ,
1192
+ ( false , true ) => {
1193
+ span_lint (
1194
+ cx,
1195
+ CAST_POSSIBLE_TRUNCATION ,
1196
+ expr. span ,
1197
+ & format ! ( "casting {} to {} may truncate the value" , cast_from, cast_to) ,
1198
+ ) ;
1199
+ if !cast_to. is_signed ( ) {
1200
+ span_lint (
1201
+ cx,
1202
+ CAST_SIGN_LOSS ,
1203
+ expr. span ,
1204
+ & format ! ( "casting {} to {} may lose the sign of the value" , cast_from, cast_to) ,
1205
+ ) ;
1206
+ }
1207
+ } ,
1208
+ ( true , true ) => {
1209
+ check_loss_of_sign ( cx, expr, cast_expr, cast_from, cast_to) ;
1210
+ check_truncation_and_wrapping ( cx, expr, cast_from, cast_to) ;
1211
+ check_lossless ( cx, expr, cast_expr, cast_from, cast_to) ;
1212
+ } ,
1213
+ ( false , false ) => {
1214
+ if let ( & ty:: Float ( FloatTy :: F64 ) , & ty:: Float ( FloatTy :: F32 ) ) = ( & cast_from. sty , & cast_to. sty ) {
1215
+ span_lint (
1216
+ cx,
1217
+ CAST_POSSIBLE_TRUNCATION ,
1218
+ expr. span ,
1219
+ "casting f64 to f32 may truncate the value" ,
1220
+ ) ;
1221
+ }
1222
+ if let ( & ty:: Float ( FloatTy :: F32 ) , & ty:: Float ( FloatTy :: F64 ) ) = ( & cast_from. sty , & cast_to. sty ) {
1223
+ span_lossless_lint ( cx, expr, cast_expr, cast_from, cast_to) ;
1224
+ }
1225
+ } ,
1226
+ }
1227
+ }
1228
+
1229
+ fn lint_cast_ptr_alignment < ' tcx > ( cx : & LateContext < ' _ , ' tcx > , expr : & Expr , cast_from : Ty < ' tcx > , cast_to : Ty < ' tcx > ) {
1230
+ if_chain ! {
1231
+ if let ty:: RawPtr ( from_ptr_ty) = & cast_from. sty;
1232
+ if let ty:: RawPtr ( to_ptr_ty) = & cast_to. sty;
1233
+ if let Ok ( from_layout) = cx. layout_of( from_ptr_ty. ty) ;
1234
+ if let Ok ( to_layout) = cx. layout_of( to_ptr_ty. ty) ;
1235
+ if from_layout. align. abi < to_layout. align. abi;
1236
+ // with c_void, we inherently need to trust the user
1237
+ if !is_c_void( cx, from_ptr_ty. ty) ;
1238
+ // when casting from a ZST, we don't know enough to properly lint
1239
+ if !from_layout. is_zst( ) ;
1240
+ then {
1241
+ span_lint(
1242
+ cx,
1243
+ CAST_PTR_ALIGNMENT ,
1244
+ expr. span,
1245
+ & format!(
1246
+ "casting from `{}` to a more-strictly-aligned pointer (`{}`) ({} < {} bytes)" ,
1247
+ cast_from,
1248
+ cast_to,
1249
+ from_layout. align. abi. bytes( ) ,
1250
+ to_layout. align. abi. bytes( ) ,
1251
+ ) ,
1252
+ ) ;
1239
1253
}
1240
1254
}
1241
1255
}
0 commit comments