@@ -2,6 +2,7 @@ mod cast_lossless;
22mod cast_possible_truncation;
33mod cast_possible_wrap;
44mod cast_precision_loss;
5+ mod cast_ptr_alignment;
56mod cast_sign_loss;
67mod fn_to_numeric_cast;
78mod fn_to_numeric_cast_with_truncation;
@@ -13,22 +14,18 @@ use std::borrow::Cow;
1314use if_chain:: if_chain;
1415use rustc_ast:: LitKind ;
1516use rustc_errors:: Applicability ;
16- use rustc_hir:: { Expr , ExprKind , GenericArg , MutTy , Mutability , TyKind , UnOp } ;
17+ use rustc_hir:: { Expr , ExprKind , MutTy , Mutability , TyKind , UnOp } ;
1718use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
1819use rustc_middle:: lint:: in_external_macro;
19- use rustc_middle:: ty:: { self , Ty , TypeAndMut , UintTy } ;
20+ use rustc_middle:: ty:: { self , TypeAndMut , UintTy } ;
2021use rustc_semver:: RustcVersion ;
2122use rustc_session:: { declare_lint_pass, declare_tool_lint, impl_lint_pass} ;
22- use rustc_span:: symbol:: sym;
23- use rustc_target:: abi:: LayoutOf ;
2423
2524use crate :: utils:: sugg:: Sugg ;
2625use crate :: utils:: {
2726 is_hir_ty_cfg_dependant, meets_msrv, snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then,
2827} ;
2928
30- use utils:: int_ty_to_nbits;
31-
3229declare_clippy_lint ! {
3330 /// **What it does:** Checks for casts from any numerical to a float type where
3431 /// the receiving type cannot store all values from the original type without
@@ -270,22 +267,6 @@ declare_lint_pass!(Casts => [
270267 FN_TO_NUMERIC_CAST_WITH_TRUNCATION ,
271268] ) ;
272269
273- /// Check if the given type is either `core::ffi::c_void` or
274- /// one of the platform specific `libc::<platform>::c_void` of libc.
275- fn is_c_void ( cx : & LateContext < ' _ > , ty : Ty < ' _ > ) -> bool {
276- if let ty:: Adt ( adt, _) = ty. kind ( ) {
277- let names = cx. get_def_path ( adt. did ) ;
278-
279- if names. is_empty ( ) {
280- return false ;
281- }
282- if names[ 0 ] == sym:: libc || names[ 0 ] == sym:: core && * names. last ( ) . unwrap ( ) == sym ! ( c_void) {
283- return true ;
284- }
285- }
286- false
287- }
288-
289270impl < ' tcx > LateLintPass < ' tcx > for Casts {
290271 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
291272 if expr. span . from_expansion ( ) {
@@ -306,56 +287,16 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
306287
307288 fn_to_numeric_cast:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
308289 fn_to_numeric_cast_with_truncation:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
309- lint_cast_ptr_alignment ( cx, expr, cast_from, cast_to) ;
310290 if cast_from. is_numeric ( ) && cast_to. is_numeric ( ) && !in_external_macro ( cx. sess ( ) , expr. span ) {
311291 cast_possible_truncation:: check ( cx, expr, cast_from, cast_to) ;
312292 cast_possible_wrap:: check ( cx, expr, cast_from, cast_to) ;
313293 cast_precision_loss:: check ( cx, expr, cast_from, cast_to) ;
314294 cast_lossless:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
315295 cast_sign_loss:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
316296 }
317- } else if let ExprKind :: MethodCall ( method_path, _, args, _) = expr. kind {
318- if_chain ! {
319- if method_path. ident. name == sym!( cast) ;
320- if let Some ( generic_args) = method_path. args;
321- if let [ GenericArg :: Type ( cast_to) ] = generic_args. args;
322- // There probably is no obvious reason to do this, just to be consistent with `as` cases.
323- if !is_hir_ty_cfg_dependant( cx, cast_to) ;
324- then {
325- let ( cast_from, cast_to) =
326- ( cx. typeck_results( ) . expr_ty( & args[ 0 ] ) , cx. typeck_results( ) . expr_ty( expr) ) ;
327- lint_cast_ptr_alignment( cx, expr, cast_from, cast_to) ;
328- }
329- }
330297 }
331- }
332- }
333298
334- fn lint_cast_ptr_alignment < ' tcx > ( cx : & LateContext < ' tcx > , expr : & Expr < ' _ > , cast_from : Ty < ' tcx > , cast_to : Ty < ' tcx > ) {
335- if_chain ! {
336- if let ty:: RawPtr ( from_ptr_ty) = & cast_from. kind( ) ;
337- if let ty:: RawPtr ( to_ptr_ty) = & cast_to. kind( ) ;
338- if let Ok ( from_layout) = cx. layout_of( from_ptr_ty. ty) ;
339- if let Ok ( to_layout) = cx. layout_of( to_ptr_ty. ty) ;
340- if from_layout. align. abi < to_layout. align. abi;
341- // with c_void, we inherently need to trust the user
342- if !is_c_void( cx, from_ptr_ty. ty) ;
343- // when casting from a ZST, we don't know enough to properly lint
344- if !from_layout. is_zst( ) ;
345- then {
346- span_lint(
347- cx,
348- CAST_PTR_ALIGNMENT ,
349- expr. span,
350- & format!(
351- "casting from `{}` to a more-strictly-aligned pointer (`{}`) ({} < {} bytes)" ,
352- cast_from,
353- cast_to,
354- from_layout. align. abi. bytes( ) ,
355- to_layout. align. abi. bytes( ) ,
356- ) ,
357- ) ;
358- }
299+ cast_ptr_alignment:: check ( cx, expr) ;
359300 }
360301}
361302
0 commit comments