Implement some atom exprs
diff --git a/src/path.rs b/src/path.rs
index c2ad34a..d7be9e6 100644
--- a/src/path.rs
+++ b/src/path.rs
@@ -232,14 +232,7 @@
impl Parse for Path {
fn parse(input: ParseStream) -> Result<Self> {
- if input.peek(Token![dyn]) {
- return Err(input.error("expected path"));
- }
-
- Ok(Path {
- leading_colon: input.parse()?,
- segments: input.parse_synom(Punctuated::parse_separated_nonempty)?,
- })
+ Self::parse_helper(input, false)
}
}
@@ -256,12 +249,12 @@
#[cfg(feature = "full")]
{
if input.peek(Lit) {
- let lit = input.parse_synom(ExprLit::parse)?;
+ let lit: ExprLit = input.parse()?;
return Ok(GenericArgument::Const(Expr::Lit(lit)));
}
if input.peek(token::Brace) {
- let block = input.parse_synom(ExprBlock::parse)?;
+ let block: ExprBlock = input.parse()?;
return Ok(GenericArgument::Const(Expr::Block(block)));
}
}
@@ -309,6 +302,12 @@
impl Parse for PathSegment {
fn parse(input: ParseStream) -> Result<Self> {
+ Self::parse_helper(input, false)
+ }
+ }
+
+ impl PathSegment {
+ fn parse_helper(input: ParseStream, expr_style: bool) -> Result<Self> {
if input.peek(Token![super])
|| input.peek(Token![self])
|| input.peek(Token![Self])
@@ -320,7 +319,7 @@
}
let ident = input.parse()?;
- if input.peek(Token![<]) && !input.peek(Token![<=])
+ if !expr_style && input.peek(Token![<]) && !input.peek(Token![<=])
|| input.peek(Token![::]) && input.peek3(Token![<])
{
Ok(PathSegment {
@@ -377,6 +376,28 @@
})
}
+ fn parse_helper(input: ParseStream, expr_style: bool) -> Result<Self> {
+ if input.peek(Token![dyn]) {
+ return Err(input.error("expected path"));
+ }
+
+ Ok(Path {
+ leading_colon: input.parse()?,
+ segments: {
+ let mut segments = Punctuated::new();
+ let value = PathSegment::parse_helper(input, expr_style)?;
+ segments.push_value(value);
+ while input.peek(Token![::]) {
+ let punct: Token![::] = input.parse()?;
+ segments.push_punct(punct);
+ let value = PathSegment::parse_helper(input, expr_style)?;
+ segments.push_value(value);
+ }
+ segments
+ },
+ })
+ }
+
named!(pub old_parse_mod_style -> Self, do_parse!(
colon: option!(punct!(::)) >>
segments: call!(Punctuated::parse_separated_nonempty_with,
@@ -388,6 +409,58 @@
));
}
+ pub fn qpath(input: ParseStream, expr_style: bool) -> Result<(Option<QSelf>, Path)> {
+ if input.peek(Token![<]) {
+ let lt_token: Token![<] = input.parse()?;
+ let this: Type = input.parse()?;
+ let path = if input.peek(Token![as]) {
+ let as_token: Token![as] = input.parse()?;
+ let path: Path = input.parse()?;
+ Some((as_token, path))
+ } else {
+ None
+ };
+ let gt_token: Token![>] = input.parse()?;
+ let colon2_token: Token![::] = input.parse()?;
+ let mut rest = Punctuated::new();
+ loop {
+ let path = PathSegment::parse_helper(input, expr_style)?;
+ rest.push_value(path);
+ if !input.peek(Token![::]) {
+ break;
+ }
+ let punct: Token![::] = input.parse()?;
+ rest.push_punct(punct);
+ }
+ let (position, as_token, path) = match path {
+ Some((as_token, mut path)) => {
+ let pos = path.segments.len();
+ path.segments.push_punct(colon2_token);
+ path.segments.extend(rest.into_pairs());
+ (pos, Some(as_token), path)
+ }
+ None => {
+ let path = Path {
+ leading_colon: Some(colon2_token),
+ segments: rest,
+ };
+ (0, None, path)
+ }
+ };
+ let qself = QSelf {
+ lt_token: lt_token,
+ ty: Box::new(this),
+ position: position,
+ as_token: as_token,
+ gt_token: gt_token,
+ };
+ Ok((Some(qself), path))
+ } else {
+ let path = Path::parse_helper(input, expr_style)?;
+ Ok((None, path))
+ }
+ }
+
// FIXME
/*
pub fn mod_style_path_segment(input: ParseStream) -> Result<PathSegment> {