Skip to content

Commit

Permalink
Calculate LetSource later
Browse files Browse the repository at this point in the history
  • Loading branch information
camsteffen committed Aug 31, 2021
1 parent 29bc94f commit dc028f6
Showing 1 changed file with 42 additions and 40 deletions.
82 changes: 42 additions & 40 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,31 +118,6 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
check_for_bindings_named_same_as_variants(self, pat);
}

fn let_source(&mut self, pat: &'tcx hir::Pat<'tcx>, _expr: &hir::Expr<'_>) -> LetSource {
let hir = self.tcx.hir();
let parent = hir.get_parent_node(pat.hir_id);
let parent_parent = hir.get_parent_node(parent);
let parent_parent_node = hir.get(parent_parent);

let parent_parent_parent = hir.get_parent_node(parent_parent);
let parent_parent_parent_parent = hir.get_parent_node(parent_parent_parent);
let parent_parent_parent_parent_node = hir.get(parent_parent_parent_parent);

if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Loop(_, _, hir::LoopSource::While, _),
..
}) = parent_parent_parent_parent_node
{
LetSource::WhileLet
} else if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::If { .. }, .. }) =
parent_parent_node
{
LetSource::IfLet
} else {
LetSource::GenericLet
}
}

fn lower_pattern<'p>(
&self,
cx: &mut MatchCheckCtxt<'p, 'tcx>,
Expand Down Expand Up @@ -172,10 +147,9 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {

fn check_let(&mut self, pat: &'tcx hir::Pat<'tcx>, expr: &hir::Expr<'_>, span: Span) {
self.check_patterns(pat);
let ls = self.let_source(pat, expr);
let mut cx = self.new_cx(expr.hir_id);
let tpat = self.lower_pattern(&mut cx, pat, &mut false).0;
check_let_reachability(&mut cx, ls, pat.hir_id, &tpat, span);
check_let_reachability(&mut cx, pat.hir_id, &tpat, span);
}

fn check_match(
Expand All @@ -192,13 +166,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
self.check_patterns(pat);
let tpat = self.lower_pattern(&mut cx, pat, &mut false).0;
check_let_reachability(
&mut cx,
LetSource::IfLetGuard,
pat.hir_id,
&tpat,
tpat.span,
);
check_let_reachability(&mut cx, pat.hir_id, &tpat, tpat.span);
}
}

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

fn irrefutable_let_pattern(id: HirId, ls: LetSource, span: Span, tcx: TyCtxt<'_>) {
fn irrefutable_let_pattern(tcx: TyCtxt<'_>, id: HirId, span: Span) {
macro_rules! emit_diag {
(
$lint:expr,
Expand All @@ -412,7 +380,8 @@ fn irrefutable_let_pattern(id: HirId, ls: LetSource, span: Span, tcx: TyCtxt<'_>
}};
}

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

fn check_let_reachability<'p, 'tcx>(
cx: &mut MatchCheckCtxt<'p, 'tcx>,
ls: LetSource,
pat_id: HirId,
pat: &'p super::Pat<'tcx>,
span: Span,
Expand All @@ -454,13 +422,13 @@ fn check_let_reachability<'p, 'tcx>(
let report = compute_match_usefulness(&cx, &arms, pat_id, pat.ty);

report_arm_reachability(&cx, &report, |arm_index, arm_span, arm_hir_id, _| {
match ls {
match let_source(cx.tcx, pat_id) {
LetSource::IfLet | LetSource::WhileLet => {
match arm_index {
// The arm with the user-specified pattern.
0 => unreachable_pattern(cx.tcx, arm_span, arm_hir_id, None),
// The arm with the wildcard pattern.
1 => irrefutable_let_pattern(pat_id, ls, arm_span, cx.tcx),
1 => irrefutable_let_pattern(cx.tcx, pat_id, arm_span),
_ => bug!(),
}
}
Expand All @@ -473,7 +441,7 @@ fn check_let_reachability<'p, 'tcx>(

if report.non_exhaustiveness_witnesses.is_empty() {
// The match is exhaustive, i.e. the `if let` pattern is irrefutable.
irrefutable_let_pattern(pat_id, ls, span, cx.tcx);
irrefutable_let_pattern(cx.tcx, pat_id, span);
}
}

Expand Down Expand Up @@ -789,3 +757,37 @@ pub enum LetSource {
IfLetGuard,
WhileLet,
}

fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource {
let hir = tcx.hir();
let parent = hir.get_parent_node(pat_id);
match hir.get(parent) {
hir::Node::Arm(hir::Arm {
guard: Some(hir::Guard::IfLet(&hir::Pat { hir_id, .. }, _)),
..
}) if hir_id == pat_id => {
return LetSource::IfLetGuard;
}
_ => {}
}
let parent_parent = hir.get_parent_node(parent);
let parent_parent_node = hir.get(parent_parent);

let parent_parent_parent = hir.get_parent_node(parent_parent);
let parent_parent_parent_parent = hir.get_parent_node(parent_parent_parent);
let parent_parent_parent_parent_node = hir.get(parent_parent_parent_parent);

if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Loop(_, _, hir::LoopSource::While, _),
..
}) = parent_parent_parent_parent_node
{
LetSource::WhileLet
} else if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::If { .. }, .. }) =
parent_parent_node
{
LetSource::IfLet
} else {
LetSource::GenericLet
}
}

0 comments on commit dc028f6

Please sign in to comment.