From 6d36d1a835370a01cbee58aba038ea0bd712c82b Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Thu, 29 Jul 2021 16:38:17 +0430 Subject: merge XOR_SWAP with MANUAL_SWAP --- clippy_utils/src/lib.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'clippy_utils') diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 59f878f8b20..e930338270c 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -558,6 +558,54 @@ pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio None } +/// This method will return tuple of projection stack and root of the expression, +/// used in `can_mut_borrow_both`. +/// +/// For example, if `e` represents the `v[0].a.b[x]` +/// this method will return a tuple, composed of a `Vec` +/// containing the `Expr`s for `v[0], v[0].a, v[0].a.b, v[0].a.b[x]` +/// and a `Expr` for root of them, `v` +fn projection_stack<'a, 'hir>(mut e: &'a Expr<'hir>) -> (Vec<&'a Expr<'hir>>, &'a Expr<'hir>) { + let mut result = vec![]; + let root = loop { + match e.kind { + ExprKind::Index(ep, _) | ExprKind::Field(ep, _) => { + result.push(e); + e = ep; + }, + _ => break e, + }; + }; + result.reverse(); + (result, root) +} + +/// Checks if two expressions can be mutably borrowed simultaneously +/// and they aren't dependent on borrowing same thing twice +pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -> bool { + let (s1, r1) = projection_stack(e1); + let (s2, r2) = projection_stack(e2); + if !eq_expr_value(cx, r1, r2) { + return true; + } + for (x1, x2) in s1.iter().zip(s2.iter()) { + match (&x1.kind, &x2.kind) { + (ExprKind::Field(_, i1), ExprKind::Field(_, i2)) => { + if i1 != i2 { + return true; + } + }, + (ExprKind::Index(_, i1), ExprKind::Index(_, i2)) => { + if !eq_expr_value(cx, i1, i2) { + return false; + } + }, + _ => return false, + } + } + false +} + /// Checks if the top level expression can be moved into a closure as is. pub fn can_move_expr_to_closure_no_visit(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, jump_targets: &[HirId]) -> bool { match expr.kind { -- cgit 1.4.1-3-g733a5