Skip to content

Commit 2d56abf

Browse files
committed
AST/HIR: Add a separate structure for labels
1 parent fdc18b3 commit 2d56abf

File tree

13 files changed

+203
-202
lines changed

13 files changed

+203
-202
lines changed

src/librustc/hir/intravisit.rs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
4444
use syntax::abi::Abi;
4545
use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute};
46-
use syntax::codemap::Spanned;
4746
use syntax_pos::Span;
4847
use hir::*;
4948
use hir::def::Def;
@@ -336,6 +335,9 @@ pub trait Visitor<'v> : Sized {
336335
fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
337336
walk_variant(self, v, g, item_id)
338337
}
338+
fn visit_label(&mut self, label: &'v Label) {
339+
walk_label(self, label)
340+
}
339341
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
340342
walk_lifetime(self, lifetime)
341343
}
@@ -370,18 +372,6 @@ pub trait Visitor<'v> : Sized {
370372
}
371373
}
372374

373-
pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
374-
if let Some(name) = opt_name {
375-
visitor.visit_name(span, name);
376-
}
377-
}
378-
379-
pub fn walk_opt_sp_name<'v, V: Visitor<'v>>(visitor: &mut V, opt_sp_name: &Option<Spanned<Name>>) {
380-
if let Some(ref sp_name) = *opt_sp_name {
381-
visitor.visit_name(sp_name.span, sp_name.node);
382-
}
383-
}
384-
385375
/// Walks the contents of a crate. See also `Crate::visit_all_items`.
386376
pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
387377
visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID);
@@ -420,6 +410,10 @@ pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
420410
walk_list!(visitor, visit_ty, &local.ty);
421411
}
422412

