Correctly parse InPlace <- expressions
diff --git a/src/expr.rs b/src/expr.rs
index 32783e1..fa7872b 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -32,8 +32,8 @@
/// E.g. 'place <- val' or `in place { val }`.
pub InPlace(ExprInPlace {
pub place: Box<Expr>,
+ pub kind: InPlaceKind,
pub value: Box<Expr>,
- pub in_token: tokens::In,
}),
/// An array, e.g. `[a, b, c, d]`.
@@ -584,6 +584,14 @@
}
}
+ast_enum! {
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
+ pub enum InPlaceKind {
+ Arrow(tokens::LArrow),
+ In(tokens::In),
+ }
+}
+
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
@@ -730,17 +738,15 @@
mut e: call!(range_expr, allow_struct, allow_block) >>
alt!(
do_parse!(
- syn!(LArrow) >>
+ arrow: syn!(LArrow) >>
// Recurse into self to parse right-associative operator.
rhs: call!(placement_expr, allow_struct, true) >>
({
- // XXX: Stop transforming the <- syntax into the InPlace
- // syntax.
e = ExprInPlace {
// op: BinOp::Place(larrow),
place: Box::new(e.into()),
+ kind: InPlaceKind::Arrow(arrow),
value: Box::new(rhs.into()),
- in_token: tokens::In::default(),
}.into();
})
)
@@ -813,7 +819,12 @@
// must be above Gt
syn!(Ge) => { BinOp::Ge }
|
- syn!(Lt) => { BinOp::Lt }
+ do_parse!(
+ // Make sure that we don't eat the < part of a <- operator
+ not!(syn!(LArrow)) >>
+ t: syn!(Lt) >>
+ (BinOp::Lt(t))
+ )
|
syn!(Gt) => { BinOp::Gt }
));
@@ -1091,8 +1102,8 @@
place: expr_no_struct >>
value: braces!(call!(Block::parse_within)) >>
(ExprInPlace {
- in_token: in_,
place: Box::new(place),
+ kind: InPlaceKind::In(in_),
value: Box::new(Expr {
node: ExprBlock {
unsafety: Unsafety::Normal,
@@ -2059,9 +2070,18 @@
impl ToTokens for ExprInPlace {
fn to_tokens(&self, tokens: &mut Tokens) {
- self.in_token.to_tokens(tokens);
- self.place.to_tokens(tokens);
- self.value.to_tokens(tokens);
+ match self.kind {
+ InPlaceKind::Arrow(ref arrow) => {
+ self.place.to_tokens(tokens);
+ arrow.to_tokens(tokens);
+ self.value.to_tokens(tokens);
+ }
+ InPlaceKind::In(ref _in) => {
+ _in.to_tokens(tokens);
+ self.place.to_tokens(tokens);
+ self.value.to_tokens(tokens);
+ }
+ }
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 8c55d64..faab98f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -38,7 +38,7 @@
ExprRange, ExprPath, ExprAddrOf, ExprBreak, ExprContinue,
ExprRet, ExprStruct, ExprRepeat, ExprParen, ExprTry, ExprCatch,
PatIdent, PatWild, PatStruct, PatTuple, PatTupleStruct, PatPath,
- PatBox, PatRef, PatLit, PatRange, PatSlice};
+ PatBox, PatRef, PatLit, PatRange, PatSlice, InPlaceKind};
mod generics;
pub use generics::{Generics, LifetimeDef, TraitBoundModifier, TyParam, TyParamBound,
diff --git a/src/ty.rs b/src/ty.rs
index 1f9717e..e4e062e 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -337,7 +337,7 @@
/// contain a `+` character.
///
/// This parser does not allow a `+`, while the default parser does.
- named!(without_plus -> Self, call!(ambig_ty, false));
+ named!(pub without_plus -> Self, call!(ambig_ty, false));
}
named!(ambig_ty(allow_plus: bool) -> Ty, alt!(
diff --git a/tests/test_round_trip.rs b/tests/test_round_trip.rs
index 5525482..1e8fc74 100644
--- a/tests/test_round_trip.rs
+++ b/tests/test_round_trip.rs
@@ -54,18 +54,8 @@
}
match path_string.as_ref() {
- // TODO placement syntax
- "tests/rust/src/libcollections/tests/binary_heap.rs" |
- // TODO placement syntax
- "tests/rust/src/libcollections/tests/vec.rs" |
- // TODO placement syntax
- "tests/rust/src/libcollections/tests/vec_deque.rs" |
// TODO better support for attributes
"tests/rust/src/librustc_data_structures/blake2b.rs" |
- // TODO placement syntax
- "tests/rust/src/librustc_mir/build/matches/test.rs" |
- // TODO placement syntax
- "tests/rust/src/libstd/collections/hash/map.rs" |
// TODO better support for attributes
"tests/rust/src/test/incremental/hashes/enum_defs.rs" |
// TODO better support for attributes