2018-08-30 12:18:55 +00:00
|
|
|
//@ run-pass
|
2018-02-14 07:15:27 +00:00
|
|
|
// This is meant to be a comprehensive test of invocations with/without
|
2018-02-07 04:03:14 +00:00
|
|
|
// trailing commas (or other, similar optionally-trailing separators).
|
|
|
|
// Every macro is accounted for, even those not tested in this file.
|
|
|
|
// (There will be a note indicating why).
|
|
|
|
|
|
|
|
// std and core are both tested because they may contain separate
|
|
|
|
// implementations for some macro_rules! macros as an implementation
|
|
|
|
// detail.
|
|
|
|
|
2018-02-25 01:05:17 +00:00
|
|
|
|
2018-02-07 04:03:14 +00:00
|
|
|
//@ compile-flags: --test -C debug_assertions=yes
|
|
|
|
//@ revisions: std core
|
|
|
|
|
|
|
|
#![cfg_attr(core, no_std)]
|
|
|
|
|
2019-07-14 08:16:46 +00:00
|
|
|
#![allow(deprecated)] // for deprecated `try!()` macro
|
2018-02-07 04:03:14 +00:00
|
|
|
#![feature(concat_idents)]
|
|
|
|
|
|
|
|
#[cfg(std)] use std::fmt;
|
|
|
|
#[cfg(core)] use core::fmt;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn assert() {
|
|
|
|
assert!(true);
|
|
|
|
assert!(true,);
|
|
|
|
assert!(true, "hello");
|
|
|
|
assert!(true, "hello",);
|
|
|
|
assert!(true, "hello {}", "world");
|
|
|
|
assert!(true, "hello {}", "world",);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn assert_eq() {
|
|
|
|
assert_eq!(1, 1);
|
|
|
|
assert_eq!(1, 1,);
|
|
|
|
assert_eq!(1, 1, "hello");
|
|
|
|
assert_eq!(1, 1, "hello",);
|
|
|
|
assert_eq!(1, 1, "hello {}", "world");
|
|
|
|
assert_eq!(1, 1, "hello {}", "world",);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn assert_ne() {
|
|
|
|
assert_ne!(1, 2);
|
|
|
|
assert_ne!(1, 2,);
|
|
|
|
assert_ne!(1, 2, "hello");
|
|
|
|
assert_ne!(1, 2, "hello",);
|
|
|
|
assert_ne!(1, 2, "hello {}", "world");
|
|
|
|
assert_ne!(1, 2, "hello {}", "world",);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2024-04-06 22:33:37 +00:00
|
|
|
#[allow(unexpected_cfgs)]
|
2018-02-07 04:03:14 +00:00
|
|
|
fn cfg() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = cfg!(pants);
|
|
|
|
let _ = cfg!(pants,);
|
|
|
|
let _ = cfg!(pants = "pants");
|
|
|
|
let _ = cfg!(pants = "pants",);
|
|
|
|
let _ = cfg!(all(pants));
|
|
|
|
let _ = cfg!(all(pants),);
|
|
|
|
let _ = cfg!(all(pants,));
|
|
|
|
let _ = cfg!(all(pants,),);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn column() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = column!();
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
2020-12-28 17:15:16 +00:00
|
|
|
// compile_error! is in a check-fail companion to this test
|
2018-02-07 04:03:14 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn concat() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = concat!();
|
|
|
|
let _ = concat!("hello");
|
|
|
|
let _ = concat!("hello",);
|
|
|
|
let _ = concat!("hello", " world");
|
|
|
|
let _ = concat!("hello", " world",);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn concat_idents() {
|
|
|
|
fn foo() {}
|
|
|
|
fn foobar() {}
|
|
|
|
|
|
|
|
concat_idents!(foo)();
|
|
|
|
concat_idents!(foo,)();
|
|
|
|
concat_idents!(foo, bar)();
|
|
|
|
concat_idents!(foo, bar,)();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn debug_assert() {
|
|
|
|
debug_assert!(true);
|
|
|
|
debug_assert!(true, );
|
|
|
|
debug_assert!(true, "hello");
|
|
|
|
debug_assert!(true, "hello",);
|
|
|
|
debug_assert!(true, "hello {}", "world");
|
|
|
|
debug_assert!(true, "hello {}", "world",);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn debug_assert_eq() {
|
|
|
|
debug_assert_eq!(1, 1);
|
|
|
|
debug_assert_eq!(1, 1,);
|
|
|
|
debug_assert_eq!(1, 1, "hello");
|
|
|
|
debug_assert_eq!(1, 1, "hello",);
|
|
|
|
debug_assert_eq!(1, 1, "hello {}", "world");
|
|
|
|
debug_assert_eq!(1, 1, "hello {}", "world",);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn debug_assert_ne() {
|
|
|
|
debug_assert_ne!(1, 2);
|
|
|
|
debug_assert_ne!(1, 2,);
|
|
|
|
debug_assert_ne!(1, 2, "hello");
|
|
|
|
debug_assert_ne!(1, 2, "hello",);
|
|
|
|
debug_assert_ne!(1, 2, "hello {}", "world");
|
|
|
|
debug_assert_ne!(1, 2, "hello {}", "world",);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn env() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = env!("PATH");
|
|
|
|
let _ = env!("PATH",);
|
|
|
|
let _ = env!("PATH", "not found");
|
|
|
|
let _ = env!("PATH", "not found",);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(std)]
|
|
|
|
#[test]
|
|
|
|
fn eprint() {
|
|
|
|
eprint!("hello");
|
|
|
|
eprint!("hello",);
|
|
|
|
eprint!("hello {}", "world");
|
|
|
|
eprint!("hello {}", "world",);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(std)]
|
|
|
|
#[test]
|
|
|
|
fn eprintln() {
|
|
|
|
eprintln!();
|
|
|
|
eprintln!("hello");
|
|
|
|
eprintln!("hello",);
|
|
|
|
eprintln!("hello {}", "world");
|
|
|
|
eprintln!("hello {}", "world",);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn file() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = file!();
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(std)]
|
|
|
|
#[test]
|
|
|
|
fn format() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = format!("hello");
|
|
|
|
let _ = format!("hello",);
|
|
|
|
let _ = format!("hello {}", "world");
|
|
|
|
let _ = format!("hello {}", "world",);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn format_args() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = format_args!("hello");
|
|
|
|
let _ = format_args!("hello",);
|
|
|
|
let _ = format_args!("hello {}", "world");
|
|
|
|
let _ = format_args!("hello {}", "world",);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn include() {
|
2023-06-12 08:55:36 +00:00
|
|
|
include!("auxiliary/macro-comma-support.rs");
|
|
|
|
include!("auxiliary/macro-comma-support.rs",);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn include_bytes() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = include_bytes!("auxiliary/macro-comma-support.rs");
|
|
|
|
let _ = include_bytes!("auxiliary/macro-comma-support.rs",);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn include_str() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = include_str!("auxiliary/macro-comma-support.rs");
|
|
|
|
let _ = include_str!("auxiliary/macro-comma-support.rs",);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn line() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = line!();
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
2022-05-11 14:42:16 +00:00
|
|
|
#[test]
|
|
|
|
fn matches() {
|
|
|
|
let _ = matches!(1, x if x > 0);
|
|
|
|
let _ = matches!(1, x if x > 0,);
|
|
|
|
}
|
|
|
|
|
2018-02-07 04:03:14 +00:00
|
|
|
#[test]
|
|
|
|
fn module_path() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = module_path!();
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn option_env() {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = option_env!("PATH");
|
|
|
|
let _ = option_env!("PATH",);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn panic() {
|
|
|
|
// prevent 'unreachable code' warnings
|
|
|
|
let falsum = || false;
|
|
|
|
|
|
|
|
if falsum() { panic!(); }
|
|
|
|
if falsum() { panic!("hello"); }
|
|
|
|
if falsum() { panic!("hello",); }
|
|
|
|
if falsum() { panic!("hello {}", "world"); }
|
|
|
|
if falsum() { panic!("hello {}", "world",); }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(std)]
|
|
|
|
#[test]
|
|
|
|
fn print() {
|
|
|
|
print!("hello");
|
|
|
|
print!("hello",);
|
|
|
|
print!("hello {}", "world");
|
|
|
|
print!("hello {}", "world",);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(std)]
|
|
|
|
#[test]
|
|
|
|
fn println() {
|
|
|
|
println!();
|
|
|
|
println!("hello");
|
|
|
|
println!("hello",);
|
|
|
|
println!("hello {}", "world");
|
|
|
|
println!("hello {}", "world",);
|
|
|
|
}
|
|
|
|
|
|
|
|
// stringify! is N/A
|
|
|
|
|
|
|
|
#[cfg(std)]
|
|
|
|
#[test]
|
|
|
|
fn thread_local() {
|
|
|
|
// this has an optional trailing *semicolon*
|
|
|
|
thread_local! {
|
|
|
|
#[allow(unused)] pub static A: () = ()
|
|
|
|
}
|
|
|
|
|
|
|
|
thread_local! {
|
|
|
|
#[allow(unused)] pub static AA: () = ();
|
|
|
|
}
|
|
|
|
|
|
|
|
thread_local! {
|
|
|
|
#[allow(unused)] pub static AAA: () = ();
|
|
|
|
#[allow(unused)] pub static AAAA: () = ()
|
|
|
|
}
|
|
|
|
|
|
|
|
thread_local! {
|
|
|
|
#[allow(unused)] pub static AAAAG: () = ();
|
|
|
|
#[allow(unused)] pub static AAAAGH: () = ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn try() {
|
|
|
|
fn inner() -> Result<(), ()> {
|
|
|
|
try!(Ok(()));
|
|
|
|
try!(Ok(()),);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
inner().unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn unimplemented() {
|
|
|
|
// prevent 'unreachable code' warnings
|
|
|
|
let falsum = || false;
|
|
|
|
|
|
|
|
if falsum() { unimplemented!(); }
|
|
|
|
if falsum() { unimplemented!("hello"); }
|
|
|
|
if falsum() { unimplemented!("hello",); }
|
|
|
|
if falsum() { unimplemented!("hello {}", "world"); }
|
|
|
|
if falsum() { unimplemented!("hello {}", "world",); }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn unreachable() {
|
|
|
|
// prevent 'unreachable code' warnings
|
|
|
|
let falsum = || false;
|
|
|
|
|
|
|
|
if falsum() { unreachable!(); }
|
|
|
|
if falsum() { unreachable!("hello"); }
|
|
|
|
if falsum() { unreachable!("hello",); }
|
|
|
|
if falsum() { unreachable!("hello {}", "world"); }
|
|
|
|
if falsum() { unreachable!("hello {}", "world",); }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(std)]
|
|
|
|
#[test]
|
|
|
|
fn vec() {
|
|
|
|
let _: Vec<()> = vec![];
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = vec![0];
|
|
|
|
let _ = vec![0,];
|
|
|
|
let _ = vec![0, 1];
|
|
|
|
let _ = vec![0, 1,];
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// give a test body access to a fmt::Formatter, which seems
|
|
|
|
// to be the easiest way to use 'write!' on core.
|
|
|
|
macro_rules! test_with_formatter {
|
|
|
|
(
|
|
|
|
#[test]
|
|
|
|
fn $fname:ident($f:ident: &mut fmt::Formatter) $block:block
|
|
|
|
) => {
|
|
|
|
#[test]
|
|
|
|
fn $fname() {
|
|
|
|
struct Struct;
|
|
|
|
impl fmt::Display for Struct {
|
|
|
|
fn fmt(&self, $f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
Ok($block)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// suppress "unused"
|
|
|
|
assert!(true, "{}", Struct);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
test_with_formatter! {
|
|
|
|
#[test]
|
|
|
|
fn write(f: &mut fmt::Formatter) {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = write!(f, "hello");
|
|
|
|
let _ = write!(f, "hello",);
|
|
|
|
let _ = write!(f, "hello {}", "world");
|
|
|
|
let _ = write!(f, "hello {}", "world",);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
test_with_formatter! {
|
|
|
|
#[test]
|
|
|
|
fn writeln(f: &mut fmt::Formatter) {
|
2018-09-13 23:37:12 +00:00
|
|
|
let _ = writeln!(f);
|
|
|
|
let _ = writeln!(f,);
|
|
|
|
let _ = writeln!(f, "hello");
|
|
|
|
let _ = writeln!(f, "hello",);
|
|
|
|
let _ = writeln!(f, "hello {}", "world");
|
|
|
|
let _ = writeln!(f, "hello {}", "world",);
|
2018-02-07 04:03:14 +00:00
|
|
|
}
|
|
|
|
}
|