413+
pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) {
414+
visitor.visit_name(label.span, label.name);
415+
}
416+
423417
pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
424418
visitor.visit_id(lifetime.id);
425419
match lifetime.name {
@@ -452,7 +446,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
452446
match item.node {
453447
ItemExternCrate(opt_name) => {
454448
visitor.visit_id(item.id);
455-
walk_opt_name(visitor, item.span, opt_name)
449+
if let Some(name) = opt_name {
450+
visitor.visit_name(item.span, name);
451+
}
456452
}
457453
ItemUse(ref path, _) => {
458454
visitor.visit_id(item.id);
@@ -993,14 +989,14 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
993989
visitor.visit_expr(if_block);
994990
walk_list!(visitor, visit_expr, optional_else);
995991
}
996-
ExprWhile(ref subexpression, ref block, ref opt_sp_name) => {
992+
ExprWhile(ref subexpression, ref block, ref opt_label) => {
993+
walk_list!(visitor, visit_label, opt_label);
997994
visitor.visit_expr(subexpression);
998995
visitor.visit_block(block);
999-
walk_opt_sp_name(visitor, opt_sp_name);
1000996
}
1001-
ExprLoop(ref block, ref opt_sp_name, _) => {
997+
ExprLoop(ref block, ref opt_label, _) => {
998+
walk_list!(visitor, visit_label, opt_label);
1002999
visitor.visit_block(block);
1003-
walk_opt_sp_name(visitor, opt_sp_name);
10041000
}
10051001
ExprMatch(ref subexpression, ref arms, _) => {
10061002
visitor.visit_expr(subexpression);
@@ -1036,28 +1032,28 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
10361032
ExprPath(ref qpath) => {
10371033
visitor.visit_qpath(qpath, expression.id, expression.span);
10381034
}
1039-
ExprBreak(label, ref opt_expr) => {
1040-
label.ident.map(|ident| {
1041-
match label.target_id {
1035+
ExprBreak(ref destination, ref opt_expr) => {
1036+
if let Some(ref label) = destination.label {
1037+
visitor.visit_label(label);
1038+
match destination.target_id {
10421039
ScopeTarget::Block(node_id) |
10431040
ScopeTarget::Loop(LoopIdResult::Ok(node_id)) =>
10441041
visitor.visit_def_mention(Def::Label(node_id)),
10451042
ScopeTarget::Loop(LoopIdResult::Err(_)) => {},
10461043
};
1047-
visitor.visit_name(ident.span, ident.node.name);
1048-
});
1044+
}
10491045
walk_list!(visitor, visit_expr, opt_expr);
10501046
}
1051-
ExprAgain(label) => {
1052-
label.ident.map(|ident| {
1053-
match label.target_id {
1047+
ExprAgain(ref destination) => {
1048+
if let Some(ref label) = destination.label {
1049+
visitor.visit_label(label);
1050+
match destination.target_id {
10541051
ScopeTarget::Block(_) => bug!("can't `continue` to a non-loop block"),
10551052
ScopeTarget::Loop(LoopIdResult::Ok(node_id)) =>
10561053
visitor.visit_def_mention(Def::Label(node_id)),
10571054
ScopeTarget::Loop(LoopIdResult::Err(_)) => {},
10581055
};
1059-
visitor.visit_name(ident.span, ident.node.name);
1060-
});
1056+
}
10611057
}
10621058
ExprRet(ref optional_expression) => {
10631059
walk_list!(visitor, visit_expr, optional_expression);

src/librustc/hir/lowering.rs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -768,22 +768,22 @@ impl<'a> LoweringContext<'a> {
768768
*self.name_map.entry(ident).or_insert_with(|| Symbol::from_ident(ident))
769769
}
770770

771-
fn lower_opt_sp_ident(&mut self, o_id: Option<Spanned<Ident>>) -> Option<Spanned<Name>> {
772-
o_id.map(|sp_ident| respan(sp_ident.span, sp_ident.node.name))
771+
fn lower_label(&mut self, label: Option<Label>) -> Option<hir::Label> {
772+
label.map(|label| hir::Label { name: label.ident.name, span: label.span })
773773
}
774774

775-
fn lower_loop_destination(&mut self, destination: Option<(NodeId, Spanned<Ident>)>)
775+
fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>)
776776
-> hir::Destination
777777
{
778778
match destination {
779-
Some((id, label_ident)) => {
779+
Some((id, label)) => {
780780
let target = if let Def::Label(loop_id) = self.expect_full_def(id) {
781781
hir::LoopIdResult::Ok(self.lower_node_id(loop_id).node_id)
782782
} else {
783783
hir::LoopIdResult::Err(hir::LoopIdError::UnresolvedLabel)
784784
};
785785
hir::Destination {
786-
ident: Some(label_ident),
786+
label: self.lower_label(Some(label)),
787787
target_id: hir::ScopeTarget::Loop(target),
788788
}
789789
},
@@ -793,7 +793,7 @@ impl<'a> LoweringContext<'a> {
793793
.map(|innermost_loop_id| *innermost_loop_id);
794794

795795
hir::Destination {
796-
ident: None,
796+
label: None,
797797
target_id: hir::ScopeTarget::Loop(
798798
loop_id.map(|id| Ok(self.lower_node_id(id).node_id))
799799
.unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
@@ -2746,17 +2746,17 @@ impl<'a> LoweringContext<'a> {
27462746

27472747
hir::ExprIf(P(self.lower_expr(cond)), P(then_expr), else_opt)
27482748
}
2749-
ExprKind::While(ref cond, ref body, opt_ident) => {
2749+
ExprKind::While(ref cond, ref body, opt_label) => {
27502750
self.with_loop_scope(e.id, |this|
27512751
hir::ExprWhile(
27522752
this.with_loop_condition_scope(|this| P(this.lower_expr(cond))),
27532753
this.lower_block(body, false),
2754-
this.lower_opt_sp_ident(opt_ident)))
2754+
this.lower_label(opt_label)))
27552755
}
2756-
ExprKind::Loop(ref body, opt_ident) => {
2756+
ExprKind::Loop(ref body, opt_label) => {
27572757
self.with_loop_scope(e.id, |this|
27582758
hir::ExprLoop(this.lower_block(body, false),
2759-
this.lower_opt_sp_ident(opt_ident),
2759+
this.lower_label(opt_label),
27602760
hir::LoopSource::Loop))
27612761
}
27622762
ExprKind::Catch(ref body) => {
@@ -2860,30 +2860,30 @@ impl<'a> LoweringContext<'a> {
28602860
hir::ExprPath(self.lower_qpath(e.id, qself, path, ParamMode::Optional,
28612861
ImplTraitContext::Disallowed))
28622862
}
2863-
ExprKind::Break(opt_ident, ref opt_expr) => {
2864-
let label_result = if self.is_in_loop_condition && opt_ident.is_none() {
2863+
ExprKind::Break(opt_label, ref opt_expr) => {
2864+
let destination = if self.is_in_loop_condition && opt_label.is_none() {
28652865
hir::Destination {
2866-
ident: opt_ident,
2866+
label: None,
28672867
target_id: hir::ScopeTarget::Loop(
28682868
Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into()),
28692869
}
28702870
} else {
2871-
self.lower_loop_destination(opt_ident.map(|ident| (e.id, ident)))
2871+
self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
28722872
};
28732873
hir::ExprBreak(
2874-
label_result,
2874+
destination,
28752875
opt_expr.as_ref().map(|x| P(self.lower_expr(x))))
28762876
}
2877-
ExprKind::Continue(opt_ident) =>
2877+
ExprKind::Continue(opt_label) =>
28782878
hir::ExprAgain(
2879-
if self.is_in_loop_condition && opt_ident.is_none() {
2879+
if self.is_in_loop_condition && opt_label.is_none() {
28802880
hir::Destination {
2881-
ident: opt_ident,
2881+
label: None,
28822882
target_id: hir::ScopeTarget::Loop(Err(
28832883
hir::LoopIdError::UnlabeledCfInWhileCondition).into()),
28842884
}
28852885
} else {
2886-
self.lower_loop_destination(opt_ident.map( |ident| (e.id, ident)))
2886+
self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
28872887
}),
28882888
ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| P(self.lower_expr(x)))),
28892889
ExprKind::InlineAsm(ref asm) => {
@@ -2983,7 +2983,7 @@ impl<'a> LoweringContext<'a> {
29832983

29842984
// Desugar ExprWhileLet
29852985
// From: `[opt_ident]: while let <pat> = <sub_expr> <body>`
2986-
ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => {
2986+
ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_label) => {
29872987
// to:
29882988
//
29892989
// [opt_ident]: loop {
@@ -3024,15 +3024,15 @@ impl<'a> LoweringContext<'a> {
30243024

30253025
// `[opt_ident]: loop { ... }`
30263026
let loop_block = P(self.block_expr(P(match_expr)));
3027-
let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident),
3027+
let loop_expr = hir::ExprLoop(loop_block, self.lower_label(opt_label),
30283028
hir::LoopSource::WhileLet);
30293029
// add attributes to the outer returned expr node
30303030
loop_expr
30313031
}
30323032

30333033
// Desugar ExprForLoop
30343034
// From: `[opt_ident]: for <pat> in <head> <body>`
3035-
ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => {
3035+
ExprKind::ForLoop(ref pat, ref head, ref body, opt_label) => {
30363036
// to:
30373037
//
30383038
// {
@@ -3133,7 +3133,7 @@ impl<'a> LoweringContext<'a> {
31333133
None));
31343134

31353135
// `[opt_ident]: loop { ... }`
3136-
let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident),
3136+
let loop_expr = hir::ExprLoop(loop_block, self.lower_label(opt_label),
31373137
hir::LoopSource::ForLoop);
31383138
let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
31393139
let loop_expr = P(hir::Expr {
@@ -3253,7 +3253,7 @@ impl<'a> LoweringContext<'a> {
32533253
e.span,
32543254
hir::ExprBreak(
32553255
hir::Destination {
3256-
ident: None,
3256+
label: None,
32573257
target_id: hir::ScopeTarget::Block(catch_node),
32583258
},
32593259
Some(from_err_expr)

src/librustc/hir/mod.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use util::nodemap::{NodeMap, FxHashSet};
3434
use syntax_pos::{Span, DUMMY_SP};
3535
use syntax::codemap::{self, Spanned};
3636
use syntax::abi::Abi;
37-
use syntax::ast::{self, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
37+
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
3838
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
3939
use syntax::ext::hygiene::SyntaxContext;
4040
use syntax::ptr::P;
@@ -172,6 +172,18 @@ pub const DUMMY_HIR_ID: HirId = HirId {
172172

173173
pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId(!0);
174174

175+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
176+
pub struct Label {
177+
pub name: Name,
178+
pub span: Span,
179+
}
180+
181+
impl fmt::Debug for Label {
182+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
183+
write!(f, "label({:?})", self.name)
184+
}
185+
}
186+
175187
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
176188
pub struct Lifetime {
177189
pub id: NodeId,
@@ -1276,11 +1288,11 @@ pub enum Expr_ {
12761288
/// A while loop, with an optional label
12771289
///
12781290
/// `'label: while expr { block }`
1279-
ExprWhile(P<Expr>, P<Block>, Option<Spanned<Name>>),
1291+
ExprWhile(P<Expr>, P<Block>, Option<Label>),
12801292
/// Conditionless loop (can be exited with break, continue, or return)
12811293
///
12821294
/// `'label: loop { block }`
1283-
ExprLoop(P<Block>, Option<Spanned<Name>>, LoopSource),
1295+
ExprLoop(P<Block>, Option<Label>, LoopSource),
12841296
/// A `match` block, with a source that indicates whether or not it is
12851297
/// the result of a desugaring, and if so, which kind.
12861298
ExprMatch(P<Expr>, HirVec<Arm>, MatchSource),
@@ -1459,7 +1471,7 @@ impl ScopeTarget {
14591471
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
14601472
pub struct Destination {
14611473
// This is `Some(_)` iff there is an explicit user-specified `label
1462-
pub ident: Option<Spanned<Ident>>,
1474+
pub label: Option<Label>,
14631475

14641476
// These errors are caught and then reported during the diagnostics pass in
14651477
// librustc_passes/loops.rs

src/librustc/hir/print.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,19 +1337,19 @@ impl<'a> State<'a> {
13371337
hir::ExprIf(ref test, ref blk, ref elseopt) => {
13381338
self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?;
13391339
}
1340-
hir::ExprWhile(ref test, ref blk, opt_sp_name) => {
1341-
if let Some(sp_name) = opt_sp_name {
1342-
self.print_name(sp_name.node)?;
1340+
hir::ExprWhile(ref test, ref blk, opt_label) => {
1341+
if let Some(label) = opt_label {
1342+
self.print_name(label.name)?;
13431343
self.word_space(":")?;
13441344
}
13451345
self.head("while")?;
13461346
self.print_expr_as_cond(&test)?;
13471347
self.s.space()?;
13481348
self.print_block(&blk)?;
13491349
}
1350-
hir::ExprLoop(ref blk, opt_sp_name, _) => {
1351-
if let Some(sp_name) = opt_sp_name {
1352-
self.print_name(sp_name.node)?;
1350+
hir::ExprLoop(ref blk, opt_label, _) => {
1351+
if let Some(label) = opt_label {
1352+
self.print_name(label.name)?;
13531353
self.word_space(":")?;
13541354
}
13551355
self.head("loop")?;
@@ -1424,23 +1424,23 @@ impl<'a> State<'a> {
14241424
hir::ExprPath(ref qpath) => {
14251425
self.print_qpath(qpath, true)?
14261426
}
1427-
hir::ExprBreak(label, ref opt_expr) => {
1427+
hir::ExprBreak(destination, ref opt_expr) => {
14281428
self.s.word("break")?;
14291429
self.s.space()?;
1430-
if let Some(label_ident) = label.ident {
1431-
self.print_name(label_ident.node.name)?;
1430+
if let Some(label) = destination.label {
1431+
self.print_name(label.name)?;
14321432
self.s.space()?;
14331433
}
14341434
if let Some(ref expr) = *opt_expr {
14351435
self.print_expr_maybe_paren(expr, parser::PREC_JUMP)?;
14361436
self.s.space()?;
14371437
}
14381438
}
1439-
hir::ExprAgain(label) => {
1439+
hir::ExprAgain(destination) => {
14401440
self.s.word("continue")?;
14411441
self.s.space()?;
1442-
if let Some(label_ident) = label.ident {
1443-
self.print_name(label_ident.node.name)?;
1442+
if let Some(label) = destination.label {
1443+
self.print_name(label.name)?;
14441444
self.s.space()?
14451445
}
14461446
}

src/librustc/ich/impls_hir.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ impl_stable_hash_for!(enum hir::LifetimeName {
148148
Name(name)
149149
});
150150

151+
impl_stable_hash_for!(struct hir::Label {
152+
span,
153+
name
154+
});
155+
151156
impl_stable_hash_for!(struct hir::Lifetime {
152157
id,
153158
span,
@@ -614,7 +619,7 @@ impl_stable_hash_for!(enum hir::CaptureClause {
614619
impl_stable_hash_for_spanned!(usize);
615620

616621
impl_stable_hash_for!(struct hir::Destination {
617-
ident,
622+
label,
618623
target_id
619624
});
620625

src/librustc/middle/resolve_lifetime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) {
10181018
fn expression_label(ex: &hir::Expr) -> Option<(ast::Name, Span)> {
10191019
match ex.node {
10201020
hir::ExprWhile(.., Some(label)) | hir::ExprLoop(_, Some(label), _) => {
1021-
Some((label.node, label.span))
1021+
Some((label.name, label.span))
10221022
}
10231023
_ => None,
10241024
}

0 commit comments

Comments
 (0)