Move cast_ref_to_mut to its own module

This commit is contained in:
Yoshitomo Nakanishi 2021-03-09 17:22:21 +09:00
parent ebd1ec0e40
commit f33bb3d900
3 changed files with 72 additions and 64 deletions

View File

@ -0,0 +1,28 @@
use rustc_hir::{Expr, ExprKind, MutTy, Mutability, TyKind, UnOp};
use rustc_lint::LateContext;
use rustc_middle::ty;
use if_chain::if_chain;
use crate::utils::span_lint;
use super::CAST_REF_TO_MUT;
pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if_chain! {
if let ExprKind::Unary(UnOp::Deref, e) = &expr.kind;
if let ExprKind::Cast(e, t) = &e.kind;
if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind;
if let ExprKind::Cast(e, t) = &e.kind;
if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind;
if let ty::Ref(..) = cx.typeck_results().node_type(e.hir_id).kind();
then {
span_lint(
cx,
CAST_REF_TO_MUT,
expr.span,
"casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`",
);
}
}
}

View File

@ -3,6 +3,7 @@
mod cast_possible_wrap;
mod cast_precision_loss;
mod cast_ptr_alignment;
mod cast_ref_to_mut;
mod cast_sign_loss;
mod fn_to_numeric_cast;
mod fn_to_numeric_cast_with_truncation;
@ -14,7 +15,7 @@
use if_chain::if_chain;
use rustc_ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, MutTy, Mutability, TyKind, UnOp};
use rustc_hir::{Expr, ExprKind, Mutability, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, TypeAndMut, UintTy};
@ -23,7 +24,7 @@
use crate::utils::sugg::Sugg;
use crate::utils::{
is_hir_ty_cfg_dependant, meets_msrv, snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then,
is_hir_ty_cfg_dependant, meets_msrv, snippet_with_applicability, span_lint_and_sugg, span_lint_and_then,
};
declare_clippy_lint! {
@ -255,51 +256,6 @@
"casting a function pointer to a numeric type not wide enough to store the address"
}
declare_lint_pass!(Casts => [
CAST_PRECISION_LOSS,
CAST_SIGN_LOSS,
CAST_POSSIBLE_TRUNCATION,
CAST_POSSIBLE_WRAP,
CAST_LOSSLESS,
UNNECESSARY_CAST,
CAST_PTR_ALIGNMENT,
FN_TO_NUMERIC_CAST,
FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
]);
impl<'tcx> LateLintPass<'tcx> for Casts {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if expr.span.from_expansion() {
return;
}
if let ExprKind::Cast(ref cast_expr, cast_to) = expr.kind {
if is_hir_ty_cfg_dependant(cx, cast_to) {
return;
}
let (cast_from, cast_to) = (
cx.typeck_results().expr_ty(cast_expr),
cx.typeck_results().expr_ty(expr),
);
if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) {
return;
}
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
cast_possible_truncation::check(cx, expr, cast_from, cast_to);
cast_possible_wrap::check(cx, expr, cast_from, cast_to);
cast_precision_loss::check(cx, expr, cast_from, cast_to);
cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to);
cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to);
}
}
cast_ptr_alignment::check(cx, expr);
}
}
declare_clippy_lint! {
/// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code.
///
@ -334,26 +290,51 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
"a cast of reference to a mutable pointer"
}
declare_lint_pass!(RefToMut => [CAST_REF_TO_MUT]);
declare_lint_pass!(Casts => [
CAST_PRECISION_LOSS,
CAST_SIGN_LOSS,
CAST_POSSIBLE_TRUNCATION,
CAST_POSSIBLE_WRAP,
CAST_LOSSLESS,
CAST_REF_TO_MUT,
UNNECESSARY_CAST,
CAST_PTR_ALIGNMENT,
FN_TO_NUMERIC_CAST,
FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
]);
impl<'tcx> LateLintPass<'tcx> for RefToMut {
impl<'tcx> LateLintPass<'tcx> for Casts {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if_chain! {
if let ExprKind::Unary(UnOp::Deref, e) = &expr.kind;
if let ExprKind::Cast(e, t) = &e.kind;
if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind;
if let ExprKind::Cast(e, t) = &e.kind;
if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind;
if let ty::Ref(..) = cx.typeck_results().node_type(e.hir_id).kind();
then {
span_lint(
cx,
CAST_REF_TO_MUT,
expr.span,
"casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`",
);
cast_ref_to_mut::check(cx, expr);
if expr.span.from_expansion() {
return;
}
if let ExprKind::Cast(ref cast_expr, cast_to) = expr.kind {
if is_hir_ty_cfg_dependant(cx, cast_to) {
return;
}
let (cast_from, cast_to) = (
cx.typeck_results().expr_ty(cast_expr),
cx.typeck_results().expr_ty(expr),
);
if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) {
return;
}
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
cast_possible_truncation::check(cx, expr, cast_from, cast_to);
cast_possible_wrap::check(cx, expr, cast_from, cast_to);
cast_precision_loss::check(cx, expr, cast_from, cast_to);
cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to);
cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to);
}
}
cast_ptr_alignment::check(cx, expr);
}
}

View File

@ -1176,7 +1176,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|| box slow_vector_initialization::SlowVectorInit);
store.register_late_pass(|| box unnecessary_sort_by::UnnecessarySortBy);
store.register_late_pass(|| box unnecessary_wraps::UnnecessaryWraps);
store.register_late_pass(|| box casts::RefToMut);
store.register_late_pass(|| box assertions_on_constants::AssertionsOnConstants);
store.register_late_pass(|| box transmuting_null::TransmutingNull);
store.register_late_pass(|| box path_buf_push_overwrite::PathBufPushOverwrite);