|
| 1 | +extern crate proc_macro2; |
| 2 | + |
| 3 | +use proc_macro2::*; |
| 4 | + |
| 5 | +macro_rules! assert_impl { |
| 6 | + ($ty:ident is $($marker:ident) and +) => { |
| 7 | + #[test] |
| 8 | + #[allow(non_snake_case)] |
| 9 | + fn $ty() { |
| 10 | + fn assert_implemented<T: $($marker +)+>() {} |
| 11 | + assert_implemented::<$ty>(); |
| 12 | + } |
| 13 | + }; |
| 14 | + |
| 15 | + ($ty:ident is not $($marker:ident) or +) => { |
| 16 | + #[test] |
| 17 | + #[allow(non_snake_case)] |
| 18 | + fn $ty() { |
| 19 | + $( |
| 20 | + { |
| 21 | + // Implemented for types that implement $marker. |
| 22 | + trait IsNotImplemented { |
| 23 | + fn assert_not_implemented() {} |
| 24 | + } |
| 25 | + impl<T: $marker> IsNotImplemented for T {} |
| 26 | + |
| 27 | + // Implemented for the type being tested. |
| 28 | + trait IsImplemented { |
| 29 | + fn assert_not_implemented() {} |
| 30 | + } |
| 31 | + impl IsImplemented for $ty {} |
| 32 | + |
| 33 | + // If $ty does not implement $marker, there is no ambiguity |
| 34 | + // in the following trait method call. |
| 35 | + <$ty>::assert_not_implemented(); |
| 36 | + } |
| 37 | + )+ |
| 38 | + } |
| 39 | + }; |
| 40 | +} |
| 41 | + |
| 42 | +assert_impl!(Delimiter is Send and Sync); |
| 43 | +assert_impl!(Spacing is Send and Sync); |
| 44 | + |
| 45 | +assert_impl!(Group is not Send or Sync); |
| 46 | +assert_impl!(Ident is not Send or Sync); |
| 47 | +assert_impl!(LexError is not Send or Sync); |
| 48 | +assert_impl!(Literal is not Send or Sync); |
| 49 | +assert_impl!(Punct is not Send or Sync); |
| 50 | +assert_impl!(Span is not Send or Sync); |
| 51 | +assert_impl!(TokenStream is not Send or Sync); |
| 52 | +assert_impl!(TokenTree is not Send or Sync); |
| 53 | + |
| 54 | +#[cfg(procmacro2_semver_exempt)] |
| 55 | +mod semver_exempt { |
| 56 | + use super::*; |
| 57 | + |
| 58 | + assert_impl!(LineColumn is Send and Sync); |
| 59 | + |
| 60 | + assert_impl!(SourceFile is not Send or Sync); |
| 61 | +} |
0 commit comments