@@ -2,10 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
22use clippy_utils:: msrvs:: { self , Msrv } ;
33use clippy_utils:: source:: snippet_with_applicability;
44use clippy_utils:: sugg:: Sugg ;
5- use clippy_utils:: { std_or_core, sym} ;
5+ use clippy_utils:: { get_parent_expr , std_or_core, sym} ;
66use rustc_errors:: Applicability ;
77use rustc_hir:: { self as hir, Expr , ExprKind , QPath } ;
88use rustc_lint:: LateContext ;
9+ use rustc_middle:: ty:: adjustment:: { Adjust , PointerCoercion } ;
910use rustc_middle:: ty:: { self , Ty , TypeVisitableExt } ;
1011
1112use super :: PTR_CAST_CONSTNESS ;
@@ -102,3 +103,25 @@ pub(super) fn check_null_ptr_cast_method(cx: &LateContext<'_>, expr: &Expr<'_>)
102103 ) ;
103104 }
104105}
106+
107+ pub ( super ) fn check_implicit_cast_from_mut ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , msrv : Msrv ) {
108+ if msrv. meets ( cx, msrvs:: POINTER_CAST_CONSTNESS )
109+ && let ty:: RawPtr ( ..) = cx. typeck_results ( ) . expr_ty ( expr) . kind ( )
110+ && !matches ! ( get_parent_expr( cx, expr) . map( |e| e. kind) , Some ( ExprKind :: Cast ( ..) ) )
111+ && let [ coercion] = cx. typeck_results ( ) . expr_adjustments ( expr)
112+ && let Adjust :: Pointer ( PointerCoercion :: MutToConstPointer ) = coercion. kind
113+ && !expr. span . from_expansion ( )
114+ {
115+ let mut app = Applicability :: MachineApplicable ;
116+ let sugg = Sugg :: hir_with_applicability ( cx, expr, "_" , & mut app) ;
117+ span_lint_and_sugg (
118+ cx,
119+ PTR_CAST_CONSTNESS ,
120+ expr. span ,
121+ "implicit casting from mut pointer to const pointer" ,
122+ "try `pointer::cast_const`, a safer alternative" ,
123+ format ! ( "{}.cast_const()" , sugg. maybe_paren( ) ) ,
124+ app,
125+ ) ;
126+ }
127+ }
0 commit comments