From 977b6e29a345ee43acabd2e1a7eb8e454626e2f3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 1 Sep 2022 12:06:48 +1000 Subject: [PATCH 1/2] Arena-allocate `hir::Lifetime`. This shrinks `hir::Ty` from 72 to 48 bytes. `visit_lifetime` is added to the HIR stats collector because these types are now stored in memory on their own, instead of being within other types. --- clippy_utils/src/hir_utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 57448f716d49..ff23ed5fffa3 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -929,7 +929,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } } - pub fn hash_lifetime(&mut self, lifetime: Lifetime) { + pub fn hash_lifetime(&mut self, lifetime: &Lifetime) { std::mem::discriminant(&lifetime.name).hash(&mut self.s); if let LifetimeName::Param(param_id, ref name) = lifetime.name { std::mem::discriminant(name).hash(&mut self.s); From c86a9c077c3b3a8c04166934ec1465920419a2cd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 1 Sep 2022 13:29:57 +1000 Subject: [PATCH 2/2] Introduce `DotDotPos`. This shrinks `hir::Pat` from 88 to 72 bytes. --- clippy_lints/src/equatable_if_let.rs | 4 +++- clippy_lints/src/matches/match_same_arms.rs | 4 ++-- clippy_lints/src/matches/single_match.rs | 2 ++ clippy_lints/src/question_mark.rs | 3 ++- clippy_lints/src/unit_types/let_unit_value.rs | 6 ++++-- clippy_utils/src/lib.rs | 3 ++- 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs index fdfb821ac789..bce49165e5b1 100644 --- a/clippy_lints/src/equatable_if_let.rs +++ b/clippy_lints/src/equatable_if_let.rs @@ -51,7 +51,9 @@ fn unary_pattern(pat: &Pat<'_>) -> bool { false }, PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)), - PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => !etc.is_some() && array_rec(a), + PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => { + !etc.as_opt_usize().is_some() && array_rec(a) + } PatKind::Ref(x, _) | PatKind::Box(x) => unary_pattern(x), PatKind::Path(_) | PatKind::Lit(_) => true, } diff --git a/clippy_lints/src/matches/match_same_arms.rs b/clippy_lints/src/matches/match_same_arms.rs index e32ef9933afe..93874b103b46 100644 --- a/clippy_lints/src/matches/match_same_arms.rs +++ b/clippy_lints/src/matches/match_same_arms.rs @@ -248,7 +248,7 @@ impl<'a> NormalizedPat<'a> { } else { (None, adt.non_enum_variant()) }; - let (front, back) = match wild_idx { + let (front, back) = match wild_idx.as_opt_usize() { Some(i) => pats.split_at(i), None => (pats, [].as_slice()), }; @@ -268,7 +268,7 @@ impl<'a> NormalizedPat<'a> { ty::Tuple(subs) => subs.len(), _ => return Self::Wild, }; - let (front, back) = match wild_idx { + let (front, back) = match wild_idx.as_opt_usize() { Some(i) => pats.split_at(i), None => (pats, [].as_slice()), }; diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs index 95478af45b4b..1bf1c4d10789 100644 --- a/clippy_lints/src/matches/single_match.rs +++ b/clippy_lints/src/matches/single_match.rs @@ -200,6 +200,8 @@ fn form_exhaustive_matches<'a>(cx: &LateContext<'a>, ty: Ty<'a>, left: &Pat<'_>, // We don't actually know the position and the presence of the `..` (dotdot) operator // in the arms, so we need to evaluate the correct offsets here in order to iterate in // both arms at the same time. + let left_pos = left_pos.as_opt_usize(); + let right_pos = right_pos.as_opt_usize(); let len = max( left_in.len() + { if left_pos.is_some() { 1 } else { 0 } diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index f4f1fd336df7..569870ab2b7f 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -122,7 +122,8 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: if_chain! { if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else }) = higher::IfLet::hir(cx, expr); if !is_else_clause(cx.tcx, expr); - if let PatKind::TupleStruct(ref path1, [field], None) = let_pat.kind; + if let PatKind::TupleStruct(ref path1, [field], ddpos) = let_pat.kind; + if ddpos.as_opt_usize().is_none(); if let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind; let caller_ty = cx.typeck_results().expr_ty(let_expr); let if_block = IfBlockType::IfLet(path1, caller_ty, ident.name, let_expr, if_then, if_else); diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs index 35824b03170a..ce9ebad8c89a 100644 --- a/clippy_lints/src/unit_types/let_unit_value.rs +++ b/clippy_lints/src/unit_types/let_unit_value.rs @@ -19,10 +19,12 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) { && cx.typeck_results().pat_ty(local.pat).is_unit() { if (local.ty.map_or(false, |ty| !matches!(ty.kind, TyKind::Infer)) - || matches!(local.pat.kind, PatKind::Tuple([], None))) + || matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none())) && expr_needs_inferred_result(cx, init) { - if !matches!(local.pat.kind, PatKind::Wild | PatKind::Tuple([], None)) { + if !matches!(local.pat.kind, PatKind::Wild) + && !matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none()) + { span_lint_and_then( cx, LET_UNIT_VALUE, diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index b27439cbec27..3cf043f22df5 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1552,7 +1552,8 @@ pub fn iter_input_pats<'tcx>(decl: &FnDecl<'_>, body: &'tcx Body<'_>) -> impl It pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { fn is_ok(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool { if_chain! { - if let PatKind::TupleStruct(ref path, pat, None) = arm.pat.kind; + if let PatKind::TupleStruct(ref path, pat, ddpos) = arm.pat.kind; + if ddpos.as_opt_usize().is_none(); if is_lang_ctor(cx, path, ResultOk); if let PatKind::Binding(_, hir_id, _, None) = pat[0].kind; if path_to_local_id(arm.body, hir_id);