@@ -8,7 +8,6 @@ use if_chain::if_chain;
88use rustc_ast:: { FloatTy , IntTy , LitFloatType , LitIntType , LitKind , UintTy } ;
99use rustc_errors:: { Applicability , DiagnosticBuilder } ;
1010use rustc_hir as hir;
11- use rustc_hir:: def:: Res ;
1211use rustc_hir:: intravisit:: { walk_body, walk_expr, walk_ty, FnKind , NestedVisitorMap , Visitor } ;
1312use rustc_hir:: {
1413 BinOpKind , Block , Body , Expr , ExprKind , FnDecl , FnRetTy , FnSig , GenericArg , GenericBounds , GenericParamKind , HirId ,
@@ -33,9 +32,9 @@ use crate::consts::{constant, Constant};
3332use crate :: utils:: paths;
3433use crate :: utils:: sugg:: Sugg ;
3534use crate :: utils:: {
36- clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_type_diagnostic_item ,
37- last_path_segment, match_def_path, match_path, meets_msrv, method_chain_args, multispan_sugg ,
38- numeric_literal:: NumericLiteral , qpath_res, reindent_multiline, sext, snippet, snippet_opt,
35+ clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_hir_ty_cfg_dependant ,
36+ is_type_diagnostic_item , last_path_segment, match_def_path, match_path, meets_msrv, method_chain_args,
37+ multispan_sugg , numeric_literal:: NumericLiteral , qpath_res, reindent_multiline, sext, snippet, snippet_opt,
3938 snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg,
4039 span_lint_and_then, unsext,
4140} ;
@@ -1282,8 +1281,8 @@ declare_clippy_lint! {
12821281}
12831282
12841283declare_clippy_lint ! {
1285- /// **What it does:** Checks for casts from a less-strictly-aligned pointer to a
1286- /// more-strictly-aligned pointer
1284+ /// **What it does:** Checks for casts, using `as` or ` pointer::cast`,
1285+ /// from a less-strictly-aligned pointer to a more-strictly-aligned pointer
12871286 ///
12881287 /// **Why is this bad?** Dereferencing the resulting pointer may be undefined
12891288 /// behavior.
@@ -1296,6 +1295,9 @@ declare_clippy_lint! {
12961295 /// ```rust
12971296 /// let _ = (&1u8 as *const u8) as *const u16;
12981297 /// let _ = (&mut 1u8 as *mut u8) as *mut u16;
1298+ ///
1299+ /// (&1u8 as *const u8).cast::<u16>();
1300+ /// (&mut 1u8 as *mut u8).cast::<u16>();
12991301 /// ```
13001302 pub CAST_PTR_ALIGNMENT ,
13011303 pedantic,
@@ -1637,12 +1639,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
16371639 return ;
16381640 }
16391641 if let ExprKind :: Cast ( ref ex, cast_to) = expr. kind {
1640- if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = cast_to. kind {
1641- if let Res :: Def ( _, def_id) = path. res {
1642- if cx. tcx . has_attr ( def_id, sym:: cfg) || cx. tcx . has_attr ( def_id, sym:: cfg_attr) {
1643- return ;
1644- }
1645- }
1642+ if is_hir_ty_cfg_dependant ( cx, cast_to) {
1643+ return ;
16461644 }
16471645 let ( cast_from, cast_to) = ( cx. typeck_results ( ) . expr_ty ( ex) , cx. typeck_results ( ) . expr_ty ( expr) ) ;
16481646 lint_fn_to_numeric_cast ( cx, expr, ex, cast_from, cast_to) ;
@@ -1692,6 +1690,19 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
16921690 }
16931691
16941692 lint_cast_ptr_alignment ( cx, expr, cast_from, cast_to) ;
1693+ } else if let ExprKind :: MethodCall ( method_path, _, args, _) = expr. kind {
1694+ if_chain ! {
1695+ if method_path. ident. name == sym!( cast) ;
1696+ if let Some ( generic_args) = method_path. args;
1697+ if let [ GenericArg :: Type ( cast_to) ] = generic_args. args;
1698+ // There probably is no obvious reason to do this, just to be consistent with `as` cases.
1699+ if !is_hir_ty_cfg_dependant( cx, cast_to) ;
1700+ then {
1701+ let ( cast_from, cast_to) =
1702+ ( cx. typeck_results( ) . expr_ty( & args[ 0 ] ) , cx. typeck_results( ) . expr_ty( expr) ) ;
1703+ lint_cast_ptr_alignment( cx, expr, cast_from, cast_to) ;
1704+ }
1705+ }
16951706 }
16961707 }
16971708}
0 commit comments