1
Fork 0

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

View file

@ -1049,7 +1049,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
hir::ExprBreak(opt_label) => { hir::ExprBreak(opt_label) => {
// Find which label this break jumps to // 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, // Now that we know the label we're going to,
// look it up in the break loop nodes table // look it up in the break loop nodes table
@ -1063,7 +1063,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
hir::ExprAgain(opt_label) => { hir::ExprAgain(opt_label) => {
// Find which label this expr continues to // 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, // Now that we know the label we're going to,
// look it up in the continue loop nodes table // look it up in the continue loop nodes table

View file

@ -277,8 +277,8 @@ mod svh_visitor {
ExprRange(..) => SawExprRange, ExprRange(..) => SawExprRange,
ExprPath(ref qself, _) => SawExprPath(qself.as_ref().map(|q| q.position)), ExprPath(ref qself, _) => SawExprPath(qself.as_ref().map(|q| q.position)),
ExprAddrOf(m, _) => SawExprAddrOf(m), ExprAddrOf(m, _) => SawExprAddrOf(m),
ExprBreak(id) => SawExprBreak(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.name.as_str())), ExprAgain(id) => SawExprAgain(id.map(|id| id.node.name.as_str())),
ExprRet(..) => SawExprRet, ExprRet(..) => SawExprRet,
ExprInlineAsm(ref asm) => SawExprInlineAsm(asm), ExprInlineAsm(ref asm) => SawExprInlineAsm(asm),
ExprStruct(..) => SawExprStruct, 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)) ExprPath(qself, folder.fold_path(path))
} }
ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))), ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|label|
ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))), 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))), ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
ExprInlineAsm(InlineAsm { ExprInlineAsm(InlineAsm {
inputs, inputs,

View file

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

View file

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

View file

@ -3759,12 +3759,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} }
ExprBreak(Some(label)) | ExprAgain(Some(label)) => { ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
let renamed = mtwt::resolve(label); let renamed = mtwt::resolve(label.node);
match self.search_label(renamed) { match self.search_label(renamed) {
None => { None => {
resolve_error(self, resolve_error(self,
expr.span, label.span,
ResolutionError::UndeclaredLabel(&label.name.as_str())) ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
} }
Some(DlDef(def @ DefLabel(_))) => { Some(DlDef(def @ DefLabel(_))) => {
// Since this def is a label, it is never read. // 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) trans_into(bcx, &**e, Ignore)
} }
hir::ExprBreak(label_opt) => { 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) => { 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) => { hir::ExprRet(ref ex) => {
// Check to see if the return expression itself is reachable. // 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`) /// A referencing operation (`&a` or `&mut a`)
ExprAddrOf(Mutability, P<Expr>), ExprAddrOf(Mutability, P<Expr>),
/// A `break`, with an optional label to break /// A `break`, with an optional label to break
ExprBreak(Option<Ident>), ExprBreak(Option<SpannedIdent>),
/// A `continue`, with an optional label /// A `continue`, with an optional label
ExprAgain(Option<Ident>), ExprAgain(Option<SpannedIdent>),
/// A `return`, with an optional value to be returned /// A `return`, with an optional value to be returned
ExprRet(Option<P<Expr>>), 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)) ExprPath(qself, folder.fold_path(path))
} }
ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))), ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|label|
ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))), 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))), ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
ExprInlineAsm(InlineAsm { ExprInlineAsm(InlineAsm {
inputs, inputs,

View file

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

View file

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

View file

@ -9,9 +9,9 @@
// except according to those terms. // except according to those terms.
macro_rules! foo { macro_rules! foo {
() => { break 'x; } () => { break 'x; } //~ ERROR use of undeclared label `'x`
} }
pub fn main() { 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. // except according to those terms.
macro_rules! foo { macro_rules! foo {
() => { break 'x; } () => { break 'x; } //~ ERROR use of undeclared label `'x`
} }
pub fn main() { pub fn main() {
'x: for _ in 0..1 { '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 // file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT. // http://rust-lang.org/COPYRIGHT.
// //
@ -11,13 +11,8 @@
// Make sure that a continue span actually contains the keyword. // Make sure that a continue span actually contains the keyword.
fn main() { fn main() {
'a: loop { continue //~ ERROR `continue` outside of loop
if false { ;
continue //~ ERROR use of undeclared label break //~ ERROR `break` outside of loop
'b; ;
} else {
break //~ ERROR use of undeclared label
'c;
}
}
} }

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
;
}