Skip to content

Commit dc028f6

Browse files
committed
Calculate LetSource later
1 parent 29bc94f commit dc028f6

File tree

1 file changed

+42
-40
lines changed

1 file changed

+42
-40
lines changed

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+42-40
Original file line numberDiff line numberDiff line change
@@ -118,31 +118,6 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
118118
check_for_bindings_named_same_as_variants(self, pat);
119119
}
120120

121-
fn let_source(&mut self, pat: &'tcx hir::Pat<'tcx>, _expr: &hir::Expr<'_>) -> LetSource {
122-
let hir = self.tcx.hir();
123-
let parent = hir.get_parent_node(pat.hir_id);
124-
let parent_parent = hir.get_parent_node(parent);
125-
let parent_parent_node = hir.get(parent_parent);
126-
127-
let parent_parent_parent = hir.get_parent_node(parent_parent);
128-
let parent_parent_parent_parent = hir.get_parent_node(parent_parent_parent);
129-
let parent_parent_parent_parent_node = hir.get(parent_parent_parent_parent);
130-
131-
if let hir::Node::Expr(hir::Expr {
132-
kind: hir::ExprKind::Loop(_, _, hir::LoopSource::While, _),
133-
..
134-
}) = parent_parent_parent_parent_node
135-
{
136-
LetSource::WhileLet
137-
} else if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::If { .. }, .. }) =
138-
parent_parent_node
139-
{
140-
LetSource::IfLet
141-
} else {
142-
LetSource::GenericLet
143-
}
144-
}
145-
146121
fn lower_pattern<'p>(
147122
&self,
148123
cx: &mut MatchCheckCtxt<'p, 'tcx>,
@@ -172,10 +147,9 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
172147

173148
fn check_let(&mut self, pat: &'tcx hir::Pat<'tcx>, expr: &hir::Expr<'_>, span: Span) {
174149
self.check_patterns(pat);
175-
let ls = self.let_source(pat, expr);
176150
let mut cx = self.new_cx(expr.hir_id);
177151
let tpat = self.lower_pattern(&mut cx, pat, &mut false).0;
178-
check_let_reachability(&mut cx, ls, pat.hir_id, &tpat, span);
152+
check_let_reachability(&mut cx, pat.hir_id, &tpat, span);
179153
}
180154

181155
fn check_match(
@@ -192,13 +166,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
192166
if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
193167
self.check_patterns(pat);
194168
let tpat = self.lower_pattern(&mut cx, pat, &mut false).0;
195-
check_let_reachability(
196-
&mut cx,
197-
LetSource::IfLetGuard,
198-
pat.hir_id,
199-
&tpat,
200-
tpat.span,
201-
);
169+
check_let_reachability(&mut cx, pat.hir_id, &tpat, tpat.span);
202170
}
203171
}
204172

@@ -397,7 +365,7 @@ fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option<
397365
});
398366
}
399367

400-
fn irrefutable_let_pattern(id: HirId, ls: LetSource, span: Span, tcx: TyCtxt<'_>) {
368+
fn irrefutable_let_pattern(tcx: TyCtxt<'_>, id: HirId, span: Span) {
401369
macro_rules! emit_diag {
402370
(
403371
$lint:expr,
@@ -412,7 +380,8 @@ fn irrefutable_let_pattern(id: HirId, ls: LetSource, span: Span, tcx: TyCtxt<'_>
412380
}};
413381
}
414382

415-
tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| match ls {
383+
let source = let_source(tcx, id);
384+
tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| match source {
416385
LetSource::GenericLet => {
417386
emit_diag!(lint, "`let`", "`let` is useless", "removing `let`");
418387
}
@@ -445,7 +414,6 @@ fn irrefutable_let_pattern(id: HirId, ls: LetSource, span: Span, tcx: TyCtxt<'_>
445414

446415
fn check_let_reachability<'p, 'tcx>(
447416
cx: &mut MatchCheckCtxt<'p, 'tcx>,
448-
ls: LetSource,
449417
pat_id: HirId,
450418
pat: &'p super::Pat<'tcx>,
451419
span: Span,
@@ -454,13 +422,13 @@ fn check_let_reachability<'p, 'tcx>(
454422
let report = compute_match_usefulness(&cx, &arms, pat_id, pat.ty);
455423

456424
report_arm_reachability(&cx, &report, |arm_index, arm_span, arm_hir_id, _| {
457-
match ls {
425+
match let_source(cx.tcx, pat_id) {
458426
LetSource::IfLet | LetSource::WhileLet => {
459427
match arm_index {
460428
// The arm with the user-specified pattern.
461429
0 => unreachable_pattern(cx.tcx, arm_span, arm_hir_id, None),
462430
// The arm with the wildcard pattern.
463-
1 => irrefutable_let_pattern(pat_id, ls, arm_span, cx.tcx),
431+
1 => irrefutable_let_pattern(cx.tcx, pat_id, arm_span),
464432
_ => bug!(),
465433
}
466434
}
@@ -473,7 +441,7 @@ fn check_let_reachability<'p, 'tcx>(
473441

474442
if report.non_exhaustiveness_witnesses.is_empty() {
475443
// The match is exhaustive, i.e. the `if let` pattern is irrefutable.
476-
irrefutable_let_pattern(pat_id, ls, span, cx.tcx);
444+
irrefutable_let_pattern(cx.tcx, pat_id, span);
477445
}
478446
}
479447

@@ -789,3 +757,37 @@ pub enum LetSource {
789757
IfLetGuard,
790758
WhileLet,
791759
}
760+
761+
fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource {
762+
let hir = tcx.hir();
763+
let parent = hir.get_parent_node(pat_id);
764+
match hir.get(parent) {
765+
hir::Node::Arm(hir::Arm {
766+
guard: Some(hir::Guard::IfLet(&hir::Pat { hir_id, .. }, _)),
767+
..
768+
}) if hir_id == pat_id => {
769+
return LetSource::IfLetGuard;
770+
}
771+
_ => {}
772+
}
773+
let parent_parent = hir.get_parent_node(parent);
774+
let parent_parent_node = hir.get(parent_parent);
775+
776+
let parent_parent_parent = hir.get_parent_node(parent_parent);
777+
let parent_parent_parent_parent = hir.get_parent_node(parent_parent_parent);
778+
let parent_parent_parent_parent_node = hir.get(parent_parent_parent_parent);
779+
780+
if let hir::Node::Expr(hir::Expr {
781+
kind: hir::ExprKind::Loop(_, _, hir::LoopSource::While, _),
782+
..
783+
}) = parent_parent_parent_parent_node
784+
{
785+
LetSource::WhileLet
786+
} else if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::If { .. }, .. }) =
787+
parent_parent_node
788+
{
789+
LetSource::IfLet
790+
} else {
791+
LetSource::GenericLet
792+
}
793+
}

0 commit comments

Comments
 (0)