Make a struct for loop labels
diff --git a/src/expr.rs b/src/expr.rs
index 55c2e4f..4cef442 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -132,8 +132,7 @@
/// E.g., `'label: while expr { block }`
pub While(ExprWhile #full {
pub attrs: Vec<Attribute>,
- pub label: Option<Lifetime>,
- pub colon_token: Option<Token![:]>,
+ pub label: Option<Label>,
pub while_token: Token![while],
pub cond: Box<Expr>,
pub body: Block,
@@ -146,8 +145,7 @@
/// This is desugared to a combination of `loop` and `match` expressions.
pub WhileLet(ExprWhileLet #full {
pub attrs: Vec<Attribute>,
- pub label: Option<Lifetime>,
- pub colon_token: Option<Token![:]>,
+ pub label: Option<Label>,
pub while_token: Token![while],
pub let_token: Token![let],
pub pat: Box<Pat>,
@@ -163,8 +161,7 @@
/// This is desugared to a combination of `loop` and `match` expressions.
pub ForLoop(ExprForLoop #full {
pub attrs: Vec<Attribute>,
- pub label: Option<Lifetime>,
- pub colon_token: Option<Token![:]>,
+ pub label: Option<Label>,
pub for_token: Token![for],
pub pat: Box<Pat>,
pub in_token: Token![in],
@@ -177,8 +174,7 @@
/// E.g. `'label: loop { block }`
pub Loop(ExprLoop #full {
pub attrs: Vec<Attribute>,
- pub label: Option<Lifetime>,
- pub colon_token: Option<Token![:]>,
+ pub label: Option<Label>,
pub loop_token: Token![loop],
pub body: Block,
}),
@@ -547,6 +543,14 @@
#[cfg(feature = "full")]
ast_struct! {
+ pub struct Label {
+ pub name: Lifetime,
+ pub colon_token: Token![:],
+ }
+}
+
+#[cfg(feature = "full")]
+ast_struct! {
/// A Block (`{ .. }`).
///
/// E.g. `{ .. }` as in `fn foo() { .. }`
@@ -1576,7 +1580,7 @@
#[cfg(feature = "full")]
impl Synom for ExprForLoop {
named!(parse -> Self, do_parse!(
- lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
+ label: option!(syn!(Label)) >>
for_: keyword!(for) >>
pat: syn!(Pat) >>
in_: keyword!(in) >>
@@ -1589,8 +1593,7 @@
pat: Box::new(pat),
expr: Box::new(expr),
body: loop_block,
- colon_token: lbl.as_ref().map(|p| Token.0)),
- label: lbl.map(|p| p.0),
+ label: label,
})
));
}
@@ -1598,15 +1601,14 @@
#[cfg(feature = "full")]
impl Synom for ExprLoop {
named!(parse -> Self, do_parse!(
- lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
+ label: option!(syn!(Label)) >>
loop_: keyword!(loop) >>
loop_block: syn!(Block) >>
(ExprLoop {
attrs: Vec::new(),
loop_token: loop_,
body: loop_block,
- colon_token: lbl.as_ref().map(|p| Token.0)),
- label: lbl.map(|p| p.0),
+ label: label,
})
));
}
@@ -1738,17 +1740,16 @@
#[cfg(feature = "full")]
impl Synom for ExprWhile {
named!(parse -> Self, do_parse!(
- lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
+ label: option!(syn!(Label)) >>
while_: keyword!(while) >>
cond: expr_no_struct >>
while_block: syn!(Block) >>
(ExprWhile {
attrs: Vec::new(),
while_token: while_,
- colon_token: lbl.as_ref().map(|p| Token.0)),
cond: Box::new(cond),
body: while_block,
- label: lbl.map(|p| p.0),
+ label: label,
})
));
}
@@ -1756,7 +1757,7 @@
#[cfg(feature = "full")]
impl Synom for ExprWhileLet {
named!(parse -> Self, do_parse!(
- lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
+ label: option!(syn!(Label)) >>
while_: keyword!(while) >>
let_: keyword!(let) >>
pat: syn!(Pat) >>
@@ -1768,11 +1769,22 @@
eq_token: eq,
let_token: let_,
while_token: while_,
- colon_token: lbl.as_ref().map(|p| Token.0)),
pat: Box::new(pat),
expr: Box::new(value),
body: while_block,
- label: lbl.map(|p| p.0),
+ label: label,
+ })
+ ));
+ }
+
+ #[cfg(feature = "full")]
+ impl Synom for Label {
+ named!(parse -> Self, do_parse!(
+ name: syn!(Lifetime) >>
+ colon: punct!(:) >>
+ (Label {
+ name: name,
+ colon_token: colon,
})
));
}
@@ -1781,11 +1793,11 @@
impl Synom for ExprContinue {
named!(parse -> Self, do_parse!(
cont: keyword!(continue) >>
- lbl: option!(syn!(Lifetime)) >>
+ label: option!(syn!(Lifetime)) >>
(ExprContinue {
attrs: Vec::new(),
continue_token: cont,
- label: lbl,
+ label: label,
})
));
}
@@ -1793,13 +1805,13 @@
#[cfg(feature = "full")]
named!(expr_break(allow_struct: bool) -> Expr, do_parse!(
break_: keyword!(break) >>
- lbl: option!(syn!(Lifetime)) >>
+ label: option!(syn!(Lifetime)) >>
// We can't allow blocks after a `break` expression when we wouldn't
// allow structs, as this expression is ambiguous.
val: opt_ambiguous_expr!(allow_struct) >>
(ExprBreak {
attrs: Vec::new(),
- label: lbl,
+ label: label,
expr: val.map(Box::new),
break_token: break_,
}.into())
@@ -2636,10 +2648,7 @@
impl ToTokens for ExprWhile {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
- if self.label.is_some() {
- self.label.to_tokens(tokens);
- TokensOrDefault(&self.colon_token).to_tokens(tokens);
- }
+ self.label.to_tokens(tokens);
self.while_token.to_tokens(tokens);
wrap_bare_struct(tokens, &self.cond);
self.body.to_tokens(tokens);
@@ -2650,10 +2659,7 @@
impl ToTokens for ExprWhileLet {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
- if self.label.is_some() {
- self.label.to_tokens(tokens);
- TokensOrDefault(&self.colon_token).to_tokens(tokens);
- }
+ self.label.to_tokens(tokens);
self.while_token.to_tokens(tokens);
self.let_token.to_tokens(tokens);
self.pat.to_tokens(tokens);
@@ -2667,10 +2673,7 @@
impl ToTokens for ExprForLoop {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
- if self.label.is_some() {
- self.label.to_tokens(tokens);
- TokensOrDefault(&self.colon_token).to_tokens(tokens);
- }
+ self.label.to_tokens(tokens);
self.for_token.to_tokens(tokens);
self.pat.to_tokens(tokens);
self.in_token.to_tokens(tokens);
@@ -2683,10 +2686,7 @@
impl ToTokens for ExprLoop {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
- if self.label.is_some() {
- self.label.to_tokens(tokens);
- TokensOrDefault(&self.colon_token).to_tokens(tokens);
- }
+ self.label.to_tokens(tokens);
self.loop_token.to_tokens(tokens);
self.body.to_tokens(tokens);
}
@@ -2962,6 +2962,14 @@
}
#[cfg(feature = "full")]
+ impl ToTokens for Label {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.name.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg(feature = "full")]
impl ToTokens for FieldValue {
fn to_tokens(&self, tokens: &mut Tokens) {
self.member.to_tokens(tokens);
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index a33d1d6..1f60d88 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -239,6 +239,8 @@
fn fold_item_use(&mut self, i: ItemUse) -> ItemUse { fold_item_use(self, i) }
# [ cfg ( feature = "full" ) ]
fn fold_item_verbatim(&mut self, i: ItemVerbatim) -> ItemVerbatim { fold_item_verbatim(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn fold_label(&mut self, i: Label) -> Label { fold_label(self, i) }
fn fold_lifetime(&mut self, i: Lifetime) -> Lifetime { fold_lifetime(self, i) }
@@ -1065,8 +1067,7 @@
pub fn fold_expr_for_loop<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprForLoop) -> ExprForLoop {
ExprForLoop {
attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
- label: (_i . label).map(|it| { _visitor.fold_lifetime(it) }),
- colon_token: (_i . colon_token).map(|it| { Token ! [ : ](tokens_helper(_visitor, &(it).0)) }),
+ label: (_i . label).map(|it| { _visitor.fold_label(it) }),
for_token: Token ! [ for ](tokens_helper(_visitor, &(_i . for_token).0)),
pat: Box::new(_visitor.fold_pat(* _i . pat)),
in_token: Token ! [ in ](tokens_helper(_visitor, &(_i . in_token).0)),
@@ -1140,8 +1141,7 @@
pub fn fold_expr_loop<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprLoop) -> ExprLoop {
ExprLoop {
attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
- label: (_i . label).map(|it| { _visitor.fold_lifetime(it) }),
- colon_token: (_i . colon_token).map(|it| { Token ! [ : ](tokens_helper(_visitor, &(it).0)) }),
+ label: (_i . label).map(|it| { _visitor.fold_label(it) }),
loop_token: Token ! [ loop ](tokens_helper(_visitor, &(_i . loop_token).0)),
body: _visitor.fold_block(_i . body),
}
@@ -1280,8 +1280,7 @@
pub fn fold_expr_while<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprWhile) -> ExprWhile {
ExprWhile {
attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
- label: (_i . label).map(|it| { _visitor.fold_lifetime(it) }),
- colon_token: (_i . colon_token).map(|it| { Token ! [ : ](tokens_helper(_visitor, &(it).0)) }),
+ label: (_i . label).map(|it| { _visitor.fold_label(it) }),
while_token: Token ! [ while ](tokens_helper(_visitor, &(_i . while_token).0)),
cond: Box::new(_visitor.fold_expr(* _i . cond)),
body: _visitor.fold_block(_i . body),
@@ -1291,8 +1290,7 @@
pub fn fold_expr_while_let<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprWhileLet) -> ExprWhileLet {
ExprWhileLet {
attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
- label: (_i . label).map(|it| { _visitor.fold_lifetime(it) }),
- colon_token: (_i . colon_token).map(|it| { Token ! [ : ](tokens_helper(_visitor, &(it).0)) }),
+ label: (_i . label).map(|it| { _visitor.fold_label(it) }),
while_token: Token ! [ while ](tokens_helper(_visitor, &(_i . while_token).0)),
let_token: Token ! [ let ](tokens_helper(_visitor, &(_i . let_token).0)),
pat: Box::new(_visitor.fold_pat(* _i . pat)),
@@ -1901,6 +1899,13 @@
tts: _i . tts,
}
}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_label<V: Folder + ?Sized>(_visitor: &mut V, _i: Label) -> Label {
+ Label {
+ name: _visitor.fold_lifetime(_i . name),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i . colon_token).0)),
+ }
+}
pub fn fold_lifetime_def<V: Folder + ?Sized>(_visitor: &mut V, _i: LifetimeDef) -> LifetimeDef {
LifetimeDef {
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index d5b63ae..df1f9d6 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -235,6 +235,8 @@
fn visit_item_use(&mut self, i: &'ast ItemUse) { visit_item_use(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_item_verbatim(&mut self, i: &'ast ItemVerbatim) { visit_item_verbatim(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_label(&mut self, i: &'ast Label) { visit_label(self, i) }
fn visit_lifetime(&mut self, i: &'ast Lifetime) { visit_lifetime(self, i) }
@@ -846,8 +848,7 @@
# [ cfg ( feature = "full" ) ]
pub fn visit_expr_for_loop<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprForLoop) {
for it in & _i . attrs { _visitor.visit_attribute(it) };
- if let Some(ref it) = _i . label { _visitor.visit_lifetime(it) };
- if let Some(ref it) = _i . colon_token { tokens_helper(_visitor, &(it).0) };
+ if let Some(ref it) = _i . label { _visitor.visit_label(it) };
tokens_helper(_visitor, &(& _i . for_token).0);
_visitor.visit_pat(& * _i . pat);
tokens_helper(_visitor, &(& _i . in_token).0);
@@ -907,8 +908,7 @@
# [ cfg ( feature = "full" ) ]
pub fn visit_expr_loop<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprLoop) {
for it in & _i . attrs { _visitor.visit_attribute(it) };
- if let Some(ref it) = _i . label { _visitor.visit_lifetime(it) };
- if let Some(ref it) = _i . colon_token { tokens_helper(_visitor, &(it).0) };
+ if let Some(ref it) = _i . label { _visitor.visit_label(it) };
tokens_helper(_visitor, &(& _i . loop_token).0);
_visitor.visit_block(& _i . body);
}
@@ -1015,8 +1015,7 @@
# [ cfg ( feature = "full" ) ]
pub fn visit_expr_while<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprWhile) {
for it in & _i . attrs { _visitor.visit_attribute(it) };
- if let Some(ref it) = _i . label { _visitor.visit_lifetime(it) };
- if let Some(ref it) = _i . colon_token { tokens_helper(_visitor, &(it).0) };
+ if let Some(ref it) = _i . label { _visitor.visit_label(it) };
tokens_helper(_visitor, &(& _i . while_token).0);
_visitor.visit_expr(& * _i . cond);
_visitor.visit_block(& _i . body);
@@ -1024,8 +1023,7 @@
# [ cfg ( feature = "full" ) ]
pub fn visit_expr_while_let<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprWhileLet) {
for it in & _i . attrs { _visitor.visit_attribute(it) };
- if let Some(ref it) = _i . label { _visitor.visit_lifetime(it) };
- if let Some(ref it) = _i . colon_token { tokens_helper(_visitor, &(it).0) };
+ if let Some(ref it) = _i . label { _visitor.visit_label(it) };
tokens_helper(_visitor, &(& _i . while_token).0);
tokens_helper(_visitor, &(& _i . let_token).0);
_visitor.visit_pat(& * _i . pat);
@@ -1494,6 +1492,11 @@
pub fn visit_item_verbatim<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ItemVerbatim) {
// Skipped field _i . tts;
}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_label<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Label) {
+ _visitor.visit_lifetime(& _i . name);
+ tokens_helper(_visitor, &(& _i . colon_token).0);
+}
pub fn visit_lifetime<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Lifetime) {
// Skipped field _i . sym;
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index d48e04f..d8f10fa 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -235,6 +235,8 @@
fn visit_item_use_mut(&mut self, i: &mut ItemUse) { visit_item_use_mut(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_item_verbatim_mut(&mut self, i: &mut ItemVerbatim) { visit_item_verbatim_mut(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_label_mut(&mut self, i: &mut Label) { visit_label_mut(self, i) }
fn visit_lifetime_mut(&mut self, i: &mut Lifetime) { visit_lifetime_mut(self, i) }
@@ -846,8 +848,7 @@
# [ cfg ( feature = "full" ) ]
pub fn visit_expr_for_loop_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ExprForLoop) {
for it in & mut _i . attrs { _visitor.visit_attribute_mut(it) };
- if let Some(ref mut it) = _i . label { _visitor.visit_lifetime_mut(it) };
- if let Some(ref mut it) = _i . colon_token { tokens_helper(_visitor, &mut (it).0) };
+ if let Some(ref mut it) = _i . label { _visitor.visit_label_mut(it) };
tokens_helper(_visitor, &mut (& mut _i . for_token).0);
_visitor.visit_pat_mut(& mut * _i . pat);
tokens_helper(_visitor, &mut (& mut _i . in_token).0);
@@ -907,8 +908,7 @@
# [ cfg ( feature = "full" ) ]
pub fn visit_expr_loop_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ExprLoop) {
for it in & mut _i . attrs { _visitor.visit_attribute_mut(it) };
- if let Some(ref mut it) = _i . label { _visitor.visit_lifetime_mut(it) };
- if let Some(ref mut it) = _i . colon_token { tokens_helper(_visitor, &mut (it).0) };
+ if let Some(ref mut it) = _i . label { _visitor.visit_label_mut(it) };
tokens_helper(_visitor, &mut (& mut _i . loop_token).0);
_visitor.visit_block_mut(& mut _i . body);
}
@@ -1015,8 +1015,7 @@
# [ cfg ( feature = "full" ) ]
pub fn visit_expr_while_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ExprWhile) {
for it in & mut _i . attrs { _visitor.visit_attribute_mut(it) };
- if let Some(ref mut it) = _i . label { _visitor.visit_lifetime_mut(it) };
- if let Some(ref mut it) = _i . colon_token { tokens_helper(_visitor, &mut (it).0) };
+ if let Some(ref mut it) = _i . label { _visitor.visit_label_mut(it) };
tokens_helper(_visitor, &mut (& mut _i . while_token).0);
_visitor.visit_expr_mut(& mut * _i . cond);
_visitor.visit_block_mut(& mut _i . body);
@@ -1024,8 +1023,7 @@
# [ cfg ( feature = "full" ) ]
pub fn visit_expr_while_let_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ExprWhileLet) {
for it in & mut _i . attrs { _visitor.visit_attribute_mut(it) };
- if let Some(ref mut it) = _i . label { _visitor.visit_lifetime_mut(it) };
- if let Some(ref mut it) = _i . colon_token { tokens_helper(_visitor, &mut (it).0) };
+ if let Some(ref mut it) = _i . label { _visitor.visit_label_mut(it) };
tokens_helper(_visitor, &mut (& mut _i . while_token).0);
tokens_helper(_visitor, &mut (& mut _i . let_token).0);
_visitor.visit_pat_mut(& mut * _i . pat);
@@ -1494,6 +1492,11 @@
pub fn visit_item_verbatim_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemVerbatim) {
// Skipped field _i . tts;
}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_label_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut Label) {
+ _visitor.visit_lifetime_mut(& mut _i . name);
+ tokens_helper(_visitor, &mut (& mut _i . colon_token).0);
+}
pub fn visit_lifetime_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut Lifetime) {
// Skipped field _i . sym;
diff --git a/src/lib.rs b/src/lib.rs
index 4847af5..65183a1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -41,7 +41,7 @@
ExprUnary, ExprUnsafe, ExprVerbatim, ExprWhile, ExprWhileLet, ExprYield, Index, Member};
#[cfg(feature = "full")]
-pub use expr::{Arm, Block, FieldPat, FieldValue, GenericMethodArgument, Local,
+pub use expr::{Arm, Block, FieldPat, FieldValue, GenericMethodArgument, Label, Local,
MethodTurbofish, Pat, PatBox, PatIdent, PatLit, PatMacro, PatPath, PatRange, PatRef, PatSlice,
PatStruct, PatTuple, PatTupleStruct, PatVerbatim, PatWild, RangeLimits, Stmt};