Introduce DotDotPos.

This shrinks `hir::Pat` from 88 to 72 bytes.
This commit is contained in:
Nicholas Nethercote 2022-09-01 13:29:57 +10:00
parent 977b6e29a3
commit c86a9c077c
6 changed files with 15 additions and 7 deletions

View File

@ -51,7 +51,9 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
false false
}, },
PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)), 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::Ref(x, _) | PatKind::Box(x) => unary_pattern(x),
PatKind::Path(_) | PatKind::Lit(_) => true, PatKind::Path(_) | PatKind::Lit(_) => true,
} }

View File

@ -248,7 +248,7 @@ impl<'a> NormalizedPat<'a> {
} else { } else {
(None, adt.non_enum_variant()) (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), Some(i) => pats.split_at(i),
None => (pats, [].as_slice()), None => (pats, [].as_slice()),
}; };
@ -268,7 +268,7 @@ impl<'a> NormalizedPat<'a> {
ty::Tuple(subs) => subs.len(), ty::Tuple(subs) => subs.len(),
_ => return Self::Wild, _ => return Self::Wild,
}; };
let (front, back) = match wild_idx { let (front, back) = match wild_idx.as_opt_usize() {
Some(i) => pats.split_at(i), Some(i) => pats.split_at(i),
None => (pats, [].as_slice()), None => (pats, [].as_slice()),
}; };

View File

@ -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 // 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 // in the arms, so we need to evaluate the correct offsets here in order to iterate in
// both arms at the same time. // 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( let len = max(
left_in.len() + { left_in.len() + {
if left_pos.is_some() { 1 } else { 0 } if left_pos.is_some() { 1 } else { 0 }

View File

@ -122,7 +122,8 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr:
if_chain! { if_chain! {
if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else }) = higher::IfLet::hir(cx, expr); 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 !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; if let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind;
let caller_ty = cx.typeck_results().expr_ty(let_expr); 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); let if_block = IfBlockType::IfLet(path1, caller_ty, ident.name, let_expr, if_then, if_else);

View File

@ -19,10 +19,12 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
&& cx.typeck_results().pat_ty(local.pat).is_unit() && cx.typeck_results().pat_ty(local.pat).is_unit()
{ {
if (local.ty.map_or(false, |ty| !matches!(ty.kind, TyKind::Infer)) 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) && 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( span_lint_and_then(
cx, cx,
LET_UNIT_VALUE, LET_UNIT_VALUE,

View File

@ -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>> { pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
fn is_ok(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool { fn is_ok(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
if_chain! { 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 is_lang_ctor(cx, path, ResultOk);
if let PatKind::Binding(_, hir_id, _, None) = pat[0].kind; if let PatKind::Binding(_, hir_id, _, None) = pat[0].kind;
if path_to_local_id(arm.body, hir_id); if path_to_local_id(arm.body, hir_id);