Skip to content

Commit

Permalink
Rollup merge of rust-lang#33351 - birkenfeld:loop-label-spans, r=pnkf…
Browse files Browse the repository at this point in the history
…elix

 This makes the \"shadowing labels\" warning *not* print the entire loop as a span, but only the lifetime.

Also makes rust-lang#31719 go away, but does not fix its root cause (the span of the expanded loop is still wonky, but not used anymore).
  • Loading branch information
Manishearth committed May 26, 2016
2 parents 267cde2 + 2e812e1 commit 1c9c002
Show file tree
Hide file tree
Showing 14 changed files with 99 additions and 83 deletions.
8 changes: 6 additions & 2 deletions src/librustc/hir/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,11 +1009,15 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
ExprWhile(cond, body, opt_name) => {
ExprWhile(folder.fold_expr(cond),
folder.fold_block(body),
opt_name.map(|i| folder.fold_name(i)))
opt_name.map(|label| {
respan(folder.new_span(label.span), folder.fold_name(label.node))
}))
}
ExprLoop(body, opt_name) => {
ExprLoop(folder.fold_block(body),
opt_name.map(|i| folder.fold_name(i)))
opt_name.map(|label| {
respan(folder.new_span(label.span), folder.fold_name(label.node))
}))
}
ExprMatch(expr, arms, source) => {
ExprMatch(folder.fold_expr(expr),
Expand Down
22 changes: 13 additions & 9 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
use syntax::abi::Abi;
use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute};
use syntax::attr::ThinAttributesExt;
use syntax::codemap::Span;
use syntax::codemap::{Span, Spanned};
use hir::*;

use std::cmp;
Expand Down Expand Up @@ -203,11 +203,17 @@ pub trait Visitor<'v> : Sized {
}

pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
for name in opt_name {
if let Some(name) = opt_name {
visitor.visit_name(span, name);
}
}

pub fn walk_opt_sp_name<'v, V: Visitor<'v>>(visitor: &mut V, opt_sp_name: &Option<Spanned<Name>>) {
if let Some(ref sp_name) = *opt_sp_name {
visitor.visit_name(sp_name.span, sp_name.node);
}
}

