1 // run-pass
2 // This is meant to be a comprehensive test of invocations with/without
3 // trailing commas (or other, similar optionally-trailing separators).
4 // Every macro is accounted for, even those not tested in this file.
5 // (There will be a note indicating why).
6
7 // std and core are both tested because they may contain separate
8 // implementations for some macro_rules! macros as an implementation
9 // detail.
10
11 // ignore-pretty issue #37195
12
13 // compile-flags: --test -C debug_assertions=yes
14 // revisions: std core
15
16 #![cfg_attr(core, no_std)]
17
18 #![allow(deprecated)] // for deprecated `try!()` macro
19 #![feature(concat_idents)]
20
21 #[cfg(std)] use std::fmt;
22 #[cfg(core)] use core::fmt;
23
24 #[test]
assert()25 fn assert() {
26 assert!(true);
27 assert!(true,);
28 assert!(true, "hello");
29 assert!(true, "hello",);
30 assert!(true, "hello {}", "world");
31 assert!(true, "hello {}", "world",);
32 }
33
34 #[test]
assert_eq()35 fn assert_eq() {
36 assert_eq!(1, 1);
37 assert_eq!(1, 1,);
38 assert_eq!(1, 1, "hello");
39 assert_eq!(1, 1, "hello",);
40 assert_eq!(1, 1, "hello {}", "world");
41 assert_eq!(1, 1, "hello {}", "world",);
42 }
43
44 #[test]
assert_ne()45 fn assert_ne() {
46 assert_ne!(1, 2);
47 assert_ne!(1, 2,);
48 assert_ne!(1, 2, "hello");
49 assert_ne!(1, 2, "hello",);
50 assert_ne!(1, 2, "hello {}", "world");
51 assert_ne!(1, 2, "hello {}", "world",);
52 }
53
54 #[test]
cfg()55 fn cfg() {
56 let _ = cfg!(pants);
57 let _ = cfg!(pants,);
58 let _ = cfg!(pants = "pants");
59 let _ = cfg!(pants = "pants",);
60 let _ = cfg!(all(pants));
61 let _ = cfg!(all(pants),);
62 let _ = cfg!(all(pants,));
63 let _ = cfg!(all(pants,),);
64 }
65
66 #[test]
column()67 fn column() {
68 let _ = column!();
69 }
70
71 // compile_error! is in a check-fail companion to this test
72
73 #[test]
concat()74 fn concat() {
75 let _ = concat!();
76 let _ = concat!("hello");
77 let _ = concat!("hello",);
78 let _ = concat!("hello", " world");
79 let _ = concat!("hello", " world",);
80 }
81
82 #[test]
concat_idents()83 fn concat_idents() {
84 fn foo() {}
85 fn foobar() {}
86
87 concat_idents!(foo)();
88 concat_idents!(foo,)();
89 concat_idents!(foo, bar)();
90 concat_idents!(foo, bar,)();
91 }
92
93 #[test]
debug_assert()94 fn debug_assert() {
95 debug_assert!(true);
96 debug_assert!(true, );
97 debug_assert!(true, "hello");
98 debug_assert!(true, "hello",);
99 debug_assert!(true, "hello {}", "world");
100 debug_assert!(true, "hello {}", "world",);
101 }
102
103 #[test]
debug_assert_eq()104 fn debug_assert_eq() {
105 debug_assert_eq!(1, 1);
106 debug_assert_eq!(1, 1,);
107 debug_assert_eq!(1, 1, "hello");
108 debug_assert_eq!(1, 1, "hello",);
109 debug_assert_eq!(1, 1, "hello {}", "world");
110 debug_assert_eq!(1, 1, "hello {}", "world",);
111 }
112
113 #[test]
debug_assert_ne()114 fn debug_assert_ne() {
115 debug_assert_ne!(1, 2);
116 debug_assert_ne!(1, 2,);
117 debug_assert_ne!(1, 2, "hello");
118 debug_assert_ne!(1, 2, "hello",);
119 debug_assert_ne!(1, 2, "hello {}", "world");
120 debug_assert_ne!(1, 2, "hello {}", "world",);
121 }
122
123 #[test]
env()124 fn env() {
125 let _ = env!("PATH");
126 let _ = env!("PATH",);
127 let _ = env!("PATH", "not found");
128 let _ = env!("PATH", "not found",);
129 }
130
131 #[cfg(std)]
132 #[test]
eprint()133 fn eprint() {
134 eprint!("hello");
135 eprint!("hello",);
136 eprint!("hello {}", "world");
137 eprint!("hello {}", "world",);
138 }
139
140 #[cfg(std)]
141 #[test]
eprintln()142 fn eprintln() {
143 eprintln!();
144 eprintln!("hello");
145 eprintln!("hello",);
146 eprintln!("hello {}", "world");
147 eprintln!("hello {}", "world",);
148 }
149
150 #[test]
file()151 fn file() {
152 let _ = file!();
153 }
154
155 #[cfg(std)]
156 #[test]
format()157 fn format() {
158 let _ = format!("hello");
159 let _ = format!("hello",);
160 let _ = format!("hello {}", "world");
161 let _ = format!("hello {}", "world",);
162 }
163
164 #[test]
format_args()165 fn format_args() {
166 let _ = format_args!("hello");
167 let _ = format_args!("hello",);
168 let _ = format_args!("hello {}", "world");
169 let _ = format_args!("hello {}", "world",);
170 }
171
172 #[test]
include()173 fn include() {
174 let _ = include!("auxiliary/macro-comma-support.rs");
175 let _ = include!("auxiliary/macro-comma-support.rs",);
176 }
177
178 #[test]
include_bytes()179 fn include_bytes() {
180 let _ = include_bytes!("auxiliary/macro-comma-support.rs");
181 let _ = include_bytes!("auxiliary/macro-comma-support.rs",);
182 }
183
184 #[test]
include_str()185 fn include_str() {
186 let _ = include_str!("auxiliary/macro-comma-support.rs");
187 let _ = include_str!("auxiliary/macro-comma-support.rs",);
188 }
189
190 #[test]
line()191 fn line() {
192 let _ = line!();
193 }
194
195 #[test]
module_path()196 fn module_path() {
197 let _ = module_path!();
198 }
199
200 #[test]
option_env()201 fn option_env() {
202 let _ = option_env!("PATH");
203 let _ = option_env!("PATH",);
204 }
205
206 #[test]
panic()207 fn panic() {
208 // prevent 'unreachable code' warnings
209 let falsum = || false;
210
211 if falsum() { panic!(); }
212 if falsum() { panic!("hello"); }
213 if falsum() { panic!("hello",); }
214 if falsum() { panic!("hello {}", "world"); }
215 if falsum() { panic!("hello {}", "world",); }
216 }
217
218 #[cfg(std)]
219 #[test]
print()220 fn print() {
221 print!("hello");
222 print!("hello",);
223 print!("hello {}", "world");
224 print!("hello {}", "world",);
225 }
226
227 #[cfg(std)]
228 #[test]
println()229 fn println() {
230 println!();
231 println!("hello");
232 println!("hello",);
233 println!("hello {}", "world");
234 println!("hello {}", "world",);
235 }
236
237 // stringify! is N/A
238
239 #[cfg(std)]
240 #[test]
thread_local()241 fn thread_local() {
242 // this has an optional trailing *semicolon*
243 thread_local! {
244 #[allow(unused)] pub static A: () = ()
245 }
246
247 thread_local! {
248 #[allow(unused)] pub static AA: () = ();
249 }
250
251 thread_local! {
252 #[allow(unused)] pub static AAA: () = ();
253 #[allow(unused)] pub static AAAA: () = ()
254 }
255
256 thread_local! {
257 #[allow(unused)] pub static AAAAG: () = ();
258 #[allow(unused)] pub static AAAAGH: () = ();
259 }
260 }
261
262 #[test]
try()263 fn try() {
264 fn inner() -> Result<(), ()> {
265 try!(Ok(()));
266 try!(Ok(()),);
267 Ok(())
268 }
269
270 inner().unwrap();
271 }
272
273 #[test]
unimplemented()274 fn unimplemented() {
275 // prevent 'unreachable code' warnings
276 let falsum = || false;
277
278 if falsum() { unimplemented!(); }
279 if falsum() { unimplemented!("hello"); }
280 if falsum() { unimplemented!("hello",); }
281 if falsum() { unimplemented!("hello {}", "world"); }
282 if falsum() { unimplemented!("hello {}", "world",); }
283 }
284
285 #[test]
unreachable()286 fn unreachable() {
287 // prevent 'unreachable code' warnings
288 let falsum = || false;
289
290 if falsum() { unreachable!(); }
291 if falsum() { unreachable!("hello"); }
292 if falsum() { unreachable!("hello",); }
293 if falsum() { unreachable!("hello {}", "world"); }
294 if falsum() { unreachable!("hello {}", "world",); }
295 }
296
297 #[cfg(std)]
298 #[test]
vec()299 fn vec() {
300 let _: Vec<()> = vec![];
301 let _ = vec![0];
302 let _ = vec![0,];
303 let _ = vec![0, 1];
304 let _ = vec![0, 1,];
305 }
306
307 // give a test body access to a fmt::Formatter, which seems
308 // to be the easiest way to use 'write!' on core.
309 macro_rules! test_with_formatter {
310 (
311 #[test]
312 fn $fname:ident($f:ident: &mut fmt::Formatter) $block:block
313 ) => {
314 #[test]
315 fn $fname() {
316 struct Struct;
317 impl fmt::Display for Struct {
318 fn fmt(&self, $f: &mut fmt::Formatter) -> fmt::Result {
319 Ok($block)
320 }
321 }
322
323 // suppress "unused"
324 assert!(true, "{}", Struct);
325 }
326 };
327 }
328
329 test_with_formatter! {
330 #[test]
331 fn write(f: &mut fmt::Formatter) {
332 let _ = write!(f, "hello");
333 let _ = write!(f, "hello",);
334 let _ = write!(f, "hello {}", "world");
335 let _ = write!(f, "hello {}", "world",);
336 }
337 }
338
339 test_with_formatter! {
340 #[test]
341 fn writeln(f: &mut fmt::Formatter) {
342 let _ = writeln!(f);
343 let _ = writeln!(f,);
344 let _ = writeln!(f, "hello");
345 let _ = writeln!(f, "hello",);
346 let _ = writeln!(f, "hello {}", "world");
347 let _ = writeln!(f, "hello {}", "world",);
348 }
349 }
350