Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
7e81ba5
propagate guard patterns into `MatchPairTree`
Human9000-bit Mar 29, 2026
33a7756
Lower guard patterns to MIR
Human9000-bit Mar 29, 2026
07ea4df
bless guard pattern testing + fmt
Human9000-bit Mar 29, 2026
6e1fde6
add mir correctness test
Human9000-bit Mar 30, 2026
f91cdfb
set `has_guard` to `true` if guard patterns are present
Human9000-bit Mar 30, 2026
512369e
update MIR correctness test
Human9000-bit Apr 2, 2026
de912aa
propagate `Scope` needed for guard patterns down to MIR
Human9000-bit Apr 3, 2026
4abe73e
guard matched candidate in case guard patterns are present, but
Human9000-bit Apr 3, 2026
d66d947
Don't mutate `guard_span` during MIR construction
Human9000-bit Apr 3, 2026
37ef41c
Don't read disrciminant for guard patterns (for now)
Human9000-bit Apr 4, 2026
91bdeb6
Properly span guard patterns
Human9000-bit Apr 5, 2026
fd58aa5
Abstract away match arms and guard patterns handling
Human9000-bit Apr 7, 2026
da1b4fa
Generalize `sub_branch_bindings` for also guard patterns
Human9000-bit Apr 7, 2026
d294282
Revert "propagate `Scope` needed for guard patterns down to MIR"
Human9000-bit Apr 8, 2026
7f9b264
more guard pattern handling
Human9000-bit Apr 10, 2026
9516e41
decouple `arm_match_scope` + rustfmt
Human9000-bit Apr 10, 2026
2332bae
Propagate the fact of guard pattern's presense when visiting it's sub…
Human9000-bit Apr 10, 2026
f47f05b
Proper spanning for arms and guards
Human9000-bit Apr 11, 2026
0089bc4
Update docs related to `sub_branch_ordered_pat_data`
Human9000-bit Apr 11, 2026
da48483
Leave `if let` guard patterns handling alone (for now)
Human9000-bit Apr 11, 2026
2f27305
Check if guards are present in a pattern in separate pass
Human9000-bit Apr 11, 2026
35fa61f
Don't enter the same scope twice
Human9000-bit Apr 11, 2026
2d01980
Properly handle guard patterns in `ScopeResolutionVisitor`
Human9000-bit Apr 11, 2026
8632813
Properly account guard patterns when entering guard scope
Human9000-bit Apr 12, 2026
834b934
Simplify `pat_has_guard`
Human9000-bit Apr 18, 2026
ec683bd
fixmes
Human9000-bit Apr 18, 2026
5361525
refactor `extract_span_scope`
Human9000-bit Apr 19, 2026
0f47364
Merge arm/pat guards in `Candidate` creation.
Human9000-bit Apr 19, 2026
5c26dc5
add runtime behavior testing for guard patterns (1)
Human9000-bit Apr 20, 2026
b3f7403
Update arm + guard pat combination and guard pat handling overall
Human9000-bit May 1, 2026
9ff6ae5
recover from `InterPat` addition
Human9000-bit Jun 8, 2026
8a3fbab
fixup! fixmes
Human9000-bit Jun 9, 2026
94465eb
merge guards early with metadata flags retention
Human9000-bit Jun 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,13 @@ fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir:

#[tracing::instrument(level = "debug", skip(visitor))]
fn resolve_pat<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, pat: &'tcx hir::Pat<'tcx>) {
// We walk the whole pattern here to avoid walking `cond` expr another time on `walk_pat`
if let PatKind::Guard(pat, cond) = pat.kind {
resolve_cond(visitor, cond);
resolve_pat(visitor, pat);
return;
}

// If this is a binding then record the lifetime of that binding.
if let PatKind::Binding(..) = pat.kind {
record_var_lifetime(visitor, pat.hir_id.local_id);
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -956,13 +956,14 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
read_discriminant();
}
}

