1 use proc_macro2::*; 2 3 macro_rules! assert_impl { 4 ($ty:ident is $($marker:ident) and +) => { 5 #[test] 6 #[allow(non_snake_case)] 7 fn $ty() { 8 fn assert_implemented<T: $($marker +)+>() {} 9 assert_implemented::<$ty>(); 10 } 11 }; 12 13 ($ty:ident is not $($marker:ident) or +) => { 14 #[test] 15 #[allow(non_snake_case)] 16 fn $ty() { 17 $( 18 { 19 // Implemented for types that implement $marker. 20 trait IsNotImplemented { 21 fn assert_not_implemented() {} 22 } 23 impl<T: $marker> IsNotImplemented for T {} 24 25 // Implemented for the type being tested. 26 trait IsImplemented { 27 fn assert_not_implemented() {} 28 } 29 impl IsImplemented for $ty {} 30 31 // If $ty does not implement $marker, there is no ambiguity 32 // in the following trait method call. 33 <$ty>::assert_not_implemented(); 34 } 35 )+ 36 } 37 }; 38 } 39 40 assert_impl!(Delimiter is Send and Sync); 41 assert_impl!(Spacing is Send and Sync); 42 43 assert_impl!(Group is not Send or Sync); 44 assert_impl!(Ident is not Send or Sync); 45 assert_impl!(LexError is not Send or Sync); 46 assert_impl!(Literal is not Send or Sync); 47 assert_impl!(Punct is not Send or Sync); 48 assert_impl!(Span is not Send or Sync); 49 assert_impl!(TokenStream is not Send or Sync); 50 assert_impl!(TokenTree is not Send or Sync); 51 52 #[cfg(procmacro2_semver_exempt)] 53 mod semver_exempt { 54 use super::*; 55 56 assert_impl!(LineColumn is Send and Sync); 57 58 assert_impl!(SourceFile is not Send or Sync); 59 } 60 61 #[cfg(not(no_libprocmacro_unwind_safe))] 62 mod unwind_safe { 63 use super::*; 64 use std::panic::{RefUnwindSafe, UnwindSafe}; 65 66 macro_rules! assert_unwind_safe { 67 ($($types:ident)*) => { 68 $( 69 assert_impl!($types is UnwindSafe and RefUnwindSafe); 70 )* 71 }; 72 } 73 74 assert_unwind_safe! { 75 Delimiter 76 Group 77 Ident 78 LexError 79 Literal 80 Punct 81 Spacing 82 Span 83 TokenStream 84 TokenTree 85 } 86 87 #[cfg(procmacro2_semver_exempt)] 88 assert_unwind_safe! { 89 LineColumn 90 SourceFile 91 } 92 } 93