Skip to content

Commit e7500b6

Browse files
committed
Extract casting detection logic in it's own function
1 parent 5b8bc56 commit e7500b6

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

compiler/rustc_lint/src/reference_casting.rs

+24-19
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,35 @@ fn is_cast_from_const_to_mut<'tcx>(
111111
cx: &LateContext<'tcx>,
112112
orig_expr: &'tcx Expr<'tcx>,
113113
) -> Option<bool> {
114-
let mut need_check_freeze = false;
115-
let mut e = orig_expr;
116-
117114
let end_ty = cx.typeck_results().node_type(orig_expr.hir_id);
118115

119116
// Bail out early if the end type is **not** a mutable pointer.
120117
if !matches!(end_ty.kind(), ty::RawPtr(TypeAndMut { ty: _, mutbl: Mutability::Mut })) {
121118
return None;
122119
}
123120

121+
let (e, need_check_freeze) = peel_casts(cx, orig_expr);
122+
123+
let start_ty = cx.typeck_results().node_type(e.hir_id);
124+
if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() {
125+
// If an UnsafeCell method is involved we need to additionally check the
126+
// inner type for the presence of the Freeze trait (ie does NOT contain
127+
// an UnsafeCell), since in that case we would incorrectly lint on valid casts.
128+
//
129+
// We also consider non concrete skeleton types (ie generics)
130+
// to be an issue since there is no way to make it safe for abitrary types.
131+
let inner_ty_has_interior_mutability =
132+
!inner_ty.is_freeze(cx.tcx, cx.param_env) && inner_ty.has_concrete_skeleton();
133+
(!need_check_freeze || !inner_ty_has_interior_mutability)
134+
.then_some(inner_ty_has_interior_mutability)
135+
} else {
136+
None
137+
}
138+
}
139+
140+
fn peel_casts<'tcx>(cx: &LateContext<'tcx>, mut e: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, bool) {
141+
let mut gone_trough_unsafe_cell_raw_get = false;
142+
124143
loop {
125144
e = e.peel_blocks();
126145
// <expr> as ...
@@ -145,27 +164,13 @@ fn is_cast_from_const_to_mut<'tcx>(
145164
)
146165
{
147166
if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) {
148-
need_check_freeze = true;
167+
gone_trough_unsafe_cell_raw_get = true;
149168
}
150169
arg
151170
} else {
152171
break;
153172
};
154173
}
155174

156-
let start_ty = cx.typeck_results().node_type(e.hir_id);
157-
if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() {
158-
// If an UnsafeCell method is involved we need to additionally check the
159-
// inner type for the presence of the Freeze trait (ie does NOT contain
160-
// an UnsafeCell), since in that case we would incorrectly lint on valid casts.
161-
//
162-
// We also consider non concrete skeleton types (ie generics)
163-
// to be an issue since there is no way to make it safe for abitrary types.
164-
let inner_ty_has_interior_mutability =
165-
!inner_ty.is_freeze(cx.tcx, cx.param_env) && inner_ty.has_concrete_skeleton();
166-
(!need_check_freeze || !inner_ty_has_interior_mutability)
167-
.then_some(inner_ty_has_interior_mutability)
168-
} else {
169-
None
170-
}
175+
(e, gone_trough_unsafe_cell_raw_get)
171176
}

0 commit comments

Comments
 (0)