Support Attribute::parse_meta without printing feature
diff --git a/src/attr.rs b/src/attr.rs
index 9483ed4..17f4446 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -178,14 +178,18 @@
     /// possible.
     #[cfg(feature = "parsing")]
     pub fn parse_meta(&self) -> Result<Meta> {
-        use quote::ToTokens;
+        if let Some(ref colon) = self.path.leading_colon {
+            return Err(Error::new(colon.spans[0], "expected meta identifier"));
+        }
 
-        let mut tts = TokenStream::new();
+        let first_segment = self.path.segments.first().expect("paths have at least one segment");
+        if let Some(colon) = first_segment.punct() {
+            return Err(Error::new(colon.spans[0], "expected meta value"));
+        }
+        let ident = first_segment.value().ident.clone();
 
-        self.path.to_tokens(&mut tts);
-        self.tts.to_tokens(&mut tts);
-
-        ::parse2(tts)
+        let parser = |input: ParseStream| parsing::parse_meta_after_ident(ident, input);
+        parse::Parser::parse2(parser, self.tts.clone())
     }
 
     /// Parses zero or more outer attributes from the stream.
@@ -528,40 +532,22 @@
 
     impl Parse for Meta {
         fn parse(input: ParseStream) -> Result<Self> {
-            // Detect what kind of meta this is.
-            let ahead = input.fork();
-
-            // The first token must be an identifier
-            ahead.call(Ident::parse_any)?;
-
-            if ahead.peek(token::Paren) {
-                input.parse().map(Meta::List)
-            } else if ahead.peek(Token![=]) {
-                input.parse().map(Meta::NameValue)
-            } else {
-                input.call(Ident::parse_any).map(Meta::Word)
-            }
+            let ident = input.call(Ident::parse_any)?;
+            parse_meta_after_ident(ident, input)
         }
     }
 
     impl Parse for MetaList {
         fn parse(input: ParseStream) -> Result<Self> {
-            let content;
-            Ok(MetaList {
-                ident: input.call(Ident::parse_any)?,
-                paren_token: parenthesized!(content in input),
-                nested: content.parse_terminated(NestedMeta::parse)?,
-            })
+            let ident = input.call(Ident::parse_any)?;
+            parse_meta_list_after_ident(ident, input)
         }
     }
 
     impl Parse for MetaNameValue {
         fn parse(input: ParseStream) -> Result<Self> {
-            Ok(MetaNameValue {
-                ident: input.call(Ident::parse_any)?,
-                eq_token: input.parse()?,
-                lit: input.parse()?,
-            })
+            let ident = input.call(Ident::parse_any)?;
+            parse_meta_name_value_after_ident(ident, input)
         }
     }
 
@@ -578,6 +564,33 @@
             }
         }
     }
+
+    pub fn parse_meta_after_ident(ident: Ident, input: ParseStream) -> Result<Meta> {
+        if input.peek(token::Paren) {
+            parse_meta_list_after_ident(ident, input).map(Meta::List)
+        } else if input.peek(Token![=]) {
+            parse_meta_name_value_after_ident(ident, input).map(Meta::NameValue)
+        } else {
+            Ok(Meta::Word(ident))
+        }
+    }
+
+    fn parse_meta_list_after_ident(ident: Ident, input: ParseStream) -> Result<MetaList> {
+        let content;
+        Ok(MetaList {
+            ident: ident,
+            paren_token: parenthesized!(content in input),
+            nested: content.parse_terminated(NestedMeta::parse)?,
+        })
+    }
+
+    fn parse_meta_name_value_after_ident(ident: Ident, input: ParseStream) -> Result<MetaNameValue> {
+        Ok(MetaNameValue {
+            ident: ident,
+            eq_token: input.parse()?,
+            lit: input.parse()?,
+        })
+    }
 }
 
 #[cfg(feature = "printing")]