Auto merge of #28170 - nagisa:loopctl-label-spans, r=alexcrichton

r? @alexcrichton
This commit is contained in:
bors 2015-09-04 05:15:22 +00:00
commit 791e7bcb41
16 changed files with 73 additions and 43 deletions

View File

@ -284,7 +284,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}
hir::ExprBreak(label) => {
let loop_scope = self.find_scope(expr, label);
let loop_scope = self.find_scope(expr, label.map(|l| l.node));
let b = self.add_ast_node(expr.id, &[pred]);
self.add_exiting_edge(expr, b,
loop_scope, loop_scope.break_index);
@ -292,7 +292,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}
hir::ExprAgain(label) => {
let loop_scope = self.find_scope(expr, label);
let loop_scope = self.find_scope(expr, label.map(|l| l.node));
let a = self.add_ast_node(expr.id, &[pred]);
self.add_exiting_edge(expr, a,
loop_scope, loop_scope.continue_index);

View File

@ -1049,7 +1049,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
hir::ExprBreak(opt_label) => {
// Find which label this break jumps to
let sc = self.find_loop_scope(opt_label, expr.id, expr.span);
let sc = self.find_loop_scope(opt_label.map(|l| l.node), expr.id, expr.span);
// Now that we know the label we're going to,
// look it up in the break loop nodes table
@ -1063,7 +1063,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
hir::ExprAgain(opt_label) => {
// Find which label this expr continues to
let sc = self.find_loop_scope(opt_label, expr.id, expr.span);
let sc = self.find_loop_scope(opt_label.map(|l| l.node), expr.id, expr.span);
// Now that we know the label we're going to,
// look it up in the continue loop nodes table

View File

@ -277,8 +277,8 @@ mod svh_visitor {
ExprRange(..) => SawExprRange,
ExprPath(ref qself, _) => SawExprPath(qself.as_ref().map(|q| q.position)),
ExprAddrOf(m, _) => SawExprAddrOf(m),
ExprBreak(id) => SawExprBreak(id.map(|id| id.name.as_str())),
ExprAgain(id) => SawExprAgain(id.map(|id| id.name.as_str())),
ExprBreak(id) => SawExprBreak(id.map(|id| id.node.name.as_str())),
ExprAgain(id) => SawExprAgain(id.map(|id| id.node.name.as_str())),
ExprRet(..) => SawExprRet,
ExprInlineAsm(ref asm) => SawExprInlineAsm(asm),
ExprStruct(..) => SawExprStruct,

View File

@ -1124,8 +1124,14 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
});
ExprPath(qself, folder.fold_path(path))
}
ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))),
ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))),
ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|label|
respan(folder.new_span(label.span),
folder.fold_ident(label.node)))
),
ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|label|
respan(folder.new_span(label.span),
folder.fold_ident(label.node)))
),
ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
ExprInlineAsm(InlineAsm {
inputs,

View File

@ -730,9 +730,9 @@ pub enum Expr_ {
/// A referencing operation (`&a` or `&mut a`)
ExprAddrOf(Mutability, P<Expr>),
/// A `break`, with an optional label to break
ExprBreak(Option<Ident>),
ExprBreak(Option<SpannedIdent>),
/// A `continue`, with an optional label
ExprAgain(Option<Ident>),
ExprAgain(Option<SpannedIdent>),
/// A `return`, with an optional value to be returned
ExprRet(Option<P<Expr>>),

View File

@ -1587,7 +1587,7 @@ impl<'a> State<'a> {
try!(word(&mut self.s, "break"));
try!(space(&mut self.s));
if let Some(ident) = opt_ident {
try!(self.print_ident(ident));
try!(self.print_ident(ident.node));
try!(space(&mut self.s));
}
}
@ -1595,7 +1595,7 @@ impl<'a> State<'a> {
try!(word(&mut self.s, "continue"));
try!(space(&mut self.s));
if let Some(ident) = opt_ident {
try!(self.print_ident(ident));
try!(self.print_ident(ident.node));
try!(space(&mut self.s))
}
}

View File

@ -3759,12 +3759,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
let renamed = mtwt::resolve(label);
let renamed = mtwt::resolve(label.node);
match self.search_label(renamed) {
None => {
resolve_error(self,
expr.span,
ResolutionError::UndeclaredLabel(&label.name.as_str()))
label.span,
ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
}
Some(DlDef(def @ DefLabel(_))) => {
// Since this def is a label, it is never read.

View File

@ -937,10 +937,10 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
trans_into(bcx, &**e, Ignore)
}
hir::ExprBreak(label_opt) => {
controlflow::trans_break(bcx, expr, label_opt)
controlflow::trans_break(bcx, expr, label_opt.map(|l| l.node))
}
hir::ExprAgain(label_opt) => {
controlflow::trans_cont(bcx, expr, label_opt)
controlflow::trans_cont(bcx, expr, label_opt.map(|l| l.node))
}
hir::ExprRet(ref ex) => {
// Check to see if the return expression itself is reachable.

View File

@ -891,9 +891,9 @@ pub enum Expr_ {
/// A referencing operation (`&a` or `&mut a`)
ExprAddrOf(Mutability, P<Expr>),
/// A `break`, with an optional label to break
ExprBreak(Option<Ident>),
ExprBreak(Option<SpannedIdent>),
/// A `continue`, with an optional label
ExprAgain(Option<Ident>),
ExprAgain(Option<SpannedIdent>),
/// A `return`, with an optional value to be returned
ExprRet(Option<P<Expr>>),

View File

@ -1299,8 +1299,14 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
});
ExprPath(qself, folder.fold_path(path))
}
ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))),
ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))),
ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|label|
respan(folder.new_span(label.span),
folder.fold_ident(label.node)))
),
ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|label|
respan(folder.new_span(label.span),
folder.fold_ident(label.node)))
),
ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
ExprInlineAsm(InlineAsm {
inputs,

View File

@ -2143,9 +2143,12 @@ impl<'a> Parser<'a> {
}
if try!(self.eat_keyword(keywords::Continue) ){
let ex = if self.token.is_lifetime() {
let lifetime = self.get_lifetime();
let ex = ExprAgain(Some(Spanned{
node: self.get_lifetime(),
span: self.span
}));
try!(self.bump());
ExprAgain(Some(lifetime))
ex
} else {
ExprAgain(None)
};
@ -2161,7 +2164,6 @@ impl<'a> Parser<'a> {
UnsafeBlock(ast::UserProvided));
}
if try!(self.eat_keyword(keywords::Return) ){
// RETURN expression
if self.token.can_begin_expr() {
let e = try!(self.parse_expr_nopanic());
hi = e.span.hi;
@ -2170,11 +2172,12 @@ impl<'a> Parser<'a> {
ex = ExprRet(None);
}
} else if try!(self.eat_keyword(keywords::Break) ){
// BREAK expression
if self.token.is_lifetime() {
let lifetime = self.get_lifetime();
ex = ExprBreak(Some(Spanned {
node: self.get_lifetime(),
span: self.span
}));
try!(self.bump());
ex = ExprBreak(Some(lifetime));
} else {
ex = ExprBreak(None);
}

View File

@ -1911,7 +1911,7 @@ impl<'a> State<'a> {
try!(word(&mut self.s, "break"));
try!(space(&mut self.s));
if let Some(ident) = opt_ident {
try!(self.print_ident(ident));
try!(self.print_ident(ident.node));
try!(space(&mut self.s));
}
}
@ -1919,7 +1919,7 @@ impl<'a> State<'a> {
try!(word(&mut self.s, "continue"));
try!(space(&mut self.s));
if let Some(ident) = opt_ident {
try!(self.print_ident(ident));
try!(self.print_ident(ident.node));
try!(space(&mut self.s))
}
}

View File

@ -9,9 +9,9 @@
// except according to those terms.
macro_rules! foo {
() => { break 'x; }
() => { break 'x; } //~ ERROR use of undeclared label `'x`
}
pub fn main() {
'x: loop { foo!() } //~ ERROR use of undeclared label `'x`
'x: loop { foo!() }
}

View File

@ -9,11 +9,11 @@
// except according to those terms.
macro_rules! foo {
() => { break 'x; }
() => { break 'x; } //~ ERROR use of undeclared label `'x`
}
pub fn main() {
'x: for _ in 0..1 {
foo!() //~ ERROR use of undeclared label `'x`
foo!()
};
}

View File

@ -1,4 +1,4 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -11,13 +11,8 @@
// Make sure that a continue span actually contains the keyword.
fn main() {
'a: loop {
if false {
continue //~ ERROR use of undeclared label
'b;
} else {
break //~ ERROR use of undeclared label
'c;
}
}
continue //~ ERROR `continue` outside of loop
;
break //~ ERROR `break` outside of loop
;
}

View File

@ -0,0 +1,20 @@
// Copyright 2012-2015 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Make sure that label for continue and break is spanned correctly
fn main() {
continue
'b //~ ERROR use of undeclared label
;
break
'c //~ ERROR use of undeclared label
;
}