Skip to content

Commit ec2324b

Browse files
committed
Thread everything rustc-dependent via a trait
1 parent f1e56c6 commit ec2324b

File tree

4 files changed

+474
-330
lines changed

4 files changed

+474
-330
lines changed

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

+45-39
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use super::deconstruct_pat::{Constructor, DeconstructedPat};
22
use super::usefulness::{
3-
compute_match_usefulness, MatchArm, MatchCheckCtxt, Reachability, UsefulnessReport,
3+
compute_match_usefulness, MatchArm, Reachability, UsefulnessCtxt, UsefulnessReport,
44
};
5-
use super::{deconstructed_to_pat, pat_to_deconstructed, PatCtxt, PatternError};
5+
use super::{deconstructed_to_pat, pat_to_deconstructed, MatchCheckCtxt, PatCtxt, PatternError};
66

77
use rustc_arena::TypedArena;
88
use rustc_ast::Mutability;
@@ -51,7 +51,7 @@ struct MatchVisitor<'a, 'p, 'tcx> {
5151
tcx: TyCtxt<'tcx>,
5252
typeck_results: &'a ty::TypeckResults<'tcx>,
5353
param_env: ty::ParamEnv<'tcx>,
54-
pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
54+
pattern_arena: &'p TypedArena<DeconstructedPat<'p, MatchCheckCtxt<'tcx>>>,
5555
}
5656

5757
impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
@@ -128,10 +128,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
128128

129129
fn lower_pattern(
130130
&self,
131-
cx: &mut MatchCheckCtxt<'p, 'tcx>,
131+
cx: &UsefulnessCtxt<'p, MatchCheckCtxt<'tcx>>,
132132
pat: &'tcx hir::Pat<'tcx>,
133133
have_errors: &mut bool,
134-
) -> &'p DeconstructedPat<'p, 'tcx> {
134+
) -> &'p DeconstructedPat<'p, MatchCheckCtxt<'tcx>> {
135135
let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.typeck_results);
136136
patcx.include_lint_checks();
137137
let pattern = patcx.lower_pattern(pat);
@@ -143,13 +143,13 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
143143
pattern
144144
}
145145

146-
fn new_cx(&self, hir_id: HirId) -> MatchCheckCtxt<'p, 'tcx> {
147-
MatchCheckCtxt {
146+
fn new_cx(&self, hir_id: HirId) -> UsefulnessCtxt<'p, MatchCheckCtxt<'tcx>> {
147+
let cx = MatchCheckCtxt {
148148
tcx: self.tcx,
149149
param_env: self.param_env,
150150
module: self.tcx.parent_module(hir_id).to_def_id(),
151-
pattern_arena: &self.pattern_arena,
152-
}
151+
};
152+
UsefulnessCtxt { cx, pattern_arena: &self.pattern_arena }
153153
}
154154

155155
fn check_let(&mut self, pat: &'tcx hir::Pat<'tcx>, expr: &hir::Expr<'_>, span: Span) {
@@ -165,15 +165,16 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
165165
arms: &'tcx [hir::Arm<'tcx>],
166166
source: hir::MatchSource,
167167
) {
168-
let mut cx = self.new_cx(scrut.hir_id);
168+
let ucx = self.new_cx(scrut.hir_id);
169+
let cx = &ucx.cx;
169170

170171
for arm in arms {
171172
// Check the arm for some things unrelated to exhaustiveness.
172173
self.check_patterns(&arm.pat, Refutable);
173174
if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
174175
self.check_patterns(pat, Refutable);
175-
let tpat = self.lower_pattern(&mut cx, pat, &mut false);
176-
check_let_reachability(&mut cx, pat.hir_id, tpat, tpat.span());
176+
let tpat = self.lower_pattern(&ucx, pat, &mut false);
177+
check_let_reachability(&ucx, pat.hir_id, tpat, tpat.span());
177178
}
178179
}
179180

@@ -182,7 +183,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
182183
let arms: Vec<_> = arms
183184
.iter()
184185
.map(|hir::Arm { pat, guard, .. }| MatchArm {
185-
pat: self.lower_pattern(&mut cx, pat, &mut have_errors),
186+
pat: self.lower_pattern(&ucx, pat, &mut have_errors),
186187
hir_id: pat.hir_id,
187188
has_guard: guard.is_some(),
188189
})
@@ -194,7 +195,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
194195
}
195196

196197
let scrut_ty = self.typeck_results.expr_ty_adjusted(scrut);
197-
let report = compute_match_usefulness(&cx, &arms, scrut.hir_id, scrut_ty);
198+
let report = compute_match_usefulness(&ucx, &arms, scrut.hir_id, scrut_ty);
198199

