Merge pull request #150 from dtolnay/marker
Remove Send and Sync from SourceFile
diff --git a/src/lib.rs b/src/lib.rs
index 2f632f6..784e456 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -220,10 +220,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
@@ -238,27 +248,27 @@
///
/// [`is_real`]: #method.is_real
pub fn path(&self) -> &FileName {
- 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 AsRef<FileName> for SourceFile {
fn as_ref(&self) -> &FileName {
- self.0.path()
+ self.inner.path()
}
}
#[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)
}
}
@@ -344,7 +354,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);
+}