Introduce small cache to avoid recomputing the same value twice
This commit is contained in:
parent
915200fbe0
commit
6a8f50e907
@ -42,8 +42,15 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
|||||||
let init = cx.expr_or_init(e);
|
let init = cx.expr_or_init(e);
|
||||||
let orig_cast = if init.span != e.span { Some(init.span) } else { None };
|
let orig_cast = if init.span != e.span { Some(init.span) } else { None };
|
||||||
|
|
||||||
|
// small cache to avoid recomputing needlesly computing peel_casts of init
|
||||||
|
let mut peel_casts = {
|
||||||
|
let mut peel_casts_cache = None;
|
||||||
|
move || *peel_casts_cache.get_or_insert_with(|| peel_casts(cx, init))
|
||||||
|
};
|
||||||
|
|
||||||
if matches!(pat, PatternKind::Borrow { mutbl: Mutability::Mut } | PatternKind::Assign)
|
if matches!(pat, PatternKind::Borrow { mutbl: Mutability::Mut } | PatternKind::Assign)
|
||||||
&& let Some(ty_has_interior_mutability) = is_cast_from_ref_to_mut_ptr(cx, init)
|
&& let Some(ty_has_interior_mutability) =
|
||||||
|
is_cast_from_ref_to_mut_ptr(cx, init, &mut peel_casts)
|
||||||
{
|
{
|
||||||
let ty_has_interior_mutability = ty_has_interior_mutability.then_some(());
|
let ty_has_interior_mutability = ty_has_interior_mutability.then_some(());
|
||||||
|
|
||||||
@ -65,7 +72,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some((from_ty_layout, to_ty_layout, e_alloc)) =
|
if let Some((from_ty_layout, to_ty_layout, e_alloc)) =
|
||||||
is_cast_to_bigger_memory_layout(cx, init)
|
is_cast_to_bigger_memory_layout(cx, init, &mut peel_casts)
|
||||||
{
|
{
|
||||||
cx.emit_span_lint(
|
cx.emit_span_lint(
|
||||||
INVALID_REFERENCE_CASTING,
|
INVALID_REFERENCE_CASTING,
|
||||||
@ -141,6 +148,7 @@ fn ptr_write<'tcx>(
|
|||||||
fn is_cast_from_ref_to_mut_ptr<'tcx>(
|
fn is_cast_from_ref_to_mut_ptr<'tcx>(
|
||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
orig_expr: &'tcx Expr<'tcx>,
|
orig_expr: &'tcx Expr<'tcx>,
|
||||||
|
mut peel_casts: impl FnMut() -> (&'tcx Expr<'tcx>, bool),
|
||||||
) -> Option<bool> {
|
) -> Option<bool> {
|
||||||
let end_ty = cx.typeck_results().node_type(orig_expr.hir_id);
|
let end_ty = cx.typeck_results().node_type(orig_expr.hir_id);
|
||||||
|
|
||||||
@ -149,7 +157,7 @@ fn is_cast_from_ref_to_mut_ptr<'tcx>(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (e, need_check_freeze) = peel_casts(cx, orig_expr);
|
let (e, need_check_freeze) = peel_casts();
|
||||||
|
|
||||||
let start_ty = cx.typeck_results().node_type(e.hir_id);
|
let start_ty = cx.typeck_results().node_type(e.hir_id);
|
||||||
if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() {
|
if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() {
|
||||||
@ -171,6 +179,7 @@ fn is_cast_from_ref_to_mut_ptr<'tcx>(
|
|||||||
fn is_cast_to_bigger_memory_layout<'tcx>(
|
fn is_cast_to_bigger_memory_layout<'tcx>(
|
||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
orig_expr: &'tcx Expr<'tcx>,
|
orig_expr: &'tcx Expr<'tcx>,
|
||||||
|
mut peel_casts: impl FnMut() -> (&'tcx Expr<'tcx>, bool),
|
||||||
) -> Option<(TyAndLayout<'tcx>, TyAndLayout<'tcx>, Expr<'tcx>)> {
|
) -> Option<(TyAndLayout<'tcx>, TyAndLayout<'tcx>, Expr<'tcx>)> {
|
||||||
let end_ty = cx.typeck_results().node_type(orig_expr.hir_id);
|
let end_ty = cx.typeck_results().node_type(orig_expr.hir_id);
|
||||||
|
|
||||||
@ -178,7 +187,7 @@ fn is_cast_to_bigger_memory_layout<'tcx>(
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let (e, _) = peel_casts(cx, orig_expr);
|
let (e, _) = peel_casts();
|
||||||
let start_ty = cx.typeck_results().node_type(e.hir_id);
|
let start_ty = cx.typeck_results().node_type(e.hir_id);
|
||||||
|
|
||||||
let ty::Ref(_, inner_start_ty, _) = start_ty.kind() else {
|
let ty::Ref(_, inner_start_ty, _) = start_ty.kind() else {
|
||||||
|
Loading…
Reference in New Issue
Block a user