Skip to content

Commit bb64315

Browse files
committed
only check for mixed deref/normal constructors when needed
1 parent 50061f3 commit bb64315

File tree

5 files changed

+26
-1
lines changed

5 files changed

+26
-1
lines changed

compiler/rustc_mir_build/src/builder/scope.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
927927
scrut_span: rustc_span::Span::default(),
928928
refutable: true,
929929
known_valid_scrutinee: true,
930+
internal_state: Default::default(),
930931
};
931932

932933
let valtree = match self.eval_unevaluated_mir_constant_to_valtree(constant) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
406406
scrut_span,
407407
refutable,
408408
known_valid_scrutinee,
409+
internal_state: Default::default(),
409410
}
410411
}
411412

compiler/rustc_pattern_analysis/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ pub trait PatCx: Sized + fmt::Debug {
109109
) {
110110
}
111111

112+
/// Check if we may need to perform additional deref-pattern-specific validation.
113+
fn match_may_contain_deref_pats(&self) -> bool {
114+
true
115+
}
116+
112117
/// The current implementation of deref patterns requires that they can't match on the same
113118
/// place as a normal constructor. Since this isn't caught by type-checking, we check it in the
114119
/// `PatCx` before running the analysis. This reports an error if the check fails.

compiler/rustc_pattern_analysis/src/rustc.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::cell::Cell;
12
use std::fmt;
23
use std::iter::once;
34

@@ -99,6 +100,16 @@ pub struct RustcPatCtxt<'p, 'tcx: 'p> {
99100
/// Whether the data at the scrutinee is known to be valid. This is false if the scrutinee comes
100101
/// from a union field, a pointer deref, or a reference deref (pending opsem decisions).
101102
pub known_valid_scrutinee: bool,
103+
pub internal_state: RustcPatCtxtState,
104+
}
105+
106+
/// Private fields of [`RustcPatCtxt`], separated out to permit record initialization syntax.
107+
#[derive(Clone, Default)]
108+
pub struct RustcPatCtxtState {
109+
/// Has a deref pattern been lowered? This is initialized to `false` and is updated by
110+
/// [`RustcPatCtxt::lower_pat`] in order to avoid performing deref-pattern-specific validation
111+
/// for everything containing patterns.
112+
has_lowered_deref_pat: Cell<bool>,
102113
}
103114

104115
impl<'p, 'tcx: 'p> fmt::Debug for RustcPatCtxt<'p, 'tcx> {
@@ -474,6 +485,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
474485
fields = vec![self.lower_pat(subpattern).at_index(0)];
475486
arity = 1;
476487
ctor = DerefPattern(cx.reveal_opaque_ty(subpattern.ty));
488+
self.internal_state.has_lowered_deref_pat.set(true);
477489
}
478490
PatKind::Leaf { subpatterns } | PatKind::Variant { subpatterns, .. } => {
479491
match ty.kind() {
@@ -1028,6 +1040,10 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
10281040
}
10291041
}
10301042

1043+
fn match_may_contain_deref_pats(&self) -> bool {
1044+
self.internal_state.has_lowered_deref_pat.get()
1045+
}
1046+
10311047
fn report_mixed_deref_pat_ctors(
10321048
&self,
10331049
deref_pat: &crate::pat::DeconstructedPat<Self>,

compiler/rustc_pattern_analysis/src/usefulness.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,9 @@ pub fn compute_match_usefulness<'p, Cx: PatCx>(
18371837
complexity_limit: usize,
18381838
) -> Result<UsefulnessReport<'p, Cx>, Cx::Error> {
18391839
// The analysis doesn't support deref patterns mixed with normal constructors; error if present.
1840-
checks::detect_mixed_deref_pat_ctors(tycx, arms)?;
1840+
if tycx.match_may_contain_deref_pats() {
1841+
checks::detect_mixed_deref_pat_ctors(tycx, arms)?;
1842+
}
18411843

18421844
let mut cx = UsefulnessCtxt {
18431845
tycx,

0 commit comments

Comments
 (0)