Support method turbofish with const generics
diff --git a/src/expr.rs b/src/expr.rs
index 016d063..76c666f 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -48,10 +48,7 @@
             pub receiver: Box<Expr>,
             pub dot_token: Token![.],
             pub method: Ident,
-            pub colon2_token: Option<Token![::]>,
-            pub lt_token: Option<Token![<]>,
-            pub typarams: Delimited<Type, Token![,]>,
-            pub gt_token: Option<Token![>]>,
+            pub turbofish: Option<MethodTurbofish>,
             pub paren_token: token::Paren,
             pub args: Delimited<Expr, Token![,]>,
         }),
@@ -468,6 +465,30 @@
 
 #[cfg(feature = "full")]
 ast_struct! {
+    pub struct MethodTurbofish {
+        pub colon2_token: Token![::],
+        pub lt_token: Token![<],
+        pub args: Delimited<GenericMethodArgument, Token![,]>,
+        pub gt_token: Token![>],
+    }
+}
+
+#[cfg(feature = "full")]
+ast_enum! {
+    /// A individual generic argument like `T`.
+    pub enum GenericMethodArgument {
+        /// The type parameters for this path segment, if present.
+        Type(Type),
+        /// Const expression. Must be inside of a block.
+        ///
+        /// NOTE: Identity expressions are represented as Type arguments, as
+        /// they are indistinguishable syntactically.
+        Const(Expr),
+    }
+}
+
+#[cfg(feature = "full")]
+ast_struct! {
     /// A field-value pair in a struct literal.
     pub struct FieldValue {
         /// Attributes tagged on the field.
@@ -727,7 +748,7 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use ty::parsing::qpath;
+    use ty::parsing::{qpath, ty_no_eq_after};
 
     #[cfg(feature = "full")]
     use proc_macro2::{Delimiter, Span, TokenNode, TokenStream};
@@ -1388,19 +1409,14 @@
     named!(and_method_call -> ExprMethodCall, do_parse!(
         dot: punct!(.) >>
         method: syn!(Ident) >>
-        typarams: option!(do_parse!(
-            colon2: punct!(::) >>
-            lt: punct!(<) >>
-            tys: call!(Delimited::parse_terminated) >>
-            gt: punct!(>) >>
-            (colon2, lt, tys, gt)
+        turbofish: option!(tuple!(
+            punct!(::),
+            punct!(<),
+            call!(Delimited::parse_terminated),
+            punct!(>)
         )) >>
         args: parens!(call!(Delimited::parse_terminated)) >>
         ({
-            let (colon2, lt, tys, gt) = match typarams {
-                Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
-                None => (None, None, None, None),
-            };
             ExprMethodCall {
                 attrs: Vec::new(),
                 // this expr will get overwritten after being returned
@@ -1413,18 +1429,26 @@
                 }).into()),
 
                 method: method,
+                turbofish: turbofish.map(|fish| MethodTurbofish {
+                    colon2_token: fish.0,
+                    lt_token: fish.1,
+                    args: fish.2,
+                    gt_token: fish.3,
+                }),
                 args: args.0,
                 paren_token: args.1,
                 dot_token: dot,
-                lt_token: lt,
-                gt_token: gt,
-                colon2_token: colon2,
-                typarams: tys.unwrap_or_default(),
             }
         })
     ));
 
     #[cfg(feature = "full")]
+    impl Synom for GenericMethodArgument {
+        // TODO parse const generics as well
+        named!(parse -> Self, map!(ty_no_eq_after, GenericMethodArgument::Type));
+    }
+
+    #[cfg(feature = "full")]
     impl Synom for ExprTuple {
         named!(parse -> Self, do_parse!(
             elems: parens!(call!(Delimited::parse_terminated)) >>
@@ -2452,12 +2476,7 @@
             self.receiver.to_tokens(tokens);
             self.dot_token.to_tokens(tokens);
             self.method.to_tokens(tokens);
-            if !self.typarams.is_empty() {
-                TokensOrDefault(&self.colon2_token).to_tokens(tokens);
-                TokensOrDefault(&self.lt_token).to_tokens(tokens);
-                self.typarams.to_tokens(tokens);
-                TokensOrDefault(&self.gt_token).to_tokens(tokens);
-            }
+            self.turbofish.to_tokens(tokens);
             self.paren_token.surround(tokens, |tokens| {
                 self.args.to_tokens(tokens);
             });
@@ -2465,6 +2484,26 @@
     }
 
     #[cfg(feature = "full")]
+    impl ToTokens for MethodTurbofish {
+        fn to_tokens(&self, tokens: &mut Tokens) {
+            self.colon2_token.to_tokens(tokens);
+            self.lt_token.to_tokens(tokens);
+            self.args.to_tokens(tokens);
+            self.gt_token.to_tokens(tokens);
+        }
+    }
+
+    #[cfg(feature = "full")]
+    impl ToTokens for GenericMethodArgument {
+        fn to_tokens(&self, tokens: &mut Tokens) {
+            match *self {
+                GenericMethodArgument::Type(ref t) => t.to_tokens(tokens),
+                GenericMethodArgument::Const(ref c) => c.to_tokens(tokens),
+            }
+        }
+    }
+
+    #[cfg(feature = "full")]
     impl ToTokens for ExprTuple {
         fn to_tokens(&self, tokens: &mut Tokens) {
             tokens.append_all(self.attrs.outer());