diff options
| author | bors <bors@rust-lang.org> | 2014-08-30 09:01:20 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-08-30 09:01:20 +0000 |
| commit | 43c26e6041b811b322f49933e8d0f9455cb7ea2b (patch) | |
| tree | 1d6a7a8293538c92f5883659ab872d550a790690 /src/libsyntax | |
| parent | c8e86e977f5f95bd2f533c12ebf8107fb6f21a0f (diff) | |
| parent | e76db8ebc2955ce19605a9c73d2b26b977406803 (diff) | |
| download | rust-43c26e6041b811b322f49933e8d0f9455cb7ea2b.tar.gz rust-43c26e6041b811b322f49933e8d0f9455cb7ea2b.zip | |
auto merge of #16190 : Pythoner6/rust/labeled-while-loop, r=alexcrichton
Fixes #12643 > Say! > I like labelled breaks/continues! I will use them with a `for` loop. And I will use with a `loop` loop. Say! I will use them ANYWHERE! … _even_ in a `while` loop. Because they're now supported there.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 4 |
6 files changed, 31 insertions, 15 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8df6b65cd16..68a1c521f19 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -524,7 +524,8 @@ pub enum Expr_ { ExprLit(Gc<Lit>), ExprCast(Gc<Expr>, P<Ty>), ExprIf(Gc<Expr>, P<Block>, Option<Gc<Expr>>), - ExprWhile(Gc<Expr>, P<Block>), + // FIXME #6993: change to Option<Name> ... or not, if these are hygienic. + ExprWhile(Gc<Expr>, P<Block>, Option<Ident>), // FIXME #6993: change to Option<Name> ... or not, if these are hygienic. ExprForLoop(Gc<Pat>, Gc<Expr>, P<Block>, Option<Ident>), // Conditionless loop (can be exited with break, cont, or ret) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9dbea1c9ac2..d0f3cf6f9d7 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -66,6 +66,12 @@ fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> { } } + ast::ExprWhile(cond, body, opt_ident) => { + let cond = fld.fold_expr(cond); + let (body, opt_ident) = expand_loop_block(body, opt_ident, fld); + fld.cx.expr(e.span, ast::ExprWhile(cond, body, opt_ident)) + } + ast::ExprLoop(loop_block, opt_ident) => { let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld); fld.cx.expr(e.span, ast::ExprLoop(loop_block, opt_ident)) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index be1c0d96711..7deabed04b8 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -1132,18 +1132,20 @@ pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> { folder.fold_block(tr), fl.map(|x| folder.fold_expr(x))) } - ExprWhile(cond, body) => { - ExprWhile(folder.fold_expr(cond), folder.fold_block(body)) + ExprWhile(cond, body, opt_ident) => { + ExprWhile(folder.fold_expr(cond), + folder.fold_block(body), + opt_ident.map(|i| folder.fold_ident(i))) } - ExprForLoop(pat, iter, body, ref maybe_ident) => { + ExprForLoop(pat, iter, body, ref opt_ident) => { ExprForLoop(folder.fold_pat(pat), folder.fold_expr(iter), folder.fold_block(body), - maybe_ident.map(|i| folder.fold_ident(i))) + opt_ident.map(|i| folder.fold_ident(i))) } ExprLoop(body, opt_ident) => { ExprLoop(folder.fold_block(body), - opt_ident.map(|x| folder.fold_ident(x))) + opt_ident.map(|i| folder.fold_ident(i))) } ExprMatch(expr, ref arms) => { ExprMatch(folder.fold_expr(expr), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 37bda15ac2c..60f24401152 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2094,19 +2094,22 @@ impl<'a> Parser<'a> { return self.parse_for_expr(None); } if self.eat_keyword(keywords::While) { - return self.parse_while_expr(); + return self.parse_while_expr(None); } if Parser::token_is_lifetime(&self.token) { let lifetime = self.get_lifetime(); self.bump(); self.expect(&token::COLON); + if self.eat_keyword(keywords::While) { + return self.parse_while_expr(Some(lifetime)) + } if self.eat_keyword(keywords::For) { return self.parse_for_expr(Some(lifetime)) } if self.eat_keyword(keywords::Loop) { return self.parse_loop_expr(Some(lifetime)) } - self.fatal("expected `for` or `loop` after a label") + self.fatal("expected `while`, `for`, or `loop` after a label") } if self.eat_keyword(keywords::Loop) { return self.parse_loop_expr(None); @@ -2762,12 +2765,12 @@ impl<'a> Parser<'a> { self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident)) } - pub fn parse_while_expr(&mut self) -> Gc<Expr> { + pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> { let lo = self.last_span.lo; let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL); let body = self.parse_block(); let hi = body.span.hi; - return self.mk_expr(lo, hi, ExprWhile(cond, body)); + return self.mk_expr(lo, hi, ExprWhile(cond, body, opt_ident)); } pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index da265d81250..6b94048eab7 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -1438,7 +1438,11 @@ impl<'a> State<'a> { ast::ExprIf(ref test, ref blk, elseopt) => { try!(self.print_if(&**test, &**blk, elseopt, false)); } - ast::ExprWhile(ref test, ref blk) => { + ast::ExprWhile(ref test, ref blk, opt_ident) => { + for ident in opt_ident.iter() { + try!(self.print_ident(*ident)); + try!(self.word_space(":")); + } try!(self.head("while")); try!(self.print_expr(&**test)); try!(space(&mut self.s)); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 7a35d82b0e4..65e192e8437 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -775,7 +775,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en visitor.visit_block(&**if_block, env.clone()); walk_expr_opt(visitor, optional_else, env.clone()) } - ExprWhile(ref subexpression, ref block) => { + ExprWhile(ref subexpression, ref block, _) => { visitor.visit_expr(&**subexpression, env.clone()); visitor.visit_block(&**block, env.clone()) } |
