From 7a083ca25f14833d704d2efba5ca9b431f6c65ad Mon Sep 17 00:00:00 2001 From: F001 Date: Thu, 30 Aug 2018 12:18:11 +0800 Subject: introduce Guard enum --- src/libsyntax/ast.rs | 7 ++++++- src/libsyntax/fold.rs | 12 +++++++++++- src/libsyntax/parse/parser.rs | 4 ++-- src/libsyntax/print/pprust.rs | 12 ++++++++---- src/libsyntax/visit.rs | 6 +++++- 5 files changed, 32 insertions(+), 9 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ec6ac86ba6b..63aaa487bf8 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -857,10 +857,15 @@ pub struct Local { pub struct Arm { pub attrs: Vec, pub pats: Vec>, - pub guard: Option>, + pub guard: Option, pub body: P, } +#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +pub enum Guard { + If(P), +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Field { pub ident: Ident, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 50a49e2f548..82dae3bc973 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -117,6 +117,10 @@ pub trait Folder : Sized { noop_fold_arm(a, self) } + fn fold_guard(&mut self, g: Guard) -> Guard { + noop_fold_guard(g, self) + } + fn fold_pat(&mut self, p: P) -> P { noop_fold_pat(p, self) } @@ -353,11 +357,17 @@ pub fn noop_fold_arm(Arm {attrs, pats, guard, body}: Arm, Arm { attrs: fold_attrs(attrs, fld), pats: pats.move_map(|x| fld.fold_pat(x)), - guard: guard.map(|x| fld.fold_expr(x)), + guard: guard.map(|x| fld.fold_guard(x)), body: fld.fold_expr(body), } } +pub fn noop_fold_guard(g: Guard, fld: &mut T) -> Guard { + match g { + Guard::If(e) => Guard::If(fld.fold_expr(e)), + } +} + pub fn noop_fold_ty_binding(b: TypeBinding, fld: &mut T) -> TypeBinding { TypeBinding { id: fld.new_id(b.id), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b1e2e69863d..ceef03bb653 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -12,7 +12,7 @@ use rustc_target::spec::abi::{self, Abi}; use ast::{AngleBracketedArgs, ParenthesisedArgs, AttrStyle, BareFnTy}; use ast::{GenericBound, TraitBoundModifier}; use ast::Unsafety; -use ast::{Mod, AnonConst, Arg, Arm, Attribute, BindingMode, TraitItemKind}; +use ast::{Mod, AnonConst, Arg, Arm, Guard, Attribute, BindingMode, TraitItemKind}; use ast::Block; use ast::{BlockCheckMode, CaptureBy, Movability}; use ast::{Constness, Crate}; @@ -3509,7 +3509,7 @@ impl<'a> Parser<'a> { self.eat(&token::BinOp(token::Or)); let pats = self.parse_pats()?; let guard = if self.eat_keyword(keywords::If) { - Some(self.parse_expr()?) + Some(Guard::If(self.parse_expr()?)) } else { None }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 3065e795ed8..da3ba928eff 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2704,10 +2704,14 @@ impl<'a> State<'a> { self.print_outer_attributes(&arm.attrs)?; self.print_pats(&arm.pats)?; self.s.space()?; - if let Some(ref e) = arm.guard { - self.word_space("if")?; - self.print_expr(e)?; - self.s.space()?; + if let Some(ref g) = arm.guard { + match g { + ast::Guard::If(ref e) => { + self.word_space("if")?; + self.print_expr(e)?; + self.s.space()?; + } + } } self.word_space("=>")?; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 51be129737e..fccc80b668f 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -819,7 +819,11 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) { walk_list!(visitor, visit_pat, &arm.pats); - walk_list!(visitor, visit_expr, &arm.guard); + if let Some(ref g) = &arm.guard { + match g { + Guard::If(ref e) => visitor.visit_expr(e), + } + } visitor.visit_expr(&arm.body); walk_list!(visitor, visit_attribute, &arm.attrs); } -- cgit 1.4.1-3-g733a5