PatKind::Or(_)
| PatKind::Box(_)
| PatKind::Ref(..)
| PatKind::Guard(..)
| PatKind::Tuple(..)
| PatKind::Wild
| PatKind::Missing
| PatKind::Guard(..)
| PatKind::Err(_) => {
// If the PatKind is Or, Box, Ref, Guard, or Tuple, the relevant accesses
// are made later as these patterns contains subpatterns.
Expand Down
30 changes: 23 additions & 7 deletions compiler/rustc_mir_build/src/builder/matches/match_pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::Arc;
use rustc_abi::FieldIdx;
use rustc_middle::mir::{Pinnedness, Place, PlaceElem, ProjectionElem};
use rustc_middle::span_bug;
use rustc_middle::thir::{Ascription, DerefPatBorrowMode, FieldPat, Pat, PatKind};
use rustc_middle::thir::{Ascription, DerefPatBorrowMode, ExprId, FieldPat, Pat, PatKind};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_span::Span;

Expand Down Expand Up @@ -87,11 +87,15 @@ impl<'tcx> FlatPat<'tcx> {
/// when squashing any or-patterns.
fn from_inter_pat(inter_pat: InterPat<'tcx>) -> Self {
let mut match_pairs = vec![];
let mut guard_patterns = vec![];
if let Some(guard_pat) = inter_pat.guard {
guard_patterns.push(super::OrderedPatternData::One(guard_pat));
}
let mut extra_data = PatternExtraData {
span: inter_pat.pattern_span,
bindings: vec![],
ascriptions: vec![],
guards: guard_patterns,
is_never: inter_pat.is_never,
..Default::default()
};
squash_inter_pat(inter_pat, &mut match_pairs, &mut extra_data);

Expand All @@ -114,12 +118,14 @@ fn squash_inter_pat<'tcx>(
or_subpats,
ascriptions,
binding,
guard,
pattern_span,
is_never: _, // Not needed by `MatchPairTree` forests.
} = inter_pat;

// Type ascriptions can appear regardless of whether the node is an or-pattern.
extra_data.ascriptions.extend(ascriptions);
guard.inspect(|&g| extra_data.guards.push(super::OrderedPatternData::One(g)));

// Or and non-or patterns have very different handling.
if let Some(or_subpats) = or_subpats {
Expand All @@ -139,7 +145,11 @@ fn squash_inter_pat<'tcx>(
// or-patterns that will be simplified by `merge_trivial_subcandidates`. In
// other words, we can assume this expands into subcandidates.
// FIXME(@dianne): this needs updating/removing if we always merge or-patterns
extra_data.bindings.push(super::SubpatternBindings::FromOrPattern);
extra_data.bindings.push(super::OrderedPatternData::FromOrPattern);
}

if or_subpats.iter().any(|pat| !pat.extra_data.guards.is_empty()) {
extra_data.guards.push(super::OrderedPatternData::FromOrPattern);
}

match_pairs.push(MatchPairTree {
Expand Down Expand Up @@ -179,7 +189,7 @@ fn squash_inter_pat<'tcx>(
// the binding to `copy_field` will occur before the binding for `x`.
// See <https://github.com/rust-lang/rust/issues/69971> for more background.
if let Some(binding) = binding {
extra_data.bindings.push(super::SubpatternBindings::One(binding));
extra_data.bindings.push(super::OrderedPatternData::One(binding));
}
}
}
Expand Down Expand Up @@ -214,6 +224,8 @@ struct InterPat<'tcx> {
/// Binding to establish for a [`PatKind::Binding`] node.
binding: Option<super::Binding<'tcx>>,

guard: Option<ExprId>,

/// Span field of the THIR pattern this node was created from.
pattern_span: Span,
/// True if this pattern can never match, because all of its alternatives
Expand Down Expand Up @@ -256,6 +268,7 @@ impl<'tcx> InterPat<'tcx> {
let mut or_subpats = None;
let mut ascriptions = vec![];
let mut binding = None;
let mut guard = None;

// Apply any type ascriptions to the value at `match_pair.place`.
if let Some(place) = place
Expand Down Expand Up @@ -454,8 +467,10 @@ impl<'tcx> InterPat<'tcx> {
Some(TestableCase::Deref { temp, mutability })
}

PatKind::Guard { .. } => {
// FIXME(guard_patterns)
PatKind::Guard { ref subpattern, condition } => {
let subpattern = InterPat::lower_thir_pat(cx, place_builder, subpattern);
subpats.push(subpattern);
guard = Some(condition);
None
}

Expand All @@ -479,6 +494,7 @@ impl<'tcx> InterPat<'tcx> {
or_subpats,
ascriptions,
binding,
guard,
pattern_span: pattern.span,
is_never,
}
Expand Down
Loading
Loading