199200
match source {
200201
hir::MatchSource::ForLoopDesugar | hir::MatchSource::Normal => {
@@ -215,12 +216,13 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
215216
}
216217

217218
fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>) {
218-
let mut cx = self.new_cx(pat.hir_id);
219+
let ucx = self.new_cx(pat.hir_id);
220+
let cx = &ucx.cx;
219221

220-
let pattern = self.lower_pattern(&mut cx, pat, &mut false);
222+
let pattern = self.lower_pattern(&ucx, pat, &mut false);
221223
let pattern_ty = pattern.ty();
222224
let arms = vec![MatchArm { pat: pattern, hir_id: pat.hir_id, has_guard: false }];
223-
let report = compute_match_usefulness(&cx, &arms, pat.hir_id, pattern_ty);
225+
let report = compute_match_usefulness(&ucx, &arms, pat.hir_id, pattern_ty);
224226
report_exhaustiveness_lints(&cx, &report);
225227

226228
// Note: we ignore whether the pattern is unreachable (i.e. whether the type is empty). We
@@ -359,7 +361,7 @@ fn check_for_bindings_named_same_as_variants(
359361
}
360362

361363
/// Checks for common cases of "catchall" patterns that may not be intended as such.
362-
fn pat_is_catchall(pat: &DeconstructedPat<'_, '_>) -> bool {
364+
fn pat_is_catchall(pat: &DeconstructedPat<'_, MatchCheckCtxt<'_>>) -> bool {
363365
use Constructor::*;
364366
match pat.ctor() {
365367
Wildcard => true,
@@ -440,13 +442,14 @@ fn irrefutable_let_pattern(tcx: TyCtxt<'_>, id: HirId, span: Span) {
440442
}
441443

442444
fn check_let_reachability<'p, 'tcx>(
443-
cx: &mut MatchCheckCtxt<'p, 'tcx>,
445+
ucx: &UsefulnessCtxt<'p, MatchCheckCtxt<'tcx>>,
444446
pat_id: HirId,
445-
pat: &'p DeconstructedPat<'p, 'tcx>,
447+
pat: &'p DeconstructedPat<'p, MatchCheckCtxt<'tcx>>,
446448
span: Span,
447449
) {
450+
let cx = &ucx.cx;
448451
let arms = [MatchArm { pat, hir_id: pat_id, has_guard: false }];
449-
let report = compute_match_usefulness(&cx, &arms, pat_id, pat.ty());
452+
let report = compute_match_usefulness(&ucx, &arms, pat_id, pat.ty());
450453
report_exhaustiveness_lints(&cx, &report);
451454

452455
// Report if the pattern is unreachable, which can only occur when the type is uninhabited.
@@ -460,8 +463,8 @@ fn check_let_reachability<'p, 'tcx>(
460463

461464
/// Report unreachable arms, if any.
462465
fn report_arm_reachability<'p, 'tcx>(
463-
cx: &MatchCheckCtxt<'p, 'tcx>,
464-
report: &UsefulnessReport<'p, 'tcx>,
466+
cx: &MatchCheckCtxt<'tcx>,
467+
report: &UsefulnessReport<'p, MatchCheckCtxt<'tcx>>,
465468
) {
466469
let mut catchall = None;
467470
for (arm, reachability) in report.arm_usefulness.iter() {
@@ -479,8 +482,8 @@ fn report_arm_reachability<'p, 'tcx>(
479482

480483
/// Report various things detected during exhaustiveness checking.
481484
fn report_exhaustiveness_lints<'p, 'tcx>(
482-
cx: &MatchCheckCtxt<'p, 'tcx>,
483-
report: &UsefulnessReport<'p, 'tcx>,
485+
cx: &MatchCheckCtxt<'tcx>,
486+
report: &UsefulnessReport<'p, MatchCheckCtxt<'tcx>>,
484487
) {
485488
if !report.unreachable_subpatterns.is_empty() {
486489
let mut unreachables = report.unreachable_subpatterns.clone();
@@ -502,11 +505,11 @@ fn report_exhaustiveness_lints<'p, 'tcx>(
502505
///
503506
/// NB: The partner lint for structs lives in `compiler/rustc_typeck/src/check/pat.rs`.
504507
pub(super) fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
505-
cx: &MatchCheckCtxt<'p, 'tcx>,
508+
cx: &MatchCheckCtxt<'tcx>,
506509
scrut_ty: Ty<'tcx>,
507510
span: Span,
508511
hir_id: HirId,
509-
witnesses: &[DeconstructedPat<'p, 'tcx>],
512+
witnesses: &[DeconstructedPat<'p, MatchCheckCtxt<'tcx>>],
510513
) {
511514
let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
512515
cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, span, |build| {
@@ -525,10 +528,10 @@ pub(super) fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
525528

526529
/// Lint on likely incorrect range patterns (#63987)
527530
pub(super) fn lint_overlapping_range_endpoints<'p, 'tcx>(
528-
cx: &MatchCheckCtxt<'p, 'tcx>,
531+
cx: &MatchCheckCtxt<'tcx>,
529532
span: Span,
530533
hir_id: HirId,
531-
overlaps: &[DeconstructedPat<'p, 'tcx>],
534+
overlaps: &[DeconstructedPat<'p, MatchCheckCtxt<'tcx>>],
532535
) {
533536
if !overlaps.is_empty() {
534537
cx.tcx.struct_span_lint_hir(OVERLAPPING_RANGE_ENDPOINTS, hir_id, span, |lint| {
@@ -548,10 +551,10 @@ pub(super) fn lint_overlapping_range_endpoints<'p, 'tcx>(
548551

549552
/// Report that a match is not exhaustive.
550553
fn non_exhaustive_match<'p, 'tcx>(
551-
cx: &MatchCheckCtxt<'p, 'tcx>,
554+
cx: &MatchCheckCtxt<'tcx>,
552555
scrut_ty: Ty<'tcx>,
553556
sp: Span,
554-
witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
557+
witnesses: Vec<DeconstructedPat<'p, MatchCheckCtxt<'tcx>>>,
555558
is_empty_match: bool,
556559
) {
557560
let non_empty_enum = match scrut_ty.kind() {
@@ -619,8 +622,8 @@ fn non_exhaustive_match<'p, 'tcx>(
619622
}
620623

621624
crate fn joined_uncovered_patterns<'p, 'tcx>(
622-
cx: &MatchCheckCtxt<'p, 'tcx>,
623-
witnesses: &[DeconstructedPat<'p, 'tcx>],
625+
cx: &MatchCheckCtxt<'tcx>,
626+
witnesses: &[DeconstructedPat<'p, MatchCheckCtxt<'tcx>>],
624627
) -> String {
625628
const LIMIT: usize = 3;
626629
let pat_to_str = |pat| deconstructed_to_pat(cx, pat).to_string();
@@ -640,18 +643,18 @@ crate fn joined_uncovered_patterns<'p, 'tcx>(
640643
}
641644

642645
crate fn pattern_not_covered_label(
643-
witnesses: &[DeconstructedPat<'_, '_>],
646+
witnesses: &[DeconstructedPat<'_, MatchCheckCtxt<'_>>],
644647
joined_patterns: &str,
645648
) -> String {
646649
format!("pattern{} {} not covered", rustc_errors::pluralize!(witnesses.len()), joined_patterns)
647650
}
648651

649652
/// Point at the definition of non-covered `enum` variants.
650653
fn adt_defined_here<'p, 'tcx>(
651-
cx: &MatchCheckCtxt<'p, 'tcx>,
654+
cx: &MatchCheckCtxt<'tcx>,
652655
err: &mut DiagnosticBuilder<'_>,
653656
ty: Ty<'tcx>,
654-
witnesses: &[DeconstructedPat<'p, 'tcx>],
657+
witnesses: &[DeconstructedPat<'p, MatchCheckCtxt<'tcx>>],
655658
) {
656659
let ty = ty.peel_refs();
657660
if let ty::Adt(def, _) = ty.kind() {
@@ -668,10 +671,13 @@ fn adt_defined_here<'p, 'tcx>(
668671
}
669672

670673
fn maybe_point_at_variant<'a, 'p: 'a, 'tcx: 'a>(
671-
cx: &MatchCheckCtxt<'p, 'tcx>,
674+
cx: &MatchCheckCtxt<'tcx>,
672675
def: &AdtDef,
673-
patterns: impl Iterator<Item = &'a DeconstructedPat<'p, 'tcx>>,
674-
) -> Vec<Span> {
676+
patterns: impl Iterator<Item = &'a DeconstructedPat<'p, MatchCheckCtxt<'tcx>>>,
677+
) -> Vec<Span>
678+
where
679+
MatchCheckCtxt<'tcx>: 'p,
680+
{
675681
use Constructor::*;
676682
let mut covered = vec![];
677683
for pattern in patterns {

0 commit comments

Comments
 (0)