diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-03-18 10:09:30 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-18 10:09:30 +0100 |
| commit | 6e48c984bd75efe0d5ba5f15bcd26567d2879bae (patch) | |
| tree | 19447cff9cc75d52fc3d5d4504fc5d182c4aeaa3 | |
| parent | bf98654e6c222308a5d88700a14988d18bd6eb0d (diff) | |
| parent | 8bb8d74182c08df2c01eefaf856fb63af7c301c5 (diff) | |
| download | rust-6e48c984bd75efe0d5ba5f15bcd26567d2879bae.tar.gz rust-6e48c984bd75efe0d5ba5f15bcd26567d2879bae.zip | |
Rollup merge of #138635 - Zalathar:immediate-subpat, r=compiler-errors
Extract `for_each_immediate_subpat` from THIR pattern visitors This is extracted from some larger changes I've been working on, trying to introduce a “THIR pattern id” to refer to THIR pattern nodes without a direct reference. The future of those changes is somewhat uncertain, due to some [proposed changes involving upvar inference](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/upvar.20inference.20on.20THIR.3F). So I'm taking my preparatory changes that make sense on their own, and extracting them into one or more independent PRs. --- This particular patch takes two different functions that were both matching on `PatKind` to traverse subpatterns, and extracts the core match into a single helper function.
| -rw-r--r-- | compiler/rustc_middle/src/thir.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/thir/visit.rs | 59 |
2 files changed, 36 insertions, 46 deletions
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 1056644b813..bbcd509c558 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -28,6 +28,7 @@ use tracing::instrument; use crate::middle::region; use crate::mir::interpret::AllocId; use crate::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp}; +use crate::thir::visit::for_each_immediate_subpat; use crate::ty::adjustment::PointerCoercion; use crate::ty::layout::IntegerExt; use crate::ty::{ @@ -672,27 +673,7 @@ impl<'tcx> Pat<'tcx> { return; } - use PatKind::*; - match &self.kind { - Wild - | Never - | Range(..) - | Binding { subpattern: None, .. } - | Constant { .. } - | Error(_) => {} - AscribeUserType { subpattern, .. } - | Binding { subpattern: Some(subpattern), .. } - | Deref { subpattern } - | DerefPattern { subpattern, .. } - | ExpandedConstant { subpattern, .. } => subpattern.walk_(it), - Leaf { subpatterns } | Variant { subpatterns, .. } => { - subpatterns.iter().for_each(|field| field.pattern.walk_(it)) - } - Or { pats } => pats.iter().for_each(|p| p.walk_(it)), - Array { box prefix, slice, box suffix } | Slice { box prefix, slice, box suffix } => { - prefix.iter().chain(slice.as_deref()).chain(suffix.iter()).for_each(|p| p.walk_(it)) - } - } + for_each_immediate_subpat(self, |p| p.walk_(it)); } /// Whether the pattern has a `PatKind::Error` nested within. diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index d208692f4e7..7d62ab7970d 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -240,36 +240,45 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( visitor: &mut V, pat: &'thir Pat<'tcx>, ) { - use PatKind::*; + for_each_immediate_subpat(pat, |p| visitor.visit_pat(p)); +} + +/// Invokes `callback` on each immediate subpattern of `pat`, if any. +/// A building block for assembling THIR pattern visitors. +pub(crate) fn for_each_immediate_subpat<'a, 'tcx>( + pat: &'a Pat<'tcx>, + mut callback: impl FnMut(&'a Pat<'tcx>), +) { match &pat.kind { - AscribeUserType { subpattern, ascription: _ } - | Deref { subpattern } - | DerefPattern { subpattern, .. } - | Binding { subpattern: Some(subpattern), .. } => visitor.visit_pat(subpattern), - Binding { .. } | Wild | Never | Error(_) => {} - Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => { - for subpattern in subpatterns { - visitor.visit_pat(&subpattern.pattern); + PatKind::Wild + | PatKind::Binding { subpattern: None, .. } + | PatKind::Constant { value: _ } + | PatKind::Range(_) + | PatKind::Never + | PatKind::Error(_) => {} + + PatKind::AscribeUserType { subpattern, .. } + | PatKind::Binding { subpattern: Some(subpattern), .. } + | PatKind::Deref { subpattern } + | PatKind::DerefPattern { subpattern, .. } + | PatKind::ExpandedConstant { subpattern, .. } => callback(subpattern), + + PatKind::Variant { subpatterns, .. } | PatKind::Leaf { subpatterns } => { + for field_pat in subpatterns { + callback(&field_pat.pattern); } } - Constant { value: _ } => {} - ExpandedConstant { def_id: _, is_inline: _, subpattern } => visitor.visit_pat(subpattern), - Range(_) => {} - Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => { - for subpattern in prefix.iter() { - visitor.visit_pat(subpattern); - } - if let Some(pat) = slice { - visitor.visit_pat(pat); - } - for subpattern in suffix.iter() { - visitor.visit_pat(subpattern); + + PatKind::Slice { prefix, slice, suffix } | PatKind::Array { prefix, slice, suffix } => { + for pat in prefix.iter().chain(slice.as_deref()).chain(suffix) { + callback(pat); } } - Or { pats } => { - for pat in pats.iter() { - visitor.visit_pat(pat); + + PatKind::Or { pats } => { + for pat in pats { + callback(pat); } } - }; + } } |
