Skip to content

Commit

Permalink
add guard patterns to THIR
Browse files Browse the repository at this point in the history
  • Loading branch information
max-niederman committed Sep 15, 2024
1 parent 33492c7 commit 9e8b4ae
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 3 deletions.
10 changes: 9 additions & 1 deletion compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,8 @@ impl<'tcx> Pat<'tcx> {
| Binding { subpattern: Some(subpattern), .. }
| Deref { subpattern }
| DerefPattern { subpattern, .. }
| InlineConstant { subpattern, .. } => subpattern.walk_(it),
| InlineConstant { subpattern, .. }
| Guard { subpattern, .. } => subpattern.walk_(it),
Leaf { subpatterns } | Variant { subpatterns, .. } => {
subpatterns.iter().for_each(|field| field.pattern.walk_(it))
}
Expand Down Expand Up @@ -823,6 +824,13 @@ pub enum PatKind<'tcx> {
pats: Box<[Box<Pat<'tcx>>]>,
},

/// A guard pattern, e.g. `x if guard(x)`.
Guard {
subpattern: Box<Pat<'tcx>>,
#[type_visitable(ignore)]
condition: ExprId,
},

/// A never pattern `!`.
Never,

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/thir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,5 +256,9 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
visitor.visit_pat(pat);
}
}
Guard { subpattern, condition } => {
visitor.visit_pat(subpattern);
visitor.visit_expr(&visitor.thir()[*condition]);
}
};
}
5 changes: 5 additions & 0 deletions compiler/rustc_mir_build/src/build/matches/match_pair.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rustc_middle::mir::*;
use rustc_middle::span_bug;
use rustc_middle::thir::{self, *};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};

Expand Down Expand Up @@ -248,6 +249,10 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
}

PatKind::Never => TestCase::Never,

PatKind::Guard { .. } => {
span_bug!(pattern.span, "MIR lowering is not yet implemented for guard patterns")
}
};

MatchPairTree { place, test_case, subpairs, pattern }
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.visit_primary_bindings(subpattern, pattern_user_ty, f)
}

PatKind::Guard { ref subpattern, .. } => {
self.visit_primary_bindings(subpattern, pattern_user_ty, f);
}

PatKind::Leaf { ref subpatterns } => {
for subpattern in subpatterns {
let subpattern_user_ty = pattern_user_ty.clone().leaf(subpattern.field);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
PatKind::Or { .. } |
PatKind::InlineConstant { .. } |
PatKind::AscribeUserType { .. } |
PatKind::Guard { .. } |
PatKind::Error(_) => {}
}
};
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
hir::PatKind::Or(pats) => PatKind::Or { pats: self.lower_patterns(pats) },

hir::PatKind::Guard(..) => {
span_bug!(pat.span, "lowering guard patterns to MIR is not yet implemented");
span_bug!(pat.span, "lowering guard patterns to THIR is not yet implemented");
}

hir::PatKind::Err(guar) => PatKind::Error(guar),
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_mir_build/src/thir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,14 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
print_indented!(self, "]", depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Guard { subpattern, condition } => {
print_indented!(self, "Guard {", depth_lvl + 1);
print_indented!(self, "subpattern:", depth_lvl + 2);
self.print_pat(subpattern, depth_lvl + 3);
print_indented!(self, "condition:", depth_lvl + 2);
self.print_expr(*condition, depth_lvl + 3);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Error(_) => {
print_indented!(self, "Error", depth_lvl + 1);
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_pattern_analysis/src/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
let fields: Vec<_>;
match &pat.kind {
PatKind::AscribeUserType { subpattern, .. }
| PatKind::InlineConstant { subpattern, .. } => return self.lower_pat(subpattern),
| PatKind::InlineConstant { subpattern, .. }
| PatKind::Guard { subpattern, .. } => return self.lower_pat(subpattern),
PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat),
PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
ctor = Wildcard;
Expand Down

0 comments on commit 9e8b4ae

Please sign in to comment.