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