Support raw identifiers
diff --git a/src/stable.rs b/src/stable.rs
index d7d35d0..b4b7eae 100644
--- a/src/stable.rs
+++ b/src/stable.rs
@@ -652,6 +652,12 @@
         chars.next();
     }
 
+    let raw = !lifetime && input.starts_with("r#");
+    if raw {
+        chars.next();
+        chars.next();
+    }
+
     match chars.next() {
         Some((_, ch)) if UnicodeXID::is_xid_start(ch) || ch == '_' => {}
         _ => return Err(LexError),
@@ -665,15 +671,13 @@
         }
     }
 
-    if lifetime && &input.rest[..end] != "'static" && KEYWORDS.contains(&&input.rest[1..end]) {
+    let a = &input.rest[..end];
+    if a == "r#_" || lifetime && a != "'static" && KEYWORDS.contains(&&a[1..]) {
         Err(LexError)
+    } else if a == "_" {
+        Ok((input.advance(end), Op::new('_', Spacing::Alone).into()))
     } else {
-        let a = &input.rest[..end];
-        if a == "_" {
-            Ok((input.advance(end), Op::new('_', Spacing::Alone).into()))
-        } else {
-            Ok((input.advance(end), ::Term::new(a, ::Span::call_site()).into()))
-        }
+        Ok((input.advance(end), ::Term::new(a, ::Span::call_site()).into()))
     }
 }
 
diff --git a/tests/test.rs b/tests/test.rs
index 3b6bcc5..23ff04d 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1,8 +1,8 @@
 extern crate proc_macro2;
 
-use std::str;
+use std::str::{self, FromStr};
 
-use proc_macro2::{Term, Literal, TokenStream, Span};
+use proc_macro2::{Term, Literal, TokenStream, Span, TokenTree};
 
 #[test]
 fn symbols() {
@@ -66,6 +66,8 @@
     fail("1f320");
     fail("' static");
     fail("'mut");
+    fail("r#1");
+    fail("r#_");
 }
 
 #[cfg(procmacro2_semver_exempt)]
@@ -181,3 +183,12 @@
     }
 }
 
+#[test]
+fn raw_identifier() {
+    let mut tts = TokenStream::from_str("r#dyn").unwrap().into_iter();
+    match tts.next().unwrap() {
+        TokenTree::Term(raw) => assert_eq!("r#dyn", raw.as_str()),
+        wrong => panic!("wrong token {:?}", wrong),
+    }
+    assert!(tts.next().is_none());
+}