@@ -352,6 +352,20 @@ pub impl Parser {
352352 self . token_is_keyword ( & ~"fn ", tok)
353353 }
354354
355+ fn token_is_lifetime ( & self , tok : & token:: Token ) -> bool {
356+ match * tok {
357+ token:: LIFETIME ( * ) => true ,
358+ _ => false ,
359+ }
360+ }
361+
362+ fn get_lifetime ( & self , tok : & token:: Token ) -> ast:: ident {
363+ match * tok {
364+ token:: LIFETIME ( ref ident) => copy * ident,
365+ _ => self . bug ( ~"not a lifetime") ,
366+ }
367+ }
368+
355369 // parse a ty_bare_fun type:
356370 fn parse_ty_bare_fn ( & self ) -> ty_
357371 {
@@ -1204,8 +1218,14 @@ pub impl Parser {
12041218 expr_do_body) ;
12051219 } else if self . eat_keyword ( & ~"while ") {
12061220 return self.parse_while_expr();
1221+ } else if self.token_is_lifetime(&*self.token) {
1222+ let lifetime = self.get_lifetime(&*self.token);
1223+ self.bump();
1224+ self.expect(&token::COLON);
1225+ self.expect_keyword(&~" loop") ;
1226+ return self . parse_loop_expr ( Some ( lifetime) ) ;
12071227 } else if self . eat_keyword ( & ~"loop ") {
1208- return self . parse_loop_expr ( ) ;
1228+ return self . parse_loop_expr ( None ) ;
12091229 } else if self . eat_keyword ( & ~"match ") {
12101230 return self.parse_match_expr();
12111231 } else if self.eat_keyword(&~" unsafe") {
@@ -1263,8 +1283,10 @@ pub impl Parser {
12631283 ex = expr_ret(Some(e));
12641284 } else { ex = expr_ret(None); }
12651285 } else if self.eat_keyword(&~"break" ) {
1266- if is_ident( & * self . token ) {
1267- ex = expr_break ( Some ( self . parse_ident ( ) ) ) ;
1286+ if self . token_is_lifetime ( & * self . token ) {
1287+ let lifetime = self . get_lifetime ( & * self . token ) ;
1288+ self . bump ( ) ;
1289+ ex = expr_break ( Some ( lifetime) ) ;
12681290 } else {
12691291 ex = expr_break ( None ) ;
12701292 }
@@ -1961,37 +1983,32 @@ pub impl Parser {
19611983 return self . mk_expr ( lo, hi, expr_while ( cond, body) ) ;
19621984 }
19631985
1964- fn parse_loop_expr ( & self ) -> @expr {
1986+ fn parse_loop_expr ( & self , opt_ident : Option < ast :: ident > ) -> @expr {
19651987 // loop headers look like 'loop {' or 'loop unsafe {'
19661988 let is_loop_header =
19671989 * self . token == token:: LBRACE
19681990 || ( is_ident ( & * self . token )
19691991 && self . look_ahead ( 1 ) == token:: LBRACE ) ;
1970- // labeled loop headers look like 'loop foo: {'
1971- let is_labeled_loop_header =
1972- is_ident ( & * self . token )
1973- && !self . is_any_keyword ( & copy * self . token )
1974- && self . look_ahead ( 1 ) == token:: COLON ;
19751992
1976- if is_loop_header || is_labeled_loop_header {
1993+ if is_loop_header {
19771994 // This is a loop body
1978- let opt_ident;
1979- if is_labeled_loop_header {
1980- opt_ident = Some ( self . parse_ident ( ) ) ;
1981- self . expect ( & token:: COLON ) ;
1982- } else {
1983- opt_ident = None ;
1984- }
1985-
19861995 let lo = self . last_span . lo ;
19871996 let body = self . parse_block_no_value ( ) ;
19881997 let hi = body. span . hi ;
19891998 return self . mk_expr ( lo, hi, expr_loop ( body, opt_ident) ) ;
19901999 } else {
19912000 // This is a 'continue' expression
2001+ if opt_ident. is_some ( ) {
2002+ self . span_err ( * self . last_span ,
2003+ ~"a label may not be used with a `loop ` \
2004+ expression") ;
2005+ }
2006+
19922007 let lo = self . span . lo ;
1993- let ex = if is_ident ( & * self . token ) {
1994- expr_again ( Some ( self . parse_ident ( ) ) )
2008+ let ex = if self . token_is_lifetime ( & * self . token ) {
2009+ let lifetime = self . get_lifetime ( & * self . token ) ;
2010+ self . bump ( ) ;
2011+ expr_again ( Some ( lifetime) )
19952012 } else {
19962013 expr_again ( None )
19972014 } ;
0 commit comments