Skip to content

Commit 28bcffe

Browse files
committed
Auto merge of rust-lang#53815 - F001:if-let-guard, r=petrochenkov
refactor match guard This is the first step to implement RFC 2294: if-let-guard. Tracking issue: rust-lang#51114 The second step should be introducing another variant `IfLet` in the Guard enum. I separated them into 2 PRs for the convenience of reviewers. r? @petrochenkov
2 parents f39f218 + 7a083ca commit 28bcffe

File tree

22 files changed

+115
-35
lines changed

22 files changed

+115
-35
lines changed

src/librustc/cfg/construct.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
488488
// expression to target
489489
let guard_start = self.add_dummy_node(&[pat_exit]);
490490
// Visit the guard expression
491-
let guard_exit = self.expr(&guard, guard_start);
492-
491+
let guard_exit = match guard {
492+
hir::Guard::If(ref e) => self.expr(e, guard_start),
493+
};
493494
// #47295: We used to have very special case code
494495
// here for when a pair of arms are both formed
495496
// solely from constants, and if so, not add these

src/librustc/hir/intravisit.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,11 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
11021102

11031103
pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
11041104
walk_list!(visitor, visit_pat, &arm.pats);
1105-
walk_list!(visitor, visit_expr, &arm.guard);
1105+
if let Some(ref g) = arm.guard {
1106+
match g {
1107+
Guard::If(ref e) => visitor.visit_expr(e),
1108+
}
1109+
}
11061110
visitor.visit_expr(&arm.body);
11071111
walk_list!(visitor, visit_attribute, &arm.attrs);
11081112
}

src/librustc/hir/lowering.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1054,7 +1054,10 @@ impl<'a> LoweringContext<'a> {
10541054
hir::Arm {
10551055
attrs: self.lower_attrs(&arm.attrs),
10561056
pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
1057-
guard: arm.guard.as_ref().map(|ref x| P(self.lower_expr(x))),
1057+
guard: match arm.guard {
1058+
Some(Guard::If(ref x)) => Some(hir::Guard::If(P(self.lower_expr(x)))),
1059+
_ => None,
1060+
},
10581061
body: P(self.lower_expr(&arm.body)),
10591062
}
10601063
}

src/librustc/hir/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1204,10 +1204,15 @@ impl DeclKind {
12041204
pub struct Arm {
12051205
pub attrs: HirVec<Attribute>,
12061206
pub pats: HirVec<P<Pat>>,
1207-
pub guard: Option<P<Expr>>,
1207+
pub guard: Option<Guard>,
12081208
pub body: P<Expr>,
12091209
}
12101210

1211+
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1212+
pub enum Guard {
1213+
If(P<Expr>),
1214+
}
1215+
12111216
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
12121217
pub struct Field {
12131218
pub id: NodeId,

src/librustc/hir/print.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,10 +1949,14 @@ impl<'a> State<'a> {
19491949
self.print_pat(&p)?;
19501950
}
19511951
self.s.space()?;
1952-
if let Some(ref e) = arm.guard {
1953-
self.word_space("if")?;
1954-
self.print_expr(&e)?;
1955-
self.s.space()?;
1952+
if let Some(ref g) = arm.guard {
1953+
match g {
1954+
hir::Guard::If(e) => {
1955+
self.word_space("if")?;
1956+
self.print_expr(&e)?;
1957+
self.s.space()?;
1958+
}
1959+
}
19561960
}
19571961
self.word_space("=>")?;
19581962

src/librustc/ich/impls_hir.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,10 @@ impl_stable_hash_for!(struct hir::Arm {
493493
body
494494
});
495495

496+
impl_stable_hash_for!(enum hir::Guard {
497+
If(expr),
498+
});
499+
496500
impl_stable_hash_for!(struct hir::Field {
497501
id -> _,
498502
ident,

src/librustc/middle/expr_use_visitor.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
792792
}
793793

794794
if let Some(ref guard) = arm.guard {
795-
self.consume_expr(&guard);
795+
match guard {
796+
hir::Guard::If(ref e) => self.consume_expr(e),
797+
}
796798
}
797799

798800
self.consume_expr(&arm.body);

src/librustc/middle/liveness.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
10301030
let body_succ =
10311031
self.propagate_through_expr(&arm.body, succ);
10321032
let guard_succ =
1033-
self.propagate_through_opt_expr(arm.guard.as_ref().map(|e| &**e), body_succ);
1033+
self.propagate_through_opt_expr(
1034+
arm.guard.as_ref().map(|g|
1035+
match g {
1036+
hir::Guard::If(e) => &**e,
1037+
}),
1038+
body_succ);
10341039
// only consider the first pattern; any later patterns must have
10351040
// the same bindings, and we also consider the first pattern to be
10361041
// the "authoritative" set of ids

src/librustc/middle/region.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -885,8 +885,10 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
885885
fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, arm: &'tcx hir::Arm) {
886886
visitor.terminating_scopes.insert(arm.body.hir_id.local_id);
887887

888-
if let Some(ref expr) = arm.guard {
889-
visitor.terminating_scopes.insert(expr.hir_id.local_id);
888+
if let Some(ref g) = arm.guard {
889+
match g {
890+
hir::Guard::If(ref expr) => visitor.terminating_scopes.insert(expr.hir_id.local_id),
891+
};
890892
}
891893

892894
intravisit::walk_arm(visitor, arm);

src/librustc_mir/build/matches/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ pub struct Candidate<'pat, 'tcx:'pat> {
453453
bindings: Vec<Binding<'tcx>>,
454454

455455
// ...and the guard must be evaluated...
456-
guard: Option<ExprRef<'tcx>>,
456+
guard: Option<Guard<'tcx>>,
457457

458458
// ...and then we branch to arm with this index.
459459
arm_index: usize,
@@ -998,7 +998,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
998998

999999
// the block to branch to if the guard fails; if there is no
10001000
// guard, this block is simply unreachable
1001-
let guard = self.hir.mirror(guard);
1001+
let guard = match guard {
1002+
Guard::If(e) => self.hir.mirror(e),
1003+
};
10021004
let source_info = self.source_info(guard.span);
10031005
let cond = unpack!(block = self.as_local_operand(block, guard));
10041006
if autoref {

0 commit comments

Comments
 (0)