diff options
| author | Nadrieril <nadrieril+git@gmail.com> | 2023-10-29 04:36:06 +0100 |
|---|---|---|
| committer | Nadrieril <nadrieril+git@gmail.com> | 2023-11-02 03:19:18 +0100 |
| commit | 1f9a2f73e12b0bbfff21f78b220cf742e44e35b7 (patch) | |
| tree | 0825588cff9f66f61181905c714dd5a4df8d1fc6 | |
| parent | fedee8d52405ae1d9526c6ee87a97b3d14b6d4fd (diff) | |
| download | rust-1f9a2f73e12b0bbfff21f78b220cf742e44e35b7.tar.gz rust-1f9a2f73e12b0bbfff21f78b220cf742e44e35b7.zip | |
Uncomplicate check_let_chain
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 80 |
1 files changed, 35 insertions, 45 deletions
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 136f4210fe4..9cae42c4359 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -150,8 +150,8 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> { ExprKind::Let { box ref pat, expr } => { self.check_let(pat, expr, self.let_source, ex.span); } - ExprKind::LogicalOp { op: LogicalOp::And, lhs, rhs } => { - self.check_let_chain(self.let_source, ex.span, lhs, rhs); + ExprKind::LogicalOp { op: LogicalOp::And, .. } => { + self.check_let_chain(self.let_source, ex); } _ => {} }; @@ -326,71 +326,61 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { } #[instrument(level = "trace", skip(self))] - fn check_let_chain( - &mut self, - let_source: LetSource, - top_expr_span: Span, - mut lhs: ExprId, - rhs: ExprId, - ) { + fn check_let_chain(&mut self, let_source: LetSource, expr: &Expr<'tcx>) { if let LetSource::None = let_source { return; } - // Lint level enclosing the next `lhs`. - let mut cur_lint_level = self.lint_level; + let top_expr_span = expr.span; + + // Lint level enclosing `next_expr`. + let mut next_expr_lint_level = self.lint_level; // Obtain the refutabilities of all exprs in the chain, // and record chain members that aren't let exprs. let mut chain_refutabilities = Vec::new(); let mut error = Ok(()); - let mut add = |expr: ExprId, mut local_lint_level| { - // `local_lint_level` is the lint level enclosing the pattern inside `expr`. - let mut expr = &self.thir[expr]; - debug!(?expr, ?local_lint_level, "add"); + let mut next_expr = Some(expr); + while let Some(mut expr) = next_expr { + while let ExprKind::Scope { value, lint_level, .. } = expr.kind { + if let LintLevel::Explicit(hir_id) = lint_level { + next_expr_lint_level = hir_id + } + expr = &self.thir[value]; + } + if let ExprKind::LogicalOp { op: LogicalOp::And, lhs, rhs } = expr.kind { + expr = &self.thir[rhs]; + // Let chains recurse on the left, so we recurse into the lhs. + next_expr = Some(&self.thir[lhs]); + } else { + next_expr = None; + } + + // Lint level enclosing `expr`. + let mut expr_lint_level = next_expr_lint_level; // Fast-forward through scopes. while let ExprKind::Scope { value, lint_level, .. } = expr.kind { if let LintLevel::Explicit(hir_id) = lint_level { - local_lint_level = hir_id + expr_lint_level = hir_id } expr = &self.thir[value]; } - debug!(?expr, ?local_lint_level, "after scopes"); - match expr.kind { + let value = match expr.kind { ExprKind::Let { box ref pat, expr: _ } => { if let Err(err) = pat.pat_error_reported() { error = Err(err); - return None; + None + } else { + let mut ncx = self.new_cx(expr_lint_level, true); + let tpat = self.lower_pattern(&mut ncx, pat); + let refutable = !is_let_irrefutable(&mut ncx, expr_lint_level, tpat); + Some((expr.span, refutable)) } - let mut ncx = self.new_cx(local_lint_level, true); - let tpat = self.lower_pattern(&mut ncx, pat); - let refutable = !is_let_irrefutable(&mut ncx, local_lint_level, tpat); - Some((expr.span, refutable)) } _ => None, - } - }; - - // Let chains recurse on the left, so we start by adding the rightmost. - chain_refutabilities.push(add(rhs, cur_lint_level)); - - loop { - while let ExprKind::Scope { value, lint_level, .. } = self.thir[lhs].kind { - if let LintLevel::Explicit(hir_id) = lint_level { - cur_lint_level = hir_id - } - lhs = value; - } - if let ExprKind::LogicalOp { op: LogicalOp::And, lhs: new_lhs, rhs: expr } = - self.thir[lhs].kind - { - chain_refutabilities.push(add(expr, cur_lint_level)); - lhs = new_lhs; - } else { - chain_refutabilities.push(add(lhs, cur_lint_level)); - break; - } + }; + chain_refutabilities.push(value); } debug!(?chain_refutabilities); chain_refutabilities.reverse(); |
