Use proper span for break and continue labels

Fixes #28109
This commit is contained in:
Simonas Kazlauskas 2015-09-02 22:29:41 +03:00
parent cd138dc447
commit d8074e65b0
9 changed files with 32 additions and 23 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

@ -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))
}
}