Print Underscore as Term

Backstory:

- To begin with, nightly treats `_` as an Op. Syn parses `_` patterns as
  PatWild and prints them back to tokens as Op.

- Nightly switches to treating `_` as Term and refuses to accept
  Op('_').

- Syn silently and retroactively on existing releases begins parsing `_`
  as PatIdent instead of PatWild, printing to tokens as Term. This is
  because the alt!(...) parser responsible for parsing syn::Pat attempts
  punct!(_) first which looks for an Op, then falls through to
  syn!(Ident) which looks for a Term. Code that uses punct!(_) breaks.
  However, code that parses a syn::Pat and prints it to tokens continues
  to work because nightly is happy with Term("_").

- Syn is updated to have punct!(_) accept Term("_") in addition to
  Op('_') as a fix for existing code broken by nightly.

- As a consequence of the fix, syn::Pat now returns to parsing `_` as
  PatWild rather than PatIdent. PatWild prints to tokens as Op('_') as
  it always did, but which trips an assertion on new nightlies.
diff --git a/src/token.rs b/src/token.rs
index 081ae1e..4ee82c4 100644
--- a/src/token.rs
+++ b/src/token.rs
@@ -332,9 +332,7 @@
 #[cfg(feature = "printing")]
 impl ::quote::ToTokens for Underscore {
     fn to_tokens(&self, tokens: &mut ::quote::Tokens) {
-        // FIXME: This should really be the following (see #408):
-        // tokens.append(::proc_macro2::Term::new("_", self.0[0]));
-        printing::punct("_", &self.0, tokens);
+        tokens.append(::proc_macro2::Term::new("_", self.0[0]));
     }
 }