@@ -2240,3 +2240,64 @@ impl<'a, 'b, 'tcx: 'a + 'b> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'
2240
2240
NestedVisitorMap :: OnlyBodies ( & self . cx . tcx . hir ( ) )
2241
2241
}
2242
2242
}
2243
+
2244
+ /// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code.
2245
+ ///
2246
+ /// **Why is this bad?** It’s basically guaranteed to be undefined behaviour.
2247
+ /// `UnsafeCell` is the only way to obtain aliasable data that is considered
2248
+ /// mutable.
2249
+ ///
2250
+ /// **Known problems:** None.
2251
+ ///
2252
+ /// **Example:**
2253
+ /// ```rust
2254
+ /// fn x(r: &i32) {
2255
+ /// unsafe {
2256
+ /// *(r as *const _ as *mut _) += 1;
2257
+ /// }
2258
+ /// }
2259
+ /// ```
2260
+ ///
2261
+ /// Instead consider using interior mutability types.
2262
+ ///
2263
+ /// ```rust
2264
+ /// fn x(r: &UnsafeCell<i32>) {
2265
+ /// unsafe {
2266
+ /// *r.get() += 1;
2267
+ /// }
2268
+ /// }
2269
+ /// ```
2270
+ declare_clippy_lint ! {
2271
+ pub CAST_REF_TO_MUT ,
2272
+ nursery,
2273
+ "a cast of reference to a mutable pointer"
2274
+ }
2275
+
2276
+ pub struct RefToMut ;
2277
+
2278
+ impl LintPass for RefToMut {
2279
+ fn get_lints ( & self ) -> LintArray {
2280
+ lint_array ! ( CAST_REF_TO_MUT )
2281
+ }
2282
+ }
2283
+
2284
+ impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for RefToMut {
2285
+ fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , expr : & ' tcx Expr ) {
2286
+ if_chain ! {
2287
+ if let ExprKind :: Unary ( UnOp :: UnDeref , e) = & expr. node;
2288
+ if let ExprKind :: Cast ( e, t) = & e. node;
2289
+ if let TyKind :: Ptr ( MutTy { mutbl: Mutability :: MutMutable , .. } ) = t. node;
2290
+ if let ExprKind :: Cast ( e, t) = & e. node;
2291
+ if let TyKind :: Ptr ( MutTy { mutbl: Mutability :: MutImmutable , .. } ) = t. node;
2292
+ if let ty:: TyKind :: Ref ( ..) = cx. tables. node_id_to_type( e. hir_id) . sty;
2293
+ then {
2294
+ span_lint(
2295
+ cx,
2296
+ CAST_REF_TO_MUT ,
2297
+ expr. span,
2298
+ & "casting immutable reference to a mutable reference"
2299
+ ) ;
2300
+ }
2301
+ }
2302
+ }
2303
+ }
0 commit comments