1
Fork 0

or-patterns: remove hack from lowering.

This commit is contained in:
Mazdak Farrokhzad 2019-09-07 15:49:58 +02:00
parent 60895fd1f9
commit 146cb8eda6
3 changed files with 19 additions and 63 deletions

View file

@ -434,35 +434,6 @@ impl<'a> LoweringContext<'a> {
visit::walk_pat(self, p) visit::walk_pat(self, p)
} }
// HACK(or_patterns; Centril | dlrobertson): Avoid creating
// HIR nodes for `PatKind::Or` for the top level of a `ast::Arm`.
// This is a temporary hack that should go away once we push down
// `arm.pats: HirVec<P<Pat>>` -> `arm.pat: P<Pat>` to HIR. // Centril
fn visit_arm(&mut self, arm: &'tcx Arm) {
match &arm.pat.node {
PatKind::Or(pats) => pats.iter().for_each(|p| self.visit_pat(p)),
_ => self.visit_pat(&arm.pat),
}
walk_list!(self, visit_expr, &arm.guard);
self.visit_expr(&arm.body);
walk_list!(self, visit_attribute, &arm.attrs);
}
// HACK(or_patterns; Centril | dlrobertson): Same as above. // Centril
fn visit_expr(&mut self, e: &'tcx Expr) {
if let ExprKind::Let(pat, scrutinee) = &e.node {
walk_list!(self, visit_attribute, e.attrs.iter());
match &pat.node {
PatKind::Or(pats) => pats.iter().for_each(|p| self.visit_pat(p)),
_ => self.visit_pat(&pat),
}
self.visit_expr(scrutinee);
self.visit_expr_post(e);
return;
}
visit::walk_expr(self, e)
}
fn visit_item(&mut self, item: &'tcx Item) { fn visit_item(&mut self, item: &'tcx Item) {
let hir_id = self.lctx.allocate_hir_id_counter(item.id); let hir_id = self.lctx.allocate_hir_id_counter(item.id);

View file

@ -250,14 +250,14 @@ impl LoweringContext<'_> {
// 4. The return type of the block is `bool` which seems like what the user wanted. // 4. The return type of the block is `bool` which seems like what the user wanted.
let scrutinee = self.lower_expr(scrutinee); let scrutinee = self.lower_expr(scrutinee);
let then_arm = { let then_arm = {
let pat = self.lower_pat_top_hack(pat); let pat = self.lower_pat(pat);
let expr = self.expr_bool(span, true); let expr = self.expr_bool(span, true);
self.arm(pat, P(expr)) self.arm(pat, P(expr))
}; };
let else_arm = { let else_arm = {
let pat = self.pat_wild(span); let pat = self.pat_wild(span);
let expr = self.expr_bool(span, false); let expr = self.expr_bool(span, false);
self.arm(hir_vec![pat], P(expr)) self.arm(pat, P(expr))
}; };
hir::ExprKind::Match( hir::ExprKind::Match(
P(scrutinee), P(scrutinee),
@ -281,7 +281,7 @@ impl LoweringContext<'_> {
None => (self.expr_block_empty(span), false), None => (self.expr_block_empty(span), false),
Some(els) => (self.lower_expr(els), true), Some(els) => (self.lower_expr(els), true),
}; };
let else_arm = self.arm(hir_vec![else_pat], P(else_expr)); let else_arm = self.arm(else_pat, P(else_expr));
// Handle then + scrutinee: // Handle then + scrutinee:
let then_blk = self.lower_block(then, false); let then_blk = self.lower_block(then, false);
@ -290,7 +290,7 @@ impl LoweringContext<'_> {
// `<pat> => <then>`: // `<pat> => <then>`:
ExprKind::Let(ref pat, ref scrutinee) => { ExprKind::Let(ref pat, ref scrutinee) => {
let scrutinee = self.lower_expr(scrutinee); let scrutinee = self.lower_expr(scrutinee);
let pat = self.lower_pat_top_hack(pat); let pat = self.lower_pat(pat);
(pat, scrutinee, hir::MatchSource::IfLetDesugar { contains_else_clause }) (pat, scrutinee, hir::MatchSource::IfLetDesugar { contains_else_clause })
} }
// `true => <then>`: // `true => <then>`:
@ -307,7 +307,7 @@ impl LoweringContext<'_> {
// let temporaries live outside of `cond`. // let temporaries live outside of `cond`.
let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new()); let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new());
let pat = self.pat_bool(span, true); let pat = self.pat_bool(span, true);
(hir_vec![pat], cond, hir::MatchSource::IfDesugar { contains_else_clause }) (pat, cond, hir::MatchSource::IfDesugar { contains_else_clause })
} }
}; };
let then_arm = self.arm(then_pat, P(then_expr)); let then_arm = self.arm(then_pat, P(then_expr));
@ -331,7 +331,7 @@ impl LoweringContext<'_> {
let else_arm = { let else_arm = {
let else_pat = self.pat_wild(span); let else_pat = self.pat_wild(span);
let else_expr = self.expr_break(span, ThinVec::new()); let else_expr = self.expr_break(span, ThinVec::new());
self.arm(hir_vec![else_pat], else_expr) self.arm(else_pat, else_expr)
}; };
// Handle then + scrutinee: // Handle then + scrutinee:
@ -348,7 +348,7 @@ impl LoweringContext<'_> {
// } // }
// } // }
let scrutinee = self.with_loop_condition_scope(|t| t.lower_expr(scrutinee)); let scrutinee = self.with_loop_condition_scope(|t| t.lower_expr(scrutinee));
let pat = self.lower_pat_top_hack(pat); let pat = self.lower_pat(pat);
(pat, scrutinee, hir::MatchSource::WhileLetDesugar, hir::LoopSource::WhileLet) (pat, scrutinee, hir::MatchSource::WhileLetDesugar, hir::LoopSource::WhileLet)
} }
_ => { _ => {
@ -376,7 +376,7 @@ impl LoweringContext<'_> {
let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new()); let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new());
// `true => <then>`: // `true => <then>`:
let pat = self.pat_bool(span, true); let pat = self.pat_bool(span, true);
(hir_vec![pat], cond, hir::MatchSource::WhileDesugar, hir::LoopSource::While) (pat, cond, hir::MatchSource::WhileDesugar, hir::LoopSource::While)
} }
}; };
let then_arm = self.arm(then_pat, P(then_expr)); let then_arm = self.arm(then_pat, P(then_expr));
@ -429,7 +429,7 @@ impl LoweringContext<'_> {
hir::Arm { hir::Arm {
hir_id: self.next_id(), hir_id: self.next_id(),
attrs: self.lower_attrs(&arm.attrs), attrs: self.lower_attrs(&arm.attrs),
pats: self.lower_pat_top_hack(&arm.pat), pat: self.lower_pat(&arm.pat),
guard: match arm.guard { guard: match arm.guard {
Some(ref x) => Some(hir::Guard::If(P(self.lower_expr(x)))), Some(ref x) => Some(hir::Guard::If(P(self.lower_expr(x)))),
_ => None, _ => None,
@ -439,16 +439,6 @@ impl LoweringContext<'_> {
} }
} }
/// HACK(or_patterns; Centril | dlrobertson): For now we don't push down top level or-patterns
/// `p | q` into `hir::PatKind::Or(...)` as post-lowering bits of the compiler are not ready
/// to deal with it. This should by fixed by pushing it down to HIR and then HAIR.
fn lower_pat_top_hack(&mut self, pat: &Pat) -> HirVec<P<hir::Pat>> {
match pat.node {
PatKind::Or(ref ps) => ps.iter().map(|x| self.lower_pat(x)).collect(),
_ => hir_vec![self.lower_pat(pat)],
}
}
pub(super) fn make_async_expr( pub(super) fn make_async_expr(
&mut self, &mut self,
capture_clause: CaptureBy, capture_clause: CaptureBy,
@ -597,7 +587,7 @@ impl LoweringContext<'_> {
); );
P(this.expr(await_span, expr_break, ThinVec::new())) P(this.expr(await_span, expr_break, ThinVec::new()))
}); });
self.arm(hir_vec![ready_pat], break_x) self.arm(ready_pat, break_x)
}; };
// `::std::task::Poll::Pending => {}` // `::std::task::Poll::Pending => {}`
@ -608,7 +598,7 @@ impl LoweringContext<'_> {
hir_vec![], hir_vec![],
); );
let empty_block = P(self.expr_block_empty(span)); let empty_block = P(self.expr_block_empty(span));
self.arm(hir_vec![pending_pat], empty_block) self.arm(pending_pat, empty_block)
}; };
let inner_match_stmt = { let inner_match_stmt = {
@ -650,7 +640,7 @@ impl LoweringContext<'_> {
}); });
// mut pinned => loop { ... } // mut pinned => loop { ... }
let pinned_arm = self.arm(hir_vec![pinned_pat], loop_expr); let pinned_arm = self.arm(pinned_pat, loop_expr);
// match <expr> { // match <expr> {
// mut pinned => loop { .. } // mut pinned => loop { .. }
@ -1084,7 +1074,7 @@ impl LoweringContext<'_> {
ThinVec::new(), ThinVec::new(),
)); ));
let some_pat = self.pat_some(pat.span, val_pat); let some_pat = self.pat_some(pat.span, val_pat);
self.arm(hir_vec![some_pat], assign) self.arm(some_pat, assign)
}; };
// `::std::option::Option::None => break` // `::std::option::Option::None => break`
@ -1092,7 +1082,7 @@ impl LoweringContext<'_> {
let break_expr = let break_expr =
self.with_loop_scope(e.id, |this| this.expr_break(e.span, ThinVec::new())); self.with_loop_scope(e.id, |this| this.expr_break(e.span, ThinVec::new()));
let pat = self.pat_none(e.span); let pat = self.pat_none(e.span);
self.arm(hir_vec![pat], break_expr) self.arm(pat, break_expr)
}; };
// `mut iter` // `mut iter`
@ -1163,7 +1153,7 @@ impl LoweringContext<'_> {
}); });
// `mut iter => { ... }` // `mut iter => { ... }`
let iter_arm = self.arm(hir_vec![iter_pat], loop_expr); let iter_arm = self.arm(iter_pat, loop_expr);
// `match ::std::iter::IntoIterator::into_iter(<head>) { ... }` // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
let into_iter_expr = { let into_iter_expr = {
@ -1249,7 +1239,7 @@ impl LoweringContext<'_> {
ThinVec::from(attrs.clone()), ThinVec::from(attrs.clone()),
)); ));
let ok_pat = self.pat_ok(span, val_pat); let ok_pat = self.pat_ok(span, val_pat);
self.arm(hir_vec![ok_pat], val_expr) self.arm(ok_pat, val_expr)
}; };
// `Err(err) => #[allow(unreachable_code)] // `Err(err) => #[allow(unreachable_code)]
@ -1284,7 +1274,7 @@ impl LoweringContext<'_> {
}; };
let err_pat = self.pat_err(try_span, err_local); let err_pat = self.pat_err(try_span, err_local);
self.arm(hir_vec![err_pat], ret_expr) self.arm(err_pat, ret_expr)
}; };
hir::ExprKind::Match( hir::ExprKind::Match(
@ -1479,14 +1469,11 @@ impl LoweringContext<'_> {
} }
} }
/// HACK(or_patterns; Centril | dlrobertson): For now we don't push down top level or-patterns fn arm(&mut self, pat: P<hir::Pat>, expr: P<hir::Expr>) -> hir::Arm {
/// `p | q` into `hir::PatKind::Or(...)` as post-lowering bits of the compiler are not ready
/// to deal with it. This should by fixed by pushing it down to HIR and then HAIR.
fn arm(&mut self, pats: HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
hir::Arm { hir::Arm {
hir_id: self.next_id(), hir_id: self.next_id(),
attrs: hir_vec![], attrs: hir_vec![],
pats, pat,
guard: None, guard: None,
span: expr.span, span: expr.span,
body: expr, body: expr,

View file

@ -834,8 +834,6 @@ pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) {
pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) { pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) {
visitor.visit_pat(&arm.pat); visitor.visit_pat(&arm.pat);
// NOTE(or_patterns; Centril | dlrobertson):
// If you change this, also change the hack in `lowering.rs`.
walk_list!(visitor, visit_expr, &arm.guard); walk_list!(visitor, visit_expr, &arm.guard);
visitor.visit_expr(&arm.body); visitor.visit_expr(&arm.body);
walk_list!(visitor, visit_attribute, &arm.attrs); walk_list!(visitor, visit_attribute, &arm.attrs);