diff options
Diffstat (limited to 'crates/ra_mbe/src/lib.rs')
-rw-r--r-- | crates/ra_mbe/src/lib.rs | 112 |
1 files changed, 110 insertions, 2 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index 7ebba807c..7817232d6 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs | |||
@@ -437,6 +437,30 @@ impl_froms!(TokenTree: Leaf, Subtree); | |||
437 | } | 437 | } |
438 | 438 | ||
439 | #[test] | 439 | #[test] |
440 | fn test_match_group_zero_match() { | ||
441 | let rules = create_rules( | ||
442 | r#" | ||
443 | macro_rules! foo { | ||
444 | ( $($i:ident)* ) => (); | ||
445 | }"#, | ||
446 | ); | ||
447 | |||
448 | assert_expansion(&rules, "foo! ()", ""); | ||
449 | } | ||
450 | |||
451 | #[test] | ||
452 | fn test_match_group_in_group() { | ||
453 | let rules = create_rules( | ||
454 | r#" | ||
455 | macro_rules! foo { | ||
456 | { $( ( $($i:ident)* ) )* } => ( $( ( $($i)* ) )* ); | ||
457 | }"#, | ||
458 | ); | ||
459 | |||
460 | assert_expansion(&rules, "foo! ( (a b) )", "(a b)"); | ||
461 | } | ||
462 | |||
463 | #[test] | ||
440 | fn test_expand_to_item_list() { | 464 | fn test_expand_to_item_list() { |
441 | let rules = create_rules( | 465 | let rules = create_rules( |
442 | " | 466 | " |
@@ -1118,7 +1142,37 @@ macro_rules! impl_fn_for_zst { | |||
1118 | |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty | 1142 | |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty |
1119 | $body: block; )+ | 1143 | $body: block; )+ |
1120 | } => { | 1144 | } => { |
1121 | fn foo(){} | 1145 | $( |
1146 | $( #[$attr] )* | ||
1147 | struct $Name; | ||
1148 | |||
1149 | impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name { | ||
1150 | #[inline] | ||
1151 | extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { | ||
1152 | $body | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1156 | impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name { | ||
1157 | #[inline] | ||
1158 | extern "rust-call" fn call_mut( | ||
1159 | &mut self, | ||
1160 | ($( $arg, )*): ($( $ArgTy, )*) | ||
1161 | ) -> $ReturnTy { | ||
1162 | Fn::call(&*self, ($( $arg, )*)) | ||
1163 | } | ||
1164 | } | ||
1165 | |||
1166 | impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name { | ||
1167 | type Output = $ReturnTy; | ||
1168 | |||
1169 | #[inline] | ||
1170 | extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { | ||
1171 | Fn::call(&self, ($( $arg, )*)) | ||
1172 | } | ||
1173 | } | ||
1174 | )+ | ||
1175 | } | ||
1122 | } | 1176 | } |
1123 | } | 1177 | } |
1124 | "#, | 1178 | "#, |
@@ -1141,7 +1195,7 @@ impl_fn_for_zst ! { | |||
1141 | } ; | 1195 | } ; |
1142 | } | 1196 | } |
1143 | "#, | 1197 | "#, |
1144 | "fn foo () {}"); | 1198 | "# [derive (Clone)] struct CharEscapeDebugContinue ; impl Fn < (char ,) > for CharEscapeDebugContinue {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeDebug {{c . escape_debug_ext (false)}}} impl FnMut < (char ,) > for CharEscapeDebugContinue {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeDebug {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeDebugContinue {type Output = char :: EscapeDebug ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeDebug {Fn :: call (& self , (c ,))}} # [derive (Clone)] struct CharEscapeUnicode ; impl Fn < (char ,) > for CharEscapeUnicode {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeUnicode {{c . escape_unicode ()}}} impl FnMut < (char ,) > for CharEscapeUnicode {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeUnicode {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeUnicode {type Output = char :: EscapeUnicode ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeUnicode {Fn :: call (& self , (c ,))}} # [derive (Clone)] struct CharEscapeDefault ; impl Fn < (char ,) > for CharEscapeDefault {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeDefault {{c . escape_default ()}}} impl FnMut < (char ,) > for CharEscapeDefault {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeDefault {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeDefault {type Output = char :: EscapeDefault ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeDefault {Fn :: call (& self , (c ,))}}"); |
1145 | } | 1199 | } |
1146 | 1200 | ||
1147 | #[test] | 1201 | #[test] |
@@ -1160,4 +1214,58 @@ impl_fn_for_zst ! { | |||
1160 | assert_expansion(&rules, r#"impl_nonzero_fmt ! { # [ stable ( feature = "nonzero" , since = "1.28.0" ) ] ( Debug , Display , Binary , Octal , LowerHex , UpperHex ) for NonZeroU8 }"#, | 1214 | assert_expansion(&rules, r#"impl_nonzero_fmt ! { # [ stable ( feature = "nonzero" , since = "1.28.0" ) ] ( Debug , Display , Binary , Octal , LowerHex , UpperHex ) for NonZeroU8 }"#, |
1161 | "fn foo () {}"); | 1215 | "fn foo () {}"); |
1162 | } | 1216 | } |
1217 | |||
1218 | #[test] | ||
1219 | fn test_cfg_if_items() { | ||
1220 | // from https://github.com/rust-lang/rust/blob/33fe1131cadba69d317156847be9a402b89f11bb/src/libstd/macros.rs#L986 | ||
1221 | let rules = create_rules( | ||
1222 | r#" | ||
1223 | macro_rules! __cfg_if_items { | ||
1224 | (($($not:meta,)*) ; ) => {}; | ||
1225 | (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => { | ||
1226 | __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* } | ||
1227 | } | ||
1228 | } | ||
1229 | "#, | ||
1230 | ); | ||
1231 | |||
1232 | assert_expansion(&rules, r#"__cfg_if_items ! { ( rustdoc , ) ; ( ( ) ( # [ cfg ( any ( target_os = "redox" , unix ) ) ] # [ stable ( feature = "rust1" , since = "1.0.0" ) ] pub use sys :: ext as unix ; # [ cfg ( windows ) ] # [ stable ( feature = "rust1" , since = "1.0.0" ) ] pub use sys :: ext as windows ; # [ cfg ( any ( target_os = "linux" , target_os = "l4re" ) ) ] pub mod linux ; ) ) , }"#, | ||
1233 | "__cfg_if_items ! {(rustdoc , ) ; }"); | ||
1234 | } | ||
1235 | |||
1236 | #[test] | ||
1237 | fn test_cfg_if_main() { | ||
1238 | // from https://github.com/rust-lang/rust/blob/3d211248393686e0f73851fc7548f6605220fbe1/src/libpanic_unwind/macros.rs#L9 | ||
1239 | let rules = create_rules( | ||
1240 | r#" | ||
1241 | macro_rules! cfg_if { | ||
1242 | ($( | ||
1243 | if #[cfg($($meta:meta),*)] { $($it:item)* } | ||
1244 | ) else * else { | ||
1245 | $($it2:item)* | ||
1246 | }) => { | ||
1247 | __cfg_if_items! { | ||
1248 | () ; | ||
1249 | $( ( ($($meta),*) ($($it)*) ), )* | ||
1250 | ( () ($($it2)*) ), | ||
1251 | } | ||
1252 | } | ||
1253 | } | ||
1254 | "#, | ||
1255 | ); | ||
1256 | |||
1257 | assert_expansion(&rules, r#" | ||
1258 | cfg_if ! { | ||
1259 | if # [ cfg ( target_env = "msvc" ) ] { | ||
1260 | // no extra unwinder support needed | ||
1261 | } else if # [ cfg ( all ( target_arch = "wasm32" , not ( target_os = "emscripten" ) ) ) ] { | ||
1262 | // no unwinder on the system! | ||
1263 | } else { | ||
1264 | mod libunwind ; | ||
1265 | pub use libunwind :: * ; | ||
1266 | } | ||
1267 | } | ||
1268 | "#, | ||
1269 | "__cfg_if_items ! {() ; (() (mod libunwind ; pub use libunwind :: * ;)) ,}"); | ||
1270 | } | ||
1163 | } | 1271 | } |