Change:
Rustc's parser does not include a loop's label in its span. So the span associated to the expression will contain only cc

Discussion:
return self.parse_if_expr(); } if try!(self.eat_keyword(keywords::For) ){ <del> return self.parse_for_expr(None); </del> <ins> let lo = self.last_span.lo; return self.parse_for_expr(None, lo); </ins> } if try!(self.eat_keyword(keywords::While) ){ <del> return self.parse_while_expr(None); </del> <ins> let lo = self.last_span.lo; return self.parse_while_expr(None, lo); </ins> } if self.token.is_lifetime() { let lifetime = self.get_lifetime(); <ins> let lo = self.span.lo; </ins> try!(self.bump()); try!(self.expect(&token::Colon)); if try!(self.eat_keyword(keywords::While) ){ <del> return self.parse_while_expr(Some(lifetime)) </del> <ins> return self.parse_while_expr(Some(lifetime), lo) </ins> } if try!(self.eat_keyword(keywords::For) ){ <del> return self.parse_for_expr(Some(lifetime)) </del> <ins> return self.parse_for_expr(Some(lifetime), lo) </ins> } if try!(self.eat_keyword(keywords::Loop) ){ <del> return self.parse_loop_expr(Some(lifetime)) </del> <ins> return self.parse_loop_expr(Some(lifetime), lo) </ins> } return Err(self.fatal("expected `while`, `for`, or `loop` after a label")) } if try!(self.eat_keyword(keywords::Loop) ){ <del> return self.parse_loop_expr(None); </del> <ins> let lo = self.last_span.lo; return self.parse_loop_expr(None, lo); </ins> } if try!(self.eat_keyword(keywords::Continue) ){ let lo = self.span.lo;

} /// Parse a 'for' .. 'in' expression ('for' token already eaten) <del> pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> PResult<P<Expr>> { </del> <ins> pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>, span_lo: BytePos) -> PResult<P<Expr>> { </ins> // Parse: `for <src_pat> in <src_expr> <src_loop_block>` <del> let lo = self.last_span.lo; </del> let pat = try!(self.parse_pat_nopanic()); try!(self.expect_keyword(keywords::In)); let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL)); let loop_block = try!(self.parse_block()); let hi = self.last_span.hi; <del> Ok(self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident))) </del> <ins> Ok(self.mk_expr(span_lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident))) </ins> } /// Parse a 'while' or 'while let' expression ('while' token already eaten) <del> pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> PResult<P<Expr>> { </del> <ins> pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>, span_lo: BytePos) -> PResult<P<Expr>> { </ins> if self.token.is_keyword(keywords::Let) { <del> return self.parse_while_let_expr(opt_ident); </del> <ins> return self.parse_while_let_expr(opt_ident, span_lo); </ins> } <del> let lo = self.last_span.lo; </del> let cond = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL)); let body = try!(self.parse_block()); let hi = body.span.hi; <del> return Ok(self.mk_expr(lo, hi, ExprWhile(cond, body, opt_ident))); </del> <ins> return Ok(self.mk_expr(span_lo, hi, ExprWhile(cond, body, opt_ident))); </ins> } /// Parse a 'while let' expression ('while' token already eaten) <del> pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::Ident>) -> PResult<P<Expr>> { let lo = self.last_span.lo; </del> <ins> pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::Ident>, span_lo: BytePos) -> PResult<P<Expr>> { </ins> try!(self.expect_keyword(keywords::Let)); let pat = try!(self.parse_pat_nopanic()); try!(self.expect(&token::Eq)); let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL)); let body = try!(self.parse_block()); let hi = body.span.hi; <del> return Ok(self.mk_expr(lo, hi, ExprWhileLet(pat, expr, body, opt_ident))); </del> <ins> return Ok(self.mk_expr(span_lo, hi, ExprWhileLet(pat, expr, body, opt_ident))); </ins> } <del> pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> PResult<P<Expr>> { let lo = self.last_span.lo; </del> <ins> pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>, span_lo: BytePos) -> PResult<P<Expr>> { </ins> let body = try!(self.parse_block()); let hi = body.span.hi; <del> Ok(self.mk_expr(lo, hi, ExprLoop(body, opt_ident))) </del> <ins> Ok(self.mk_expr(span_lo, hi, ExprLoop(body, opt_ident))) </ins> } fn parse_match_expr(&mut self) -> PResult<P<Expr>> {

<ins> // Copyright 2012-2014 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. // Regression test for #27042. Test that a loop's label is included in its span. fn main() { let _: i32 = 'a: //~ ERROR mismatched types loop { break }; let _: i32 = 'b: //~ ERROR mismatched types while true { break }; let _: i32 = 'c: //~ ERROR mismatched types for _ in None { break }; let _: i32 = 'd: //~ ERROR mismatched types while let Some(_) = None { break }; } </ins>