/// Walks the contents of a crate. See also `Crate::visit_all_items`.
pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID);
Expand Down Expand Up @@ -737,14 +743,14 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
visitor.visit_block(if_block);
walk_list!(visitor, visit_expr, optional_else);
}
ExprWhile(ref subexpression, ref block, opt_name) => {
ExprWhile(ref subexpression, ref block, ref opt_sp_name) => {
visitor.visit_expr(subexpression);
visitor.visit_block(block);
walk_opt_name(visitor, expression.span, opt_name)
walk_opt_sp_name(visitor, opt_sp_name);
}
ExprLoop(ref block, opt_name) => {
ExprLoop(ref block, ref opt_sp_name) => {
visitor.visit_block(block);
walk_opt_name(visitor, expression.span, opt_name)
walk_opt_sp_name(visitor, opt_sp_name);
}
ExprMatch(ref subexpression, ref arms, _) => {
visitor.visit_expr(subexpression);
Expand Down Expand Up @@ -784,9 +790,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
visitor.visit_path(path, expression.id)
}
ExprBreak(ref opt_sp_name) | ExprAgain(ref opt_sp_name) => {
for sp_name in opt_sp_name {
visitor.visit_name(sp_name.span, sp_name.node);
}
walk_opt_sp_name(visitor, opt_sp_name);
}
ExprRet(ref optional_expression) => {
walk_list!(visitor, visit_expr, optional_expression);
Expand Down
23 changes: 10 additions & 13 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ impl<'a> LoweringContext<'a> {
}
}

fn lower_opt_sp_ident(&mut self, o_id: Option<Spanned<Ident>>) -> Option<Spanned<Name>> {
o_id.map(|sp_ident| respan(sp_ident.span, self.lower_ident(sp_ident.node)))
}

fn lower_attrs(&mut self, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
attrs.clone().into()
}
Expand Down Expand Up @@ -1122,11 +1126,10 @@ impl<'a> LoweringContext<'a> {
}
ExprKind::While(ref cond, ref body, opt_ident) => {
hir::ExprWhile(self.lower_expr(cond), self.lower_block(body),
opt_ident.map(|ident| self.lower_ident(ident)))
self.lower_opt_sp_ident(opt_ident))
}
ExprKind::Loop(ref body, opt_ident) => {
hir::ExprLoop(self.lower_block(body),
opt_ident.map(|ident| self.lower_ident(ident)))
hir::ExprLoop(self.lower_block(body), self.lower_opt_sp_ident(opt_ident))
}
ExprKind::Match(ref expr, ref arms) => {
hir::ExprMatch(self.lower_expr(expr),
Expand Down Expand Up @@ -1243,12 +1246,8 @@ impl<'a> LoweringContext<'a> {
};
hir::ExprPath(hir_qself, self.lower_path_full(path, rename))
}
ExprKind::Break(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| {
respan(sp_ident.span, self.lower_ident(sp_ident.node))
})),
ExprKind::Again(opt_ident) => hir::ExprAgain(opt_ident.map(|sp_ident| {
respan(sp_ident.span, self.lower_ident(sp_ident.node))
})),
ExprKind::Break(opt_ident) => hir::ExprBreak(self.lower_opt_sp_ident(opt_ident)),
ExprKind::Again(opt_ident) => hir::ExprAgain(self.lower_opt_sp_ident(opt_ident)),
ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| self.lower_expr(x))),
ExprKind::InlineAsm(InlineAsm {
ref inputs,
Expand Down Expand Up @@ -1422,8 +1421,7 @@ impl<'a> LoweringContext<'a> {

// `[opt_ident]: loop { ... }`
let loop_block = self.block_expr(match_expr);
let loop_expr = hir::ExprLoop(loop_block,
opt_ident.map(|ident| self.lower_ident(ident)));
let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident));
// add attributes to the outer returned expr node
let attrs = e.attrs.clone();
return P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: attrs });
Expand Down Expand Up @@ -1503,8 +1501,7 @@ impl<'a> LoweringContext<'a> {

// `[opt_ident]: loop { ... }`
let loop_block = self.block_expr(match_expr);
let loop_expr = hir::ExprLoop(loop_block,
opt_ident.map(|ident| self.lower_ident(ident)));
let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident));
let loop_expr =
P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None });

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -873,11 +873,11 @@ pub enum Expr_ {
/// A while loop, with an optional label
///
/// `'label: while expr { block }`
ExprWhile(P<Expr>, P<Block>, Option<Name>),
ExprWhile(P<Expr>, P<Block>, Option<Spanned<Name>>),
/// Conditionless loop (can be exited with break, continue, or return)
///
/// `'label: loop { block }`
ExprLoop(P<Block>, Option<Name>),
ExprLoop(P<Block>, Option<Spanned<Name>>),
/// A `match` block, with a source that indicates whether or not it is
/// the result of a desugaring, and if so, which kind.
ExprMatch(P<Expr>, HirVec<Arm>, MatchSource),
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1351,19 +1351,19 @@ impl<'a> State<'a> {
hir::ExprIf(ref test, ref blk, ref elseopt) => {
self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?;
}
hir::ExprWhile(ref test, ref blk, opt_name) => {
if let Some(name) = opt_name {
self.print_name(name)?;
hir::ExprWhile(ref test, ref blk, opt_sp_name) => {
if let Some(sp_name) = opt_sp_name {
self.print_name(sp_name.node)?;
self.word_space(":")?;
}
self.head("while")?;
self.print_expr(&test)?;
space(&mut self.s)?;
self.print_block(&blk)?;
}
hir::ExprLoop(ref blk, opt_name) => {
if let Some(name) = opt_name {
self.print_name(name)?;
hir::ExprLoop(ref blk, opt_sp_name) => {
if let Some(sp_name) = opt_sp_name {
self.print_name(sp_name.node)?;
self.word_space(":")?;
}
self.head("loop")?;
Expand Down
13 changes: 7 additions & 6 deletions src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,23 +404,23 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v hir::Block) {
if let hir::ExprClosure(..) = ex.node {
return
}
if let Some(label) = expression_label(ex) {
if let Some((label, label_span)) = expression_label(ex) {
for &(prior, prior_span) in &self.labels_in_fn[..] {
// FIXME (#24278): non-hygienic comparison
if label == prior {
signal_shadowing_problem(self.sess,
label,
original_label(prior_span),
shadower_label(ex.span));
shadower_label(label_span));
}
}

check_if_label_shadows_lifetime(self.sess,
self.scope,
label,
ex.span);
label_span);

self.labels_in_fn.push((label, ex.span));
self.labels_in_fn.push((label, label_span));
}
intravisit::walk_expr(self, ex)
}
Expand All @@ -430,10 +430,11 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v hir::Block) {
}
}

fn expression_label(ex: &hir::Expr) -> Option<ast::Name> {
fn expression_label(ex: &hir::Expr) -> Option<(ast::Name, Span)> {
match ex.node {
hir::ExprWhile(_, _, Some(label)) |
hir::ExprLoop(_, Some(label)) => Some(label.unhygienize()),
hir::ExprLoop(_, Some(label)) => Some((label.node.unhygienize(),
label.span)),
_ => None,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_incremental/calculate_svh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ mod svh_visitor {
ExprType(..) => SawExprType,
ExprIf(..) => SawExprIf,
ExprWhile(..) => SawExprWhile,
ExprLoop(_, id) => SawExprLoop(id.map(|id| id.as_str())),
ExprLoop(_, id) => SawExprLoop(id.map(|id| id.node.as_str())),
ExprMatch(..) => SawExprMatch,
ExprClosure(..) => SawExprClosure,
ExprBlock(..) => SawExprBlock,
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3128,7 +3128,7 @@ impl<'a> Resolver<'a> {

{
let rib = this.label_ribs.last_mut().unwrap();
rib.bindings.insert(mtwt::resolve(label), def);
rib.bindings.insert(mtwt::resolve(label.node), def);
}

visit::walk_expr(this, expr);
Expand Down Expand Up @@ -3173,7 +3173,7 @@ impl<'a> Resolver<'a> {
self.value_ribs.push(Rib::new(NormalRibKind));
self.resolve_pattern(pattern, RefutableMode, &mut HashMap::new());

self.resolve_labeled_block(label, expr.id, block);
self.resolve_labeled_block(label.map(|l| l.node), expr.id, block);

self.value_ribs.pop();
}
Expand All @@ -3183,7 +3183,7 @@ impl<'a> Resolver<'a> {
self.value_ribs.push(Rib::new(NormalRibKind));
self.resolve_pattern(pattern, LocalIrrefutableMode, &mut HashMap::new());

self.resolve_labeled_block(label, expr.id, block);
self.resolve_labeled_block(label.map(|l| l.node), expr.id, block);

self.value_ribs.pop();
}
Expand Down
8 changes: 4 additions & 4 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,23 +1007,23 @@ pub enum ExprKind {
/// A while loop, with an optional label
///
/// `'label: while expr { block }`
While(P<Expr>, P<Block>, Option<Ident>),
While(P<Expr>, P<Block>, Option<SpannedIdent>),
/// A while-let loop, with an optional label
///
/// `'label: while let pat = expr { block }`
///
/// This is desugared to a combination of `loop` and `match` expressions.
WhileLet(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
WhileLet(P<Pat>, P<Expr>, P<Block>, Option<SpannedIdent>),
/// A for loop, with an optional label
///
/// `'label: for pat in expr { block }`
///
/// This is desugared to a combination of `loop` and `match` expressions.
ForLoop(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
ForLoop(P<Pat>, P<Expr>, P<Block>, Option<SpannedIdent>),
/// Conditionless loop (can be exited with break, continue, or return)
///
/// `'label: loop { block }`
Loop(P<Block>, Option<Ident>),
Loop(P<Block>, Option<SpannedIdent>),
/// A `match` block.
Match(P<Expr>, Vec<Arm>),
/// A closure (for example, `move |a, b, c| {a + b + c}`)
Expand Down
14 changes: 7 additions & 7 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

use ast::{Block, Crate, DeclKind, PatKind};
use ast::{Local, Ident, Mac_, Name};
use ast::{Local, Ident, Mac_, Name, SpannedIdent};
use ast::{MacStmtStyle, Mrk, Stmt, StmtKind, ItemKind};
use ast::TokenTree;
use ast;
Expand Down Expand Up @@ -277,20 +277,20 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac,
/// body is in a block enclosed by loop head so the renaming of loop label
/// must be propagated to the enclosed context.
fn expand_loop_block(loop_block: P<Block>,
opt_ident: Option<Ident>,
fld: &mut MacroExpander) -> (P<Block>, Option<Ident>) {
opt_ident: Option<SpannedIdent>,
fld: &mut MacroExpander) -> (P<Block>, Option<SpannedIdent>) {
match opt_ident {
Some(label) => {
let new_label = fresh_name(label);
let rename = (label, new_label);
let new_label = fresh_name(label.node);
let rename = (label.node, new_label);

// The rename *must not* be added to the pending list of current
// syntax context otherwise an unrelated `break` or `continue` in
// the same context will pick that up in the deferred renaming pass
// and be renamed incorrectly.
let mut rename_list = vec!(rename);
let mut rename_fld = IdentRenamer{renames: &mut rename_list};
let renamed_ident = rename_fld.fold_ident(label);
let renamed_ident = rename_fld.fold_ident(label.node);

// The rename *must* be added to the enclosed syntax context for
// `break` or `continue` to pick up because by definition they are
Expand All @@ -300,7 +300,7 @@ fn expand_loop_block(loop_block: P<Block>,
let expanded_block = expand_block_elts(loop_block, fld);
fld.cx.syntax_env.pop_frame();

(expanded_block, Some(renamed_ident))
(expanded_block, Some(Spanned { node: renamed_ident, span: label.span }))
}
None => (fld.fold_block(loop_block), opt_ident)
}
Expand Down
12 changes: 8 additions & 4 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1212,23 +1212,27 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
ExprKind::While(cond, body, opt_ident) => {
ExprKind::While(folder.fold_expr(cond),
folder.fold_block(body),
opt_ident.map(|i| folder.fold_ident(i)))
opt_ident.map(|label| respan(folder.new_span(label.span),
folder.fold_ident(label.node))))
}
ExprKind::WhileLet(pat, expr, body, opt_ident) => {
ExprKind::WhileLet(folder.fold_pat(pat),
folder.fold_expr(expr),
folder.fold_block(body),
opt_ident.map(|i| folder.fold_ident(i)))
opt_ident.map(|label| respan(folder.new_span(label.span),
folder.fold_ident(label.node))))
}
ExprKind::ForLoop(pat, iter, body, opt_ident) => {
ExprKind::ForLoop(folder.fold_pat(pat),
folder.fold_expr(iter),
folder.fold_block(body),
opt_ident.map(|i| folder.fold_ident(i)))
opt_ident.map(|label| respan(folder.new_span(label.span),
folder.fold_ident(label.node))))
}
ExprKind::Loop(body, opt_ident) => {
ExprKind::Loop(folder.fold_block(body),
opt_ident.map(|i| folder.fold_ident(i)))
opt_ident.map(|label| respan(folder.new_span(label.span),
folder.fold_ident(label.node))))
}
ExprKind::Match(expr, arms) => {
ExprKind::Match(folder.fold_expr(expr),
Expand Down
Loading

0 comments on commit 1c9c002

Please sign in to comment.