mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-01 19:23:50 +00:00
Auto merge of #28170 - nagisa:loopctl-label-spans, r=alexcrichton
r? @alexcrichton
This commit is contained in:
commit
791e7bcb41
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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>>),
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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>>),
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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!() }
|
||||
}
|
||||
|
@ -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!()
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
;
|
||||
}
|
||||
|
20
src/test/compile-fail/issue-28109.rs
Normal file
20
src/test/compile-fail/issue-28109.rs
Normal 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
|
||||
;
|
||||
}
|
Loading…
Reference in New Issue
Block a user