Merge branch 'master' into path
diff --git a/.travis.yml b/.travis.yml
index b07a4d4..0234f4e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,11 @@
 
 matrix:
   include:
-    - rust: 1.15.0
+    - rust: 1.15.0 # oldest supported version
+      script: cargo build
+    - rust: 1.19.0 # first release with the --tests flag
+      script: cargo test --tests
+    - rust: 1.26.0 # first release on which our doc tests pass
     - rust: stable
     - rust: beta
     - rust: nightly
diff --git a/Cargo.toml b/Cargo.toml
index f15b987..da1c1e0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,9 +15,6 @@
 unstable API.
 """
 
-[lib]
-doctest = false
-
 [package.metadata.docs.rs]
 rustc-args = ["--cfg", "procmacro2_semver_exempt"]
 rustdoc-args = ["--cfg", "procmacro2_semver_exempt"]
@@ -25,6 +22,9 @@
 [dependencies]
 unicode-xid = "0.1"
 
+[dev-dependencies]
+quote = "0.6"
+
 [features]
 # When enabled: act as a shim around the nightly compiler's proc_macro crate.
 # This requires a nightly compiler.
@@ -38,3 +38,11 @@
 
 [badges]
 travis-ci = { repository = "alexcrichton/proc-macro2" }
+
+[patch.crates-io]
+# Our doc tests depend on quote which depends on proc-macro2. Without this line,
+# the proc-macro2 dependency of quote would be the released version of
+# proc-macro2. Quote would implement its traits for types from that proc-macro2,
+# meaning impls would be missing when tested against types from the local
+# proc-macro2.
+proc-macro2 = { path = "." }
diff --git a/src/lib.rs b/src/lib.rs
index 4f8f59d..1204c6c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -218,10 +218,20 @@
 /// This type is semver exempt and not exposed by default.
 #[cfg(procmacro2_semver_exempt)]
 #[derive(Clone, PartialEq, Eq)]
-pub struct SourceFile(imp::SourceFile);
+pub struct SourceFile {
+    inner: imp::SourceFile,
+    _marker: marker::PhantomData<Rc<()>>,
+}
 
 #[cfg(procmacro2_semver_exempt)]
 impl SourceFile {
+    fn _new(inner: imp::SourceFile) -> Self {
+        SourceFile {
+            inner: inner,
+            _marker: marker::PhantomData,
+        }
+    }
+
     /// Get the path to this source file.
     ///
     /// ### Note
@@ -236,20 +246,20 @@
     ///
     /// [`is_real`]: #method.is_real
     pub fn path(&self) -> PathBuf {
-        self.0.path()
+        self.inner.path()
     }
 
     /// Returns `true` if this source file is a real source file, and not
     /// generated by an external macro's expansion.
     pub fn is_real(&self) -> bool {
-        self.0.is_real()
+        self.inner.is_real()
     }
 }
 
 #[cfg(procmacro2_semver_exempt)]
 impl fmt::Debug for SourceFile {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.fmt(f)
+        self.inner.fmt(f)
     }
 }
 
@@ -335,7 +345,7 @@
     /// This method is semver exempt and not exposed by default.
     #[cfg(procmacro2_semver_exempt)]
     pub fn source_file(&self) -> SourceFile {
-        SourceFile(self.inner.source_file())
+        SourceFile::_new(self.inner.source_file())
     }
 
     /// Get the starting line/column in the source file for this span.
diff --git a/tests/marker.rs b/tests/marker.rs
new file mode 100644
index 0000000..7bb5027
--- /dev/null
+++ b/tests/marker.rs
@@ -0,0 +1,61 @@
+extern crate proc_macro2;
+
+use proc_macro2::*;
+
+macro_rules! assert_impl {
+    ($ty:ident is $($marker:ident) and +) => {
+        #[test]
+        #[allow(non_snake_case)]
+        fn $ty() {
+            fn assert_implemented<T: $($marker +)+>() {}
+            assert_implemented::<$ty>();
+        }
+    };
+
+    ($ty:ident is not $($marker:ident) or +) => {
+        #[test]
+        #[allow(non_snake_case)]
+        fn $ty() {
+            $(
+                {
+                    // Implemented for types that implement $marker.
+                    trait IsNotImplemented {
+                        fn assert_not_implemented() {}
+                    }
+                    impl<T: $marker> IsNotImplemented for T {}
+
+                    // Implemented for the type being tested.
+                    trait IsImplemented {
+                        fn assert_not_implemented() {}
+                    }
+                    impl IsImplemented for $ty {}
+
+                    // If $ty does not implement $marker, there is no ambiguity
+                    // in the following trait method call.
+                    <$ty>::assert_not_implemented();
+                }
+            )+
+        }
+    };
+}
+
+assert_impl!(Delimiter is Send and Sync);
+assert_impl!(Spacing is Send and Sync);
+
+assert_impl!(Group is not Send or Sync);
+assert_impl!(Ident is not Send or Sync);
+assert_impl!(LexError is not Send or Sync);
+assert_impl!(Literal is not Send or Sync);
+assert_impl!(Punct is not Send or Sync);
+assert_impl!(Span is not Send or Sync);
+assert_impl!(TokenStream is not Send or Sync);
+assert_impl!(TokenTree is not Send or Sync);
+
+#[cfg(procmacro2_semver_exempt)]
+mod semver_exempt {
+    use super::*;
+
+    assert_impl!(LineColumn is Send and Sync);
+
+    assert_impl!(SourceFile is not Send or Sync);
+}