Automatically use rich API on 1.30.0+

This commit detects the rustc version in the build script of proc-macro2
to determine whether the compiler supports the necessary backend APIs.
This should hopefully allow the crate to compile on stable by default
but have a better implementation on 1.30.0+ compilers.
diff --git a/README.md b/README.md
index de26577..f11c4dc 100644
--- a/README.md
+++ b/README.md
@@ -5,25 +5,20 @@
 [![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/proc-macro2)
 
 A small shim over the `proc_macro` crate in the compiler intended to multiplex
-the current stable interface (as of 2017-07-05) and the [upcoming richer
-interface][upcoming].
+the stable interface as of 1.15.0 and the interface as of 1.30.0.
 
-[upcoming]: https://github.com/rust-lang/rust/pull/40939
-
-The upcoming support has features like:
+New features added in Rust 1.30.0 include:
 
 * Span information on tokens
 * No need to go in/out through strings
 * Structured input/output
 
-The hope is that libraries ported to `proc_macro2` will be trivial to port to
-the real `proc_macro` crate once the support on nightly is stabilized.
+Libraries ported to `proc_macro2` can retain support for older compilers while
+continuing to get all the nice benefits of using a 1.30.0+ compiler.
 
 ## Usage
 
-This crate by default compiles on the stable version of the compiler. It only
-uses the stable surface area of the `proc_macro` crate upstream in the compiler
-itself. Usage is done via:
+This crate compiles on all 1.15.0+ stable compilers and usage looks like:
 
 ```toml
 [dependencies]
@@ -48,23 +43,13 @@
 }
 ```
 
-If you'd like you can enable the `nightly` feature in this crate. This will
-cause it to compile against the **unstable and nightly-only** features of the
-`proc_macro` crate. This in turn requires a nightly compiler. This should help
-preserve span information, however, coming in from the compiler itself.
-
-You can enable this feature via:
-
-```toml
-[dependencies]
-proc-macro2 = { version = "0.4", features = ["nightly"] }
-```
-
+The 1.30.0 compiler is automatically detected and its interfaces are used when
+available.
 
 ## Unstable Features
 
 `proc-macro2` supports exporting some methods from `proc_macro` which are
-currently highly unstable, and may not be stabilized in the first pass of
+currently highly unstable, and are not stabilized in the first pass of
 `proc_macro` stabilizations. These features are not exported by default. Minor
 versions of `proc-macro2` may make breaking changes to them at any time.
 
@@ -79,7 +64,6 @@
 depends on your crate. This infectious nature is intentional, as it serves as a
 reminder that you are outside of the normal semver guarantees.
 
-
 # License
 
 This project is licensed under either of
diff --git a/build.rs b/build.rs
index aaa92b6..cd91b4b 100644
--- a/build.rs
+++ b/build.rs
@@ -1,21 +1,53 @@
 use std::env;
+use std::process::Command;
+use std::str;
 
 fn main() {
     println!("cargo:rerun-if-changed=build.rs");
 
     let target = env::var("TARGET").unwrap();
 
-    maybe_enable_use_proc_macro(&target);
+    if !enable_use_proc_macro(&target) {
+        return
+    }
+    println!("cargo:rustc-cfg=use_proc_macro");
+
+    let minor = match rustc_minor_version() {
+        Some(n) => n,
+        None => return,
+    };
+
+    // Rust 1.30 stabilized the necessary APIs in the `proc_macro` crate
+    if minor >= 30 || cfg!(feature = "nightly") {
+        println!("cargo:rustc-cfg=wrap_proc_macro");
+
+        if cfg!(procmacro2_semver_exempt) {
+            println!("cargo:rustc-cfg=super_unstable");
+        }
+    } else {
+    }
 }
 
-fn maybe_enable_use_proc_macro(target: &str) {
+fn enable_use_proc_macro(target: &str) -> bool {
     // wasm targets don't have the `proc_macro` crate, disable this feature.
     if target.contains("wasm32") {
-        return;
+        return false;
     }
 
     // Otherwise, only enable it if our feature is actually enabled.
-    if cfg!(feature = "proc-macro") {
-        println!("cargo:rustc-cfg=use_proc_macro");
+    cfg!(feature = "proc-macro")
+}
+
+fn rustc_minor_version() -> Option<u32> {
+    macro_rules! otry {
+        ($e:expr) => (match $e { Some(e) => e, None => return None })
     }
+    let rustc = otry!(env::var_os("RUSTC"));
+    let output = otry!(Command::new(rustc).arg("--version").output().ok());
+    let version = otry!(str::from_utf8(&output.stdout).ok());
+    let mut pieces = version.split('.');
+    if pieces.next() != Some("rustc 1") {
+        return None;
+    }
+    otry!(pieces.next()).parse().ok()
 }
diff --git a/src/lib.rs b/src/lib.rs
index 39ab87a..9eac7d6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -45,7 +45,7 @@
 // Proc-macro2 types in rustdoc of other crates get linked to here.
 #![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.13")]
 #![cfg_attr(
-    feature = "nightly",
+    super_unstable,
     feature(proc_macro_raw_ident, proc_macro_span)
 )]
 
@@ -65,10 +65,10 @@
 mod strnom;
 mod stable;
 
-#[cfg(not(feature = "nightly"))]
+#[cfg(not(wrap_proc_macro))]
 use stable as imp;
 #[path = "unstable.rs"]
-#[cfg(feature = "nightly")]
+#[cfg(wrap_proc_macro)]
 mod imp;
 
 /// An abstract stream of tokens, or more concretely a sequence of token trees.
@@ -328,7 +328,7 @@
     }
 
     /// This method is only available when the `"nightly"` feature is enabled.
-    #[cfg(all(feature = "nightly", use_proc_macro))]
+    #[cfg(super_unstable)]
     pub fn unstable(self) -> proc_macro::Span {
         self.inner.unstable()
     }
diff --git a/src/unstable.rs b/src/unstable.rs
index 66158ec..e62c86a 100644
--- a/src/unstable.rs
+++ b/src/unstable.rs
@@ -1,4 +1,4 @@
-#![cfg_attr(not(procmacro2_semver_exempt), allow(dead_code))]
+#![cfg_attr(not(super_unstable), allow(dead_code))]
 
 use std::fmt;
 use std::iter;
@@ -292,11 +292,13 @@
 // NOTE: We have to generate our own filename object here because we can't wrap
 // the one provided by proc_macro.
 #[derive(Clone, PartialEq, Eq)]
+#[cfg(super_unstable)]
 pub enum SourceFile {
     Nightly(proc_macro::SourceFile, FileName),
     Stable(stable::SourceFile),
 }
 
+#[cfg(super_unstable)]
 impl SourceFile {
     fn nightly(sf: proc_macro::SourceFile) -> Self {
         let filename = stable::file_name(sf.path().display().to_string());
@@ -319,12 +321,14 @@
     }
 }
 
+#[cfg(super_unstable)]
 impl AsRef<FileName> for SourceFile {
     fn as_ref(&self) -> &FileName {
         self.path()
     }
 }
 
+#[cfg(super_unstable)]
 impl fmt::Debug for SourceFile {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -354,6 +358,7 @@
         }
     }
 
+    #[cfg(super_unstable)]
     pub fn def_site() -> Span {
         if nightly_works() {
             Span::Nightly(proc_macro::Span::def_site())
@@ -362,6 +367,7 @@
         }
     }
 
+    #[cfg(super_unstable)]
     pub fn resolved_at(&self, other: Span) -> Span {
         match (self, other) {
             (Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.resolved_at(b)),
@@ -370,6 +376,7 @@
         }
     }
 
+    #[cfg(super_unstable)]
     pub fn located_at(&self, other: Span) -> Span {
         match (self, other) {
             (Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.located_at(b)),
@@ -385,7 +392,7 @@
         }
     }
 
-    #[cfg(procmacro2_semver_exempt)]
+    #[cfg(super_unstable)]
     pub fn source_file(&self) -> SourceFile {
         match self {
             Span::Nightly(s) => SourceFile::nightly(s.source_file()),
@@ -393,7 +400,7 @@
         }
     }
 
-    #[cfg(procmacro2_semver_exempt)]
+    #[cfg(super_unstable)]
     pub fn start(&self) -> LineColumn {
         match self {
             Span::Nightly(s) => {
@@ -407,7 +414,7 @@
         }
     }
 
-    #[cfg(procmacro2_semver_exempt)]
+    #[cfg(super_unstable)]
     pub fn end(&self) -> LineColumn {
         match self {
             Span::Nightly(s) => {
@@ -421,7 +428,7 @@
         }
     }
 
-    #[cfg(procmacro2_semver_exempt)]
+    #[cfg(super_unstable)]
     pub fn join(&self, other: Span) -> Option<Span> {
         let ret = match (self, other) {
             (Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.join(b)?),
@@ -431,6 +438,7 @@
         Some(ret)
     }
 
+    #[cfg(super_unstable)]
     pub fn eq(&self, other: &Span) -> bool {
         match (self, other) {
             (Span::Nightly(a), Span::Nightly(b)) => a.eq(b),
@@ -484,7 +492,17 @@
 
     pub fn new_raw(string: &str, span: Span) -> Ident {
         match span {
-            Span::Nightly(s) => Ident::Nightly(proc_macro::Ident::new_raw(string, s)),
+            Span::Nightly(s) => {
+                let p: proc_macro::TokenStream = string.parse().unwrap();
+                let ident = match p.into_iter().next() {
+                    Some(proc_macro::TokenTree::Ident(mut i)) => {
+                        i.set_span(s);
+                        i
+                    }
+                    _ => panic!(),
+                };
+                Ident::Nightly(ident)
+            }
             Span::Stable(s) => Ident::Stable(stable::Ident::new_raw(string, s)),
         }
     }