Fix up some final issues
diff --git a/Cargo.toml b/Cargo.toml
index ce4d8d9..68f8b4e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,7 +30,7 @@
 
 [dependencies]
 proc-macro2 = { version = "0.4.1", default-features = false }
-quote = { version = "0.6", optional = true, default-features = false }
+quote = { version = "0.5", optional = true, default-features = false }
 unicode-xid = "0.1"
 
 [dev-dependencies]
@@ -44,4 +44,4 @@
 all-features = true
 
 [patch.crates-io]
-quote = { git = 'https://github.com/alexcrichton/quote', branch = 'next' }
+quote = { git = 'https://github.com/dtolnay/quote' }
diff --git a/src/synom.rs b/src/synom.rs
index 553c959..b68b07f 100644
--- a/src/synom.rs
+++ b/src/synom.rs
@@ -155,6 +155,7 @@
 use proc_macro2;
 
 pub use error::{PResult, ParseError};
+use error::parse_error;
 
 use buffer::{Cursor, TokenBuffer};
 
@@ -214,13 +215,30 @@
 }
 
 impl Synom for proc_macro2::Ident {
-    fn parse(input: Cursor) -> PResult<Self> {
-        input.term().ok_or_else(|| ParseError::new("not an ident"))
-    }
+	fn parse(input: Cursor) -> PResult<Self> {
+		let (term, rest) = match input.term() {
+			Some(term) => term,
+			_ => return parse_error(),
+		};
+		match &term.to_string()[..] {
+			"_"
+			// From https://doc.rust-lang.org/grammar.html#keywords
+			| "abstract" | "alignof" | "as" | "become" | "box" | "break" | "const"
+			| "continue" | "crate" | "do" | "else" | "enum" | "extern" | "false" | "final"
+			| "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" | "match"
+			| "mod" | "move" | "mut" | "offsetof" | "override" | "priv" | "proc" | "pub"
+			| "pure" | "ref" | "return" | "Self" | "self" | "sizeof" | "static" | "struct"
+			| "super" | "trait" | "true" | "type" | "typeof" | "unsafe" | "unsized" | "use"
+			| "virtual" | "where" | "while" | "yield" => return parse_error(),
+			_ => {}
+		}
 
-    fn description() -> Option<&'static str> {
-        Some("arbitrary token stream")
-    }
+		Ok((term, rest))
+	}
+
+	fn description() -> Option<&'static str> {
+		Some("identifier")
+	}
 }
 
 /// Parser that can parse Rust tokens into a particular syntax tree node.
diff --git a/tests/common/mod.rs b/tests/common/mod.rs
index cc7039c..508389f 100644
--- a/tests/common/mod.rs
+++ b/tests/common/mod.rs
@@ -21,8 +21,13 @@
 pub mod respan;
 
 pub fn check_min_stack() {
-    let min_stack_value = env::var("RUST_MIN_STACK")
-        .expect("RUST_MIN_STACK env var should be set since some tests require it.");
+    let min_stack_value = match env::var("RUST_MIN_STACK") {
+        Ok(s) => s,
+        Err(_) => {
+            env::set_var("RUST_MIN_STACK", 16000000.to_string());
+            return
+        }
+    };
     let min_stack_value: usize = min_stack_value
         .parse()
         .expect("RUST_MIN_STACK env var should be set since some tests require it.");
diff --git a/tests/test_ident.rs b/tests/test_ident.rs
index 99596a6..cb0b2f4 100644
--- a/tests/test_ident.rs
+++ b/tests/test_ident.rs
@@ -28,7 +28,7 @@
 
 #[test]
 fn ident_parse_keyword() {
-    parse("abstract").unwrap();
+    parse("abstract").unwrap_err();
 }
 
 #[test]
@@ -43,7 +43,7 @@
 
 #[test]
 fn ident_parse_underscore() {
-    parse("_").unwrap();
+    parse("_").unwrap_err();
 }
 
 #[test]
diff --git a/tests/test_round_trip.rs b/tests/test_round_trip.rs
index 92e84e5..4659be4 100644
--- a/tests/test_round_trip.rs
+++ b/tests/test_round_trip.rs
@@ -120,10 +120,10 @@
                         true
                     } else {
                         errorf!(
-                            "=== {}: FAIL\nbefore: {}\nafter: {}\n",
+                            "=== {}: FAIL\nbefore: {:#?}\nafter: {:#?}\n",
                             path.display(),
-                            format!("{:?}", before).replace("\n", ""),
-                            format!("{:?}", after).replace("\n", "")
+                            before,
+                            after,
                         );
                         false
                     }