diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 20e422e5df1a2..2a224b9fd32c5 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -488,7 +488,7 @@ impl CFGBuilder { fn find_scope(&self, expr: @ast::Expr, - label: Option) -> LoopScope { + label: Option) -> LoopScope { match label { None => { return *self.loop_scopes.last(); diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 0c0a839512470..992d4ea21193e 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -867,7 +867,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { fn find_scope<'a>(&self, expr: @ast::Expr, - label: Option, + label: Option, loop_scopes: &'a mut ~[LoopScope]) -> &'a mut LoopScope { let index = match label { None => { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 27f21385e9bf1..d8a7096982f09 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -756,7 +756,7 @@ impl Liveness { } pub fn find_loop_scope(&self, - opt_label: Option, + opt_label: Option, id: NodeId, sp: Span) -> NodeId { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index f1d3ecf69e1c0..335ea06eda98f 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -5157,15 +5157,13 @@ impl Resolver { ExprForLoop(*) => fail!("non-desugared expr_for_loop"), ExprBreak(Some(label)) | ExprAgain(Some(label)) => { - let name = label.name; - match self.search_ribs(self.label_ribs, name, expr.span, + match self.search_ribs(self.label_ribs, label, expr.span, DontAllowCapturingSelf) { None => self.resolve_error(expr.span, fmt!("use of undeclared label \ `%s`", - self.session.str_of( - label))), + interner_get(label))), Some(DlDef(def @ DefLabel(_))) => { self.record_def(expr.id, def) } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d964e89ab8e1c..cb05b8bb7eb22 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -76,7 +76,7 @@ use std::vec; use std::local_data; use extra::time; use extra::sort; -use syntax::ast::Ident; +use syntax::ast::Name; use syntax::ast_map::{path, path_elt_to_str, path_name, path_pretty_name}; use syntax::ast_util::{local_def}; use syntax::attr; @@ -1189,7 +1189,7 @@ pub fn scope_block(bcx: @mut Block, pub fn loop_scope_block(bcx: @mut Block, loop_break: @mut Block, - loop_label: Option, + loop_label: Option, n: &str, opt_node_info: Option) -> @mut Block { return new_block(bcx.fcx, Some(bcx), Some(@mut ScopeInfo { diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index bbdb9730e9550..242b15fe5f0dc 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -38,7 +38,7 @@ use std::cast; use std::hashmap::{HashMap}; use std::libc::{c_uint, c_longlong, c_ulonglong, c_char}; use std::vec; -use syntax::ast::Ident; +use syntax::ast::{Name,Ident}; use syntax::ast_map::{path, path_elt, path_pretty_name}; use syntax::codemap::Span; use syntax::parse::token; @@ -463,7 +463,7 @@ pub fn block_cleanups(bcx: @mut Block) -> ~[cleanup] { pub struct ScopeInfo { parent: Option<@mut ScopeInfo>, loop_break: Option<@mut Block>, - loop_label: Option, + loop_label: Option, // A list of functions that must be run at when leaving this // block, cleaning up any variables that were introduced in the // block. diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index db4b85605ca3e..2bf4e5c2bc6b0 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -22,7 +22,7 @@ use util::ppaux; use middle::trans::type_::Type; use syntax::ast; -use syntax::ast::Ident; +use syntax::ast::Name; use syntax::ast_util; use syntax::codemap::Span; @@ -188,7 +188,7 @@ pub fn trans_while(bcx: @mut Block, cond: @ast::Expr, body: &ast::Block) -> @mut pub fn trans_loop(bcx:@mut Block, body: &ast::Block, - opt_label: Option) + opt_label: Option) -> @mut Block { let _icx = push_ctxt("trans_loop"); let next_bcx = sub_block(bcx, "next"); @@ -201,7 +201,7 @@ pub fn trans_loop(bcx:@mut Block, } pub fn trans_break_cont(bcx: @mut Block, - opt_label: Option, + opt_label: Option, to_end: bool) -> @mut Block { let _icx = push_ctxt("trans_break_cont"); @@ -254,11 +254,11 @@ pub fn trans_break_cont(bcx: @mut Block, return bcx; } -pub fn trans_break(bcx: @mut Block, label_opt: Option) -> @mut Block { +pub fn trans_break(bcx: @mut Block, label_opt: Option) -> @mut Block { return trans_break_cont(bcx, label_opt, true); } -pub fn trans_cont(bcx: @mut Block, label_opt: Option) -> @mut Block { +pub fn trans_cont(bcx: @mut Block, label_opt: Option) -> @mut Block { return trans_break_cont(bcx, label_opt, false); } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 4b2df0db3c31c..ea9e47416c1c5 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -617,7 +617,8 @@ fn trans_rvalue_stmt_unadjusted(bcx: @mut Block, expr: @ast::Expr) -> @mut Block return controlflow::trans_while(bcx, cond, body); } ast::ExprLoop(ref body, opt_label) => { - return controlflow::trans_loop(bcx, body, opt_label); + // FIXME #6993: map can go away when ast.rs is changed + return controlflow::trans_loop(bcx, body, opt_label.map(|x| x.name)); } ast::ExprAssign(dst, src) => { let src_datum = unpack_datum!( diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index fd6acf138e1be..8d557125d3700 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -522,10 +522,12 @@ pub enum Expr_ { ExprCast(@Expr, Ty), ExprIf(@Expr, Block, Option<@Expr>), ExprWhile(@Expr, Block), + // FIXME #6993: change to Option ExprForLoop(@Pat, @Expr, Block, Option), /* Conditionless loop (can be exited with break, cont, or ret) Same semantics as while(true) { body }, but typestate knows that the (implicit) condition is always true. */ + // FIXME #6993: change to Option ExprLoop(Block, Option), ExprMatch(@Expr, ~[Arm]), ExprFnBlock(fn_decl, Block), @@ -541,8 +543,8 @@ pub enum Expr_ { /// The special identifier `self`. ExprSelf, ExprAddrOf(Mutability, @Expr), - ExprBreak(Option), - ExprAgain(Option), + ExprBreak(Option), + ExprAgain(Option), ExprRet(Option<@Expr>), /// Gets the log level for the enclosing module diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 80fd7971efdd7..2cebae550fd56 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -113,6 +113,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv, // Desugar expr_for_loop // From: `[':] for in ` + // FIXME #6993 : change type of opt_ident to Option ast::ExprForLoop(src_pat, src_expr, ref src_loop_block, opt_ident) => { // Expand any interior macros etc. // NB: we don't fold pats yet. Curious. @@ -144,7 +145,8 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv, // `None => break ['];` let none_arm = { - let break_expr = cx.expr(span, ast::ExprBreak(opt_ident)); + // FIXME #6993: this map goes away: + let break_expr = cx.expr(span, ast::ExprBreak(opt_ident.map(|x| x.name))); let none_pat = cx.pat_ident(span, none_ident); cx.arm(span, ~[none_pat], break_expr) }; diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 0b19e4462f08a..c861c26b82eb3 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -688,10 +688,13 @@ pub fn noop_fold_expr(e: &Expr_, fld: @ast_fold) -> Expr_ { ExprPath(ref pth) => ExprPath(fld.fold_path(pth)), ExprSelf => ExprSelf, ExprBreak(ref opt_ident) => { - ExprBreak(opt_ident.map_move(|x| fld.fold_ident(x))) + // FIXME #6993: add fold_name to fold.... then cut out the + // bogus Name->Ident->Name conversion. + ExprBreak(opt_ident.map_move(|x| fld.fold_ident(Ident::new(x)).name)) } ExprAgain(ref opt_ident) => { - ExprAgain(opt_ident.map_move(|x| fld.fold_ident(x))) + // FIXME #6993: add fold_name to fold.... + ExprAgain(opt_ident.map_move(|x| fld.fold_ident(Ident::new(x)).name)) } ExprRet(ref e) => { ExprRet(e.map_move(|x| fld.fold_expr(x))) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9a09a1d9cecba..4adc34d75a73e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1849,7 +1849,7 @@ impl Parser { if self.token_is_lifetime(&*self.token) { let lifetime = self.get_lifetime(&*self.token); self.bump(); - ex = ExprBreak(Some(lifetime)); + ex = ExprBreak(Some(lifetime.name)); } else { ex = ExprBreak(None); } @@ -2585,7 +2585,7 @@ impl Parser { let ex = if self.token_is_lifetime(&*self.token) { let lifetime = self.get_lifetime(&*self.token); self.bump(); - ExprAgain(Some(lifetime)) + ExprAgain(Some(lifetime.name)) } else { ExprAgain(None) }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index ca0ff81b65b76..55f052d769dce 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -19,7 +19,7 @@ use codemap::{CodeMap, BytePos}; use codemap; use diagnostic; use parse::classify::expr_is_simple_block; -use parse::token::{ident_interner, ident_to_str}; +use parse::token::{ident_interner, ident_to_str, interner_get}; use parse::{comments, token}; use parse; use print::pp::{break_offset, word, space, zerobreak, hardbreak}; @@ -1394,7 +1394,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { space(s.s); for ident in opt_ident.iter() { word(s.s, "'"); - print_ident(s, *ident); + print_name(s, *ident); space(s.s); } } @@ -1403,7 +1403,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { space(s.s); for ident in opt_ident.iter() { word(s.s, "'"); - print_ident(s, *ident); + print_name(s, *ident); space(s.s) } } @@ -1503,6 +1503,10 @@ pub fn print_ident(s: @ps, ident: ast::Ident) { word(s.s, ident_to_str(&ident)); } +pub fn print_name(s: @ps, name: ast::Name) { + word(s.s, interner_get(name)); +} + pub fn print_for_decl(s: @ps, loc: &ast::Local, coll: &ast::Expr) { print_local_decl(s, loc); space(s.s); diff --git a/src/test/run-pass/issue-9047.rs b/src/test/run-pass/issue-9047.rs new file mode 100644 index 0000000000000..fc9c22fb82cd1 --- /dev/null +++ b/src/test/run-pass/issue-9047.rs @@ -0,0 +1,19 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn decode() -> ~str { + 'outer: loop { + let mut ch_start: uint; + break 'outer; + } + ~"" +} + +fn main() {}