summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_lint/src/reference_casting.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_lint/src/reference_casting.rs')
-rw-r--r--compiler/rustc_lint/src/reference_casting.rs31
1 files changed, 19 insertions, 12 deletions
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index 39def599b..d44691b5e 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -43,19 +43,19 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
let init = cx.expr_or_init(e);
- let orig_cast = if is_cast_from_const_to_mut(cx, init) {
- if init.span != e.span { Some(init.span) } else { None }
- } else {
+ let Some(ty_has_interior_mutability) = is_cast_from_const_to_mut(cx, init) else {
return;
};
+ let orig_cast = if init.span != e.span { Some(init.span) } else { None };
+ let ty_has_interior_mutability = ty_has_interior_mutability.then_some(());
cx.emit_spanned_lint(
INVALID_REFERENCE_CASTING,
expr.span,
if is_assignment {
- InvalidReferenceCastingDiag::AssignToRef { orig_cast }
+ InvalidReferenceCastingDiag::AssignToRef { orig_cast, ty_has_interior_mutability }
} else {
- InvalidReferenceCastingDiag::BorrowAsMut { orig_cast }
+ InvalidReferenceCastingDiag::BorrowAsMut { orig_cast, ty_has_interior_mutability }
},
);
}
@@ -93,7 +93,10 @@ fn is_operation_we_care_about<'tcx>(
if let ExprKind::Call(path, [arg_ptr, _arg_val]) = e.kind
&& let ExprKind::Path(ref qpath) = path.kind
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
- && matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned))
+ && matches!(
+ cx.tcx.get_diagnostic_name(def_id),
+ Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned)
+ )
{
Some((true, arg_ptr))
} else {
@@ -104,7 +107,10 @@ fn is_operation_we_care_about<'tcx>(
deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e))
}
-fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, orig_expr: &'tcx Expr<'tcx>) -> bool {
+fn is_cast_from_const_to_mut<'tcx>(
+ cx: &LateContext<'tcx>,
+ orig_expr: &'tcx Expr<'tcx>,
+) -> Option<bool> {
let mut need_check_freeze = false;
let mut e = orig_expr;
@@ -112,7 +118,7 @@ fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, orig_expr: &'tcx Expr
// Bail out early if the end type is **not** a mutable pointer.
if !matches!(end_ty.kind(), ty::RawPtr(TypeAndMut { ty: _, mutbl: Mutability::Mut })) {
- return false;
+ return None;
}
loop {
@@ -155,10 +161,11 @@ fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, orig_expr: &'tcx Expr
//
// We also consider non concrete skeleton types (ie generics)
// to be an issue since there is no way to make it safe for abitrary types.
- !need_check_freeze
- || inner_ty.is_freeze(cx.tcx, cx.param_env)
- || !inner_ty.has_concrete_skeleton()
+ let inner_ty_has_interior_mutability =
+ !inner_ty.is_freeze(cx.tcx, cx.param_env) && inner_ty.has_concrete_skeleton();
+ (!need_check_freeze || !inner_ty_has_interior_mutability)
+ .then_some(inner_ty_has_interior_mutability)
} else {
- false
+ None
}
}