mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-30 04:24:26 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			890 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			890 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // run-pass
 | |
| // edition:2021
 | |
| // compile-flags: --test
 | |
| 
 | |
| #![feature(async_closure)]
 | |
| #![feature(box_patterns)]
 | |
| #![feature(box_syntax)]
 | |
| #![feature(const_trait_impl)]
 | |
| #![feature(decl_macro)]
 | |
| #![feature(generators)]
 | |
| #![feature(more_qualified_paths)]
 | |
| #![feature(raw_ref_op)]
 | |
| #![feature(trait_alias)]
 | |
| #![feature(try_blocks)]
 | |
| #![feature(type_ascription)]
 | |
| #![deny(unused_macros)]
 | |
| 
 | |
| macro_rules! stringify_block {
 | |
|     ($block:block) => {
 | |
|         stringify!($block)
 | |
|     };
 | |
| }
 | |
| 
 | |
| macro_rules! stringify_expr {
 | |
|     ($expr:expr) => {
 | |
|         stringify!($expr)
 | |
|     };
 | |
| }
 | |
| 
 | |
| macro_rules! stringify_item {
 | |
|     ($item:item) => {
 | |
|         stringify!($item)
 | |
|     };
 | |
| }
 | |
| 
 | |
| macro_rules! stringify_meta {
 | |
|     ($meta:meta) => {
 | |
|         stringify!($meta)
 | |
|     };
 | |
| }
 | |
| 
 | |
| macro_rules! stringify_pat {
 | |
|     ($pat:pat) => {
 | |
|         stringify!($pat)
 | |
|     };
 | |
| }
 | |
| 
 | |
| macro_rules! stringify_path {
 | |
|     ($path:path) => {
 | |
|         stringify!($path)
 | |
|     };
 | |
| }
 | |
| 
 | |
| macro_rules! stringify_stmt {
 | |
|     ($stmt:stmt) => {
 | |
|         stringify!($stmt)
 | |
|     };
 | |
| }
 | |
| 
 | |
| macro_rules! stringify_ty {
 | |
|     ($ty:ty) => {
 | |
|         stringify!($ty)
 | |
|     };
 | |
| }
 | |
| 
 | |
| macro_rules! stringify_vis {
 | |
|     ($vis:vis) => {
 | |
|         stringify!($vis)
 | |
|     };
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_block() {
 | |
|     assert_eq!(stringify_block!({}), "{}");
 | |
|     assert_eq!(stringify_block!({ true }), "{ true }");
 | |
|     assert_eq!(stringify_block!({ return }), "{ return }");
 | |
|     assert_eq!(
 | |
|         stringify_block!({
 | |
|             return;
 | |
|         }),
 | |
|         "{ return; }",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_block!({
 | |
|             let _;
 | |
|             true
 | |
|         }),
 | |
|         "{ let _; true }",
 | |
|     );
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_expr() {
 | |
|     // ExprKind::Box
 | |
|     assert_eq!(stringify_expr!(box expr), "box expr");
 | |
| 
 | |
|     // ExprKind::Array
 | |
|     assert_eq!(stringify_expr!([]), "[]");
 | |
|     assert_eq!(stringify_expr!([true]), "[true]");
 | |
|     assert_eq!(stringify_expr!([true,]), "[true]");
 | |
|     assert_eq!(stringify_expr!([true, true]), "[true, true]");
 | |
| 
 | |
|     // ExprKind::Call
 | |
|     assert_eq!(stringify_expr!(f()), "f()");
 | |
|     assert_eq!(stringify_expr!(f::<u8>()), "f::<u8>()");
 | |
|     assert_eq!(stringify_expr!(f::<1>()), "f::<1>()");
 | |
|     assert_eq!(stringify_expr!(f::<'a, u8, 1>()), "f::<'a, u8, 1>()");
 | |
|     assert_eq!(stringify_expr!(f(true)), "f(true)");
 | |
|     assert_eq!(stringify_expr!(f(true,)), "f(true)");
 | |
|     assert_eq!(stringify_expr!(()()), "()()");
 | |
| 
 | |
|     // ExprKind::MethodCall
 | |
|     assert_eq!(stringify_expr!(x.f()), "x.f()");
 | |
|     assert_eq!(stringify_expr!(x.f::<u8>()), "x.f::<u8>()");
 | |
| 
 | |
|     // ExprKind::Tup
 | |
|     assert_eq!(stringify_expr!(()), "()");
 | |
|     assert_eq!(stringify_expr!((true,)), "(true,)");
 | |
|     assert_eq!(stringify_expr!((true, false)), "(true, false)");
 | |
|     assert_eq!(stringify_expr!((true, false,)), "(true, false)");
 | |
| 
 | |
|     // ExprKind::Binary
 | |
|     assert_eq!(stringify_expr!(true || false), "true || false");
 | |
|     assert_eq!(stringify_expr!(true || false && false), "true || false && false");
 | |
| 
 | |
|     // ExprKind::Unary
 | |
|     assert_eq!(stringify_expr!(*expr), "*expr");
 | |
|     assert_eq!(stringify_expr!(!expr), "!expr");
 | |
|     assert_eq!(stringify_expr!(-expr), "-expr");
 | |
| 
 | |
|     // ExprKind::Lit
 | |
|     assert_eq!(stringify_expr!('x'), "'x'");
 | |
|     assert_eq!(stringify_expr!(1_000_i8), "1_000_i8");
 | |
|     assert_eq!(stringify_expr!(1.00000000000000001), "1.00000000000000001");
 | |
| 
 | |
|     // ExprKind::Cast
 | |
|     assert_eq!(stringify_expr!(expr as T), "expr as T");
 | |
|     assert_eq!(stringify_expr!(expr as T<u8>), "expr as T<u8>");
 | |
| 
 | |
|     // ExprKind::Type
 | |
|     assert_eq!(stringify_expr!(expr: T), "expr: T");
 | |
|     assert_eq!(stringify_expr!(expr: T<u8>), "expr: T<u8>");
 | |
| 
 | |
|     // ExprKind::If
 | |
|     assert_eq!(stringify_expr!(if true {}), "if true {}");
 | |
|     assert_eq!(
 | |
|         stringify_expr!(if true {
 | |
|         } else {
 | |
|         }),
 | |
|         "if true {} else {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_expr!(if let true = true {
 | |
|         } else {
 | |
|         }),
 | |
|         "if let true = true {} else {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_expr!(if true {
 | |
|         } else if false {
 | |
|         }),
 | |
|         "if true {} else if false {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_expr!(if true {
 | |
|         } else if false {
 | |
|         } else {
 | |
|         }),
 | |
|         "if true {} else if false {} else {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_expr!(if true {
 | |
|             return;
 | |
|         } else if false {
 | |
|             0
 | |
|         } else {
 | |
|             0
 | |
|         }),
 | |
|         "if true { return; } else if false { 0 } else { 0 }",
 | |
|     );
 | |
| 
 | |
|     // ExprKind::While
 | |
|     assert_eq!(stringify_expr!(while true {}), "while true {}");
 | |
|     assert_eq!(stringify_expr!('a: while true {}), "'a: while true {}");
 | |
|     assert_eq!(stringify_expr!(while let true = true {}), "while let true = true {}");
 | |
| 
 | |
|     // ExprKind::ForLoop
 | |
|     assert_eq!(stringify_expr!(for _ in x {}), "for _ in x {}");
 | |
|     assert_eq!(stringify_expr!('a: for _ in x {}), "'a: for _ in x {}");
 | |
| 
 | |
|     // ExprKind::Loop
 | |
|     assert_eq!(stringify_expr!(loop {}), "loop {}");
 | |
|     assert_eq!(stringify_expr!('a: loop {}), "'a: loop {}");
 | |
| 
 | |
|     // ExprKind::Match
 | |
|     assert_eq!(stringify_expr!(match self {}), "match self {}");
 | |
|     assert_eq!(
 | |
|         stringify_expr!(match self {
 | |
|             Ok => 1,
 | |
|         }),
 | |
|         "match self { Ok => 1, }",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_expr!(match self {
 | |
|             Ok => 1,
 | |
|             Err => 0,
 | |
|         }),
 | |
|         "match self { Ok => 1, Err => 0, }",
 | |
|     );
 | |
| 
 | |
|     // ExprKind::Closure
 | |
|     assert_eq!(stringify_expr!(|| {}), "|| {}");
 | |
|     assert_eq!(stringify_expr!(|x| {}), "|x| {}");
 | |
|     assert_eq!(stringify_expr!(|x: u8| {}), "|x: u8| {}");
 | |
|     assert_eq!(stringify_expr!(|| ()), "|| ()");
 | |
|     assert_eq!(stringify_expr!(move || self), "move || self");
 | |
|     assert_eq!(stringify_expr!(async || self), "async || self");
 | |
|     assert_eq!(stringify_expr!(async move || self), "async move || self");
 | |
|     assert_eq!(stringify_expr!(static || self), "static || self");
 | |
|     assert_eq!(stringify_expr!(static move || self), "static move || self");
 | |
|     #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5149
 | |
|     assert_eq!(
 | |
|         stringify_expr!(static async || self),
 | |
|         "static async || self",
 | |
|     );
 | |
|     #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5149
 | |
|     assert_eq!(
 | |
|         stringify_expr!(static async move || self),
 | |
|         "static async move || self",
 | |
|     );
 | |
|     assert_eq!(stringify_expr!(|| -> u8 { self }), "|| -> u8 { self }");
 | |
|     assert_eq!(stringify_expr!(1 + || {}), "1 + (|| {})"); // ??
 | |
| 
 | |
|     // ExprKind::Block
 | |
|     assert_eq!(stringify_expr!({}), "{}");
 | |
|     assert_eq!(stringify_expr!(unsafe {}), "unsafe {}");
 | |
|     assert_eq!(stringify_expr!('a: {}), "'a: {}");
 | |
|     assert_eq!(
 | |
|         stringify_expr!(
 | |
|             #[attr]
 | |
|             {}
 | |
|         ),
 | |
|         "#[attr] {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_expr!(
 | |
|             {
 | |
|                 #![attr]
 | |
|             }
 | |
|         ),
 | |
|         "{\n\
 | |
|         \x20   #![attr]\n\
 | |
|         }",
 | |
|     );
 | |
| 
 | |
|     // ExprKind::Async
 | |
|     assert_eq!(stringify_expr!(async {}), "async {}");
 | |
|     assert_eq!(stringify_expr!(async move {}), "async move {}");
 | |
| 
 | |
|     // ExprKind::Await
 | |
|     assert_eq!(stringify_expr!(expr.await), "expr.await");
 | |
| 
 | |
|     // ExprKind::TryBlock
 | |
|     assert_eq!(stringify_expr!(try {}), "try {}");
 | |
| 
 | |
|     // ExprKind::Assign
 | |
|     assert_eq!(stringify_expr!(expr = true), "expr = true");
 | |
| 
 | |
|     // ExprKind::AssignOp
 | |
|     assert_eq!(stringify_expr!(expr += true), "expr += true");
 | |
| 
 | |
|     // ExprKind::Field
 | |
|     assert_eq!(stringify_expr!(expr.field), "expr.field");
 | |
|     assert_eq!(stringify_expr!(expr.0), "expr.0");
 | |
| 
 | |
|     // ExprKind::Index
 | |
|     assert_eq!(stringify_expr!(expr[true]), "expr[true]");
 | |
| 
 | |
|     // ExprKind::Range
 | |
|     assert_eq!(stringify_expr!(..), "..");
 | |
|     assert_eq!(stringify_expr!(..hi), "..hi");
 | |
|     assert_eq!(stringify_expr!(lo..), "lo..");
 | |
|     assert_eq!(stringify_expr!(lo..hi), "lo..hi");
 | |
|     assert_eq!(stringify_expr!(..=hi), "..=hi");
 | |
|     assert_eq!(stringify_expr!(lo..=hi), "lo..=hi");
 | |
|     assert_eq!(stringify_expr!(-2..=-1), "-2..=-1");
 | |
| 
 | |
|     // ExprKind::Path
 | |
|     assert_eq!(stringify_expr!(thing), "thing");
 | |
|     assert_eq!(stringify_expr!(m::thing), "m::thing");
 | |
|     assert_eq!(stringify_expr!(self::thing), "self::thing");
 | |
|     assert_eq!(stringify_expr!(crate::thing), "crate::thing");
 | |
|     assert_eq!(stringify_expr!(Self::thing), "Self::thing");
 | |
|     assert_eq!(stringify_expr!(<Self as T>::thing), "<Self as T>::thing");
 | |
|     assert_eq!(stringify_expr!(Self::<'static>), "Self::<'static>");
 | |
| 
 | |
|     // ExprKind::AddrOf
 | |
|     assert_eq!(stringify_expr!(&expr), "&expr");
 | |
|     assert_eq!(stringify_expr!(&mut expr), "&mut expr");
 | |
|     assert_eq!(stringify_expr!(&raw const expr), "&raw const expr");
 | |
|     assert_eq!(stringify_expr!(&raw mut expr), "&raw mut expr");
 | |
| 
 | |
|     // ExprKind::Break
 | |
|     assert_eq!(stringify_expr!(break), "break");
 | |
|     assert_eq!(stringify_expr!(break 'a), "break 'a");
 | |
|     assert_eq!(stringify_expr!(break true), "break true");
 | |
|     assert_eq!(stringify_expr!(break 'a true), "break 'a true");
 | |
| 
 | |
|     // ExprKind::Continue
 | |
|     assert_eq!(stringify_expr!(continue), "continue");
 | |
|     assert_eq!(stringify_expr!(continue 'a), "continue 'a");
 | |
| 
 | |
|     // ExprKind::Ret
 | |
|     assert_eq!(stringify_expr!(return), "return");
 | |
|     assert_eq!(stringify_expr!(return true), "return true");
 | |
| 
 | |
|     // ExprKind::MacCall
 | |
|     assert_eq!(stringify_expr!(mac!(...)), "mac!(...)");
 | |
|     assert_eq!(stringify_expr!(mac![...]), "mac![...]");
 | |
|     assert_eq!(stringify_expr!(mac! { ... }), "mac! { ... }");
 | |
| 
 | |
|     // ExprKind::Struct
 | |
|     assert_eq!(stringify_expr!(Struct {}), "Struct {}");
 | |
|     #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5151
 | |
|     assert_eq!(stringify_expr!(<Struct as Trait>::Type {}), "<Struct as Trait>::Type {}");
 | |
|     assert_eq!(stringify_expr!(Struct { .. }), "Struct { .. }");
 | |
|     assert_eq!(stringify_expr!(Struct { ..base }), "Struct { ..base }");
 | |
|     assert_eq!(stringify_expr!(Struct { x }), "Struct { x }");
 | |
|     assert_eq!(stringify_expr!(Struct { x, .. }), "Struct { x, .. }");
 | |
|     assert_eq!(stringify_expr!(Struct { x, ..base }), "Struct { x, ..base }");
 | |
|     assert_eq!(stringify_expr!(Struct { x: true }), "Struct { x: true }");
 | |
|     assert_eq!(stringify_expr!(Struct { x: true, .. }), "Struct { x: true, .. }");
 | |
|     assert_eq!(stringify_expr!(Struct { x: true, ..base }), "Struct { x: true, ..base }");
 | |
| 
 | |
|     // ExprKind::Repeat
 | |
|     assert_eq!(stringify_expr!([(); 0]), "[(); 0]");
 | |
| 
 | |
|     // ExprKind::Paren
 | |
|     assert_eq!(stringify_expr!((expr)), "(expr)");
 | |
| 
 | |
|     // ExprKind::Try
 | |
|     assert_eq!(stringify_expr!(expr?), "expr?");
 | |
| 
 | |
|     // ExprKind::Yield
 | |
|     assert_eq!(stringify_expr!(yield), "yield");
 | |
|     assert_eq!(stringify_expr!(yield true), "yield true");
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_item() {
 | |
|     // ItemKind::ExternCrate
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             extern crate std;
 | |
|         ),
 | |
|         "extern crate std;",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub extern crate self as std;
 | |
|         ),
 | |
|         "pub extern crate self as std;",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::Use
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub use crate::{a, b::c};
 | |
|         ),
 | |
|         "pub use crate::{a, b::c};",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::Static
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub static S: () = {};
 | |
|         ),
 | |
|         "pub static S: () = {};",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             static mut S: () = {};
 | |
|         ),
 | |
|         "static mut S: () = {};",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             static S: ();
 | |
|         ),
 | |
|         "static S: ();",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             static mut S: ();
 | |
|         ),
 | |
|         "static mut S: ();",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::Const
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub const S: () = {};
 | |
|         ),
 | |
|         "pub const S: () = {};",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             const S: ();
 | |
|         ),
 | |
|         "const S: ();",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::Fn
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub default const async unsafe extern "C" fn f() {}
 | |
|         ),
 | |
|         "pub default const async unsafe extern \"C\" fn f() {}",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::Mod
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub mod m;
 | |
|         ),
 | |
|         "pub mod m;",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             mod m {}
 | |
|         ),
 | |
|         "mod m {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             unsafe mod m;
 | |
|         ),
 | |
|         "unsafe mod m;",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             unsafe mod m {}
 | |
|         ),
 | |
|         "unsafe mod m {}",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::ForeignMod
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             extern "C" {}
 | |
|         ),
 | |
|         "extern \"C\" {}",
 | |
|     );
 | |
|     #[rustfmt::skip]
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub extern "C" {}
 | |
|         ),
 | |
|         "extern \"C\" {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             unsafe extern "C++" {}
 | |
|         ),
 | |
|         "unsafe extern \"C++\" {}",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::TyAlias
 | |
|     #[rustfmt::skip]
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub default type Type<'a>: Bound
 | |
|             where
 | |
|                 Self: 'a,
 | |
|             = T;
 | |
|         ),
 | |
|         "pub default type Type<'a>: Bound where Self: 'a = T;",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::Enum
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub enum Void {}
 | |
|         ),
 | |
|         "pub enum Void {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             enum Empty {
 | |
|                 Unit,
 | |
|                 Tuple(),
 | |
|                 Struct {},
 | |
|             }
 | |
|         ),
 | |
|         "enum Empty { Unit, Tuple(), Struct {}, }",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             enum Enum<T>
 | |
|             where
 | |
|                 T: 'a,
 | |
|             {
 | |
|                 Unit,
 | |
|                 Tuple(T),
 | |
|                 Struct { t: T },
 | |
|             }
 | |
|         ),
 | |
|         "enum Enum<T> where T: 'a {\n\
 | |
|         \x20   Unit,\n\
 | |
|         \x20   Tuple(T),\n\
 | |
|         \x20   Struct {\n\
 | |
|         \x20       t: T,\n\
 | |
|         \x20   },\n\
 | |
|         }",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::Struct
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub struct Unit;
 | |
|         ),
 | |
|         "pub struct Unit;",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             struct Tuple();
 | |
|         ),
 | |
|         "struct Tuple();",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             struct Tuple(T);
 | |
|         ),
 | |
|         "struct Tuple(T);",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             struct Struct {}
 | |
|         ),
 | |
|         "struct Struct {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             struct Struct<T>
 | |
|             where
 | |
|                 T: 'a,
 | |
|             {
 | |
|                 t: T,
 | |
|             }
 | |
|         ),
 | |
|         "struct Struct<T> where T: 'a {\n\
 | |
|         \x20   t: T,\n\
 | |
|         }",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::Union
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub union Union {}
 | |
|         ),
 | |
|         "pub union Union {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             union Union<T> where T: 'a {
 | |
|                 t: T,
 | |
|             }
 | |
|         ),
 | |
|         "union Union<T> where T: 'a {\n\
 | |
|         \x20   t: T,\n\
 | |
|         }",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::Trait
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub unsafe auto trait Send {}
 | |
|         ),
 | |
|         "pub unsafe auto trait Send {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             trait Trait<'a>: Sized
 | |
|             where
 | |
|                 Self: 'a,
 | |
|             {
 | |
|             }
 | |
|         ),
 | |
|         "trait Trait<'a>: Sized where Self: 'a {}",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::TraitAlias
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub trait Trait<T> = Sized where T: 'a;
 | |
|         ),
 | |
|         "pub trait Trait<T> = Sized where T: 'a;",
 | |
|     );
 | |
| 
 | |
|     // ItemKind::Impl
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub impl Struct {}
 | |
|         ),
 | |
|         "pub impl Struct {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             impl<T> Struct<T> {}
 | |
|         ),
 | |
|         "impl<T> Struct<T> {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub impl Trait for Struct {}
 | |
|         ),
 | |
|         "pub impl Trait for Struct {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             impl<T> const Trait for T {}
 | |
|         ),
 | |
|         "impl<T> const Trait for T {}",
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             impl ~const Struct {}
 | |
|         ),
 | |
|         "impl Struct {}", // FIXME
 | |
|     );
 | |
| 
 | |
|     // ItemKind::MacCall
 | |
|     assert_eq!(stringify_item!(mac!(...);), "mac!(...);");
 | |
|     assert_eq!(stringify_item!(mac![...];), "mac![...];");
 | |
|     assert_eq!(stringify_item!(mac! { ... }), "mac! { ... }");
 | |
| 
 | |
|     // ItemKind::MacroDef
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             macro_rules! stringify {
 | |
|                 () => {};
 | |
|             }
 | |
|         ),
 | |
|         "macro_rules! stringify { () => {} ; }", // FIXME
 | |
|     );
 | |
|     assert_eq!(
 | |
|         stringify_item!(
 | |
|             pub macro stringify() {}
 | |
|         ),
 | |
|         "pub macro stringify { () => {} }",
 | |
|     );
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_meta() {
 | |
|     assert_eq!(stringify_meta!(k), "k");
 | |
|     assert_eq!(stringify_meta!(k = "v"), "k = \"v\"");
 | |
|     assert_eq!(stringify_meta!(list(k1, k2 = "v")), "list(k1, k2 = \"v\")");
 | |
|     assert_eq!(stringify_meta!(serde::k), "serde::k");
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_pat() {
 | |
|     // PatKind::Wild
 | |
|     assert_eq!(stringify_pat!(_), "_");
 | |
| 
 | |
|     // PatKind::Ident
 | |
|     assert_eq!(stringify_pat!(_x), "_x");
 | |
|     assert_eq!(stringify_pat!(ref _x), "ref _x");
 | |
|     assert_eq!(stringify_pat!(mut _x), "mut _x");
 | |
|     assert_eq!(stringify_pat!(ref mut _x), "ref mut _x");
 | |
|     assert_eq!(stringify_pat!(ref mut _x @ _), "ref mut _x @ _");
 | |
| 
 | |
|     // PatKind::Struct
 | |
|     assert_eq!(stringify_pat!(Struct {}), "Struct {}");
 | |
|     assert_eq!(stringify_pat!(Struct::<u8> {}), "Struct::<u8> {}");
 | |
|     assert_eq!(stringify_pat!(Struct::<'static> {}), "Struct::<'static> {}");
 | |
|     assert_eq!(stringify_pat!(Struct { x }), "Struct { x }");
 | |
|     assert_eq!(stringify_pat!(Struct { x: _x }), "Struct { x: _x }");
 | |
|     assert_eq!(stringify_pat!(Struct { .. }), "Struct { .. }");
 | |
|     assert_eq!(stringify_pat!(Struct { x, .. }), "Struct { x, .. }");
 | |
|     assert_eq!(stringify_pat!(Struct { x: _x, .. }), "Struct { x: _x, .. }");
 | |
|     #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5151
 | |
|     assert_eq!(
 | |
|         stringify_pat!(<Struct as Trait>::Type {}),
 | |
|         "<Struct as Trait>::Type {}",
 | |
|     );
 | |
| 
 | |
|     // PatKind::TupleStruct
 | |
|     assert_eq!(stringify_pat!(Tuple()), "Tuple()");
 | |
|     assert_eq!(stringify_pat!(Tuple::<u8>()), "Tuple::<u8>()");
 | |
|     assert_eq!(stringify_pat!(Tuple::<'static>()), "Tuple::<'static>()");
 | |
|     assert_eq!(stringify_pat!(Tuple(x)), "Tuple(x)");
 | |
|     assert_eq!(stringify_pat!(Tuple(..)), "Tuple(..)");
 | |
|     assert_eq!(stringify_pat!(Tuple(x, ..)), "Tuple(x, ..)");
 | |
|     assert_eq!(stringify_pat!(<Struct as Trait>::Type()), "<Struct as Trait>::Type()");
 | |
| 
 | |
|     // PatKind::Or
 | |
|     assert_eq!(stringify_pat!(true | false), "true | false");
 | |
|     assert_eq!(stringify_pat!(| true), "true");
 | |
|     assert_eq!(stringify_pat!(|true| false), "true | false");
 | |
| 
 | |
|     // PatKind::Path
 | |
|     assert_eq!(stringify_pat!(crate::Path), "crate::Path");
 | |
|     assert_eq!(stringify_pat!(Path::<u8>), "Path::<u8>");
 | |
|     assert_eq!(stringify_pat!(Path::<'static>), "Path::<'static>");
 | |
|     assert_eq!(stringify_pat!(<Struct as Trait>::Type), "<Struct as Trait>::Type");
 | |
| 
 | |
|     // PatKind::Tuple
 | |
|     assert_eq!(stringify_pat!(()), "()");
 | |
|     assert_eq!(stringify_pat!((true,)), "(true,)");
 | |
|     assert_eq!(stringify_pat!((true, false)), "(true, false)");
 | |
| 
 | |
|     // PatKind::Box
 | |
|     assert_eq!(stringify_pat!(box pat), "box pat");
 | |
| 
 | |
|     // PatKind::Ref
 | |
|     assert_eq!(stringify_pat!(&pat), "&pat");
 | |
|     assert_eq!(stringify_pat!(&mut pat), "&mut pat");
 | |
| 
 | |
|     // PatKind::Lit
 | |
|     assert_eq!(stringify_pat!(1_000_i8), "1_000_i8");
 | |
| 
 | |
|     // PatKind::Range
 | |
|     assert_eq!(stringify_pat!(..1), "..1");
 | |
|     assert_eq!(stringify_pat!(0..), "0..");
 | |
|     assert_eq!(stringify_pat!(0..1), "0..1");
 | |
|     assert_eq!(stringify_pat!(0..=1), "0..=1");
 | |
|     assert_eq!(stringify_pat!(-2..=-1), "-2..=-1");
 | |
| 
 | |
|     // PatKind::Slice
 | |
|     assert_eq!(stringify_pat!([]), "[]");
 | |
|     assert_eq!(stringify_pat!([true]), "[true]");
 | |
|     assert_eq!(stringify_pat!([true,]), "[true]");
 | |
|     assert_eq!(stringify_pat!([true, false]), "[true, false]");
 | |
| 
 | |
|     // PatKind::Rest
 | |
|     assert_eq!(stringify_pat!(..), "..");
 | |
| 
 | |
|     // PatKind::Paren
 | |
|     assert_eq!(stringify_pat!((pat)), "(pat)");
 | |
| 
 | |
|     // PatKind::MacCall
 | |
|     assert_eq!(stringify_pat!(mac!(...)), "mac!(...)");
 | |
|     assert_eq!(stringify_pat!(mac![...]), "mac![...]");
 | |
|     assert_eq!(stringify_pat!(mac! { ... }), "mac! { ... }");
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_path() {
 | |
|     assert_eq!(stringify_path!(thing), "thing");
 | |
|     assert_eq!(stringify_path!(m::thing), "m::thing");
 | |
|     assert_eq!(stringify_path!(self::thing), "self::thing");
 | |
|     assert_eq!(stringify_path!(crate::thing), "crate::thing");
 | |
|     assert_eq!(stringify_path!(Self::thing), "Self::thing");
 | |
|     assert_eq!(stringify_path!(Self<'static>), "Self<'static>");
 | |
|     assert_eq!(stringify_path!(Self::<'static>), "Self<'static>");
 | |
|     assert_eq!(stringify_path!(Self()), "Self()");
 | |
|     assert_eq!(stringify_path!(Self() -> ()), "Self() -> ()");
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_stmt() {
 | |
|     // StmtKind::Local
 | |
|     assert_eq!(stringify_stmt!(let _), "let _;");
 | |
|     assert_eq!(stringify_stmt!(let x = true), "let x = true;");
 | |
|     assert_eq!(stringify_stmt!(let x: bool = true), "let x: bool = true;");
 | |
| 
 | |
|     // StmtKind::Item
 | |
|     assert_eq!(
 | |
|         stringify_stmt!(
 | |
|             struct S;
 | |
|         ),
 | |
|         "struct S;",
 | |
|     );
 | |
| 
 | |
|     // StmtKind::Expr
 | |
|     assert_eq!(stringify_stmt!(loop {}), "loop {}");
 | |
| 
 | |
|     // StmtKind::Semi
 | |
|     assert_eq!(stringify_stmt!(1 + 1), "1 + 1;");
 | |
| 
 | |
|     // StmtKind::Empty
 | |
|     assert_eq!(stringify_stmt!(;), ";");
 | |
| 
 | |
|     // StmtKind::MacCall
 | |
|     assert_eq!(stringify_stmt!(mac!(...)), "mac!(...)");
 | |
|     assert_eq!(stringify_stmt!(mac![...]), "mac![...]");
 | |
|     assert_eq!(stringify_stmt!(mac! { ... }), "mac! { ... }");
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_ty() {
 | |
|     // TyKind::Slice
 | |
|     assert_eq!(stringify_ty!([T]), "[T]");
 | |
| 
 | |
|     // TyKind::Array
 | |
|     assert_eq!(stringify_ty!([T; 0]), "[T; 0]");
 | |
| 
 | |
|     // TyKind::Ptr
 | |
|     assert_eq!(stringify_ty!(*const T), "*const T");
 | |
|     assert_eq!(stringify_ty!(*mut T), "*mut T");
 | |
| 
 | |
|     // TyKind::Ref
 | |
|     assert_eq!(stringify_ty!(&T), "&T");
 | |
|     assert_eq!(stringify_ty!(&mut T), "&mut T");
 | |
|     assert_eq!(stringify_ty!(&'a T), "&'a T");
 | |
|     assert_eq!(stringify_ty!(&'a mut T), "&'a mut T");
 | |
| 
 | |
|     // TyKind::BareFn
 | |
|     assert_eq!(stringify_ty!(fn()), "fn()");
 | |
|     assert_eq!(stringify_ty!(fn() -> ()), "fn() -> ()");
 | |
|     assert_eq!(stringify_ty!(fn(u8)), "fn(u8)");
 | |
|     assert_eq!(stringify_ty!(fn(x: u8)), "fn(x: u8)");
 | |
|     #[rustfmt::skip]
 | |
|     assert_eq!(stringify_ty!(for<> fn()), "fn()");
 | |
|     assert_eq!(stringify_ty!(for<'a> fn()), "for<'a> fn()");
 | |
| 
 | |
|     // TyKind::Never
 | |
|     assert_eq!(stringify_ty!(!), "!");
 | |
| 
 | |
|     // TyKind::Tup
 | |
|     assert_eq!(stringify_ty!(()), "()");
 | |
|     assert_eq!(stringify_ty!((T,)), "(T,)");
 | |
|     assert_eq!(stringify_ty!((T, U)), "(T, U)");
 | |
| 
 | |
|     // TyKind::Path
 | |
|     assert_eq!(stringify_ty!(T), "T");
 | |
|     assert_eq!(stringify_ty!(Ref<'a>), "Ref<'a>");
 | |
|     assert_eq!(stringify_ty!(PhantomData<T>), "PhantomData<T>");
 | |
|     assert_eq!(stringify_ty!(PhantomData::<T>), "PhantomData<T>");
 | |
|     assert_eq!(stringify_ty!(Fn() -> !), "Fn() -> !");
 | |
|     assert_eq!(stringify_ty!(Fn(u8) -> !), "Fn(u8) -> !");
 | |
|     assert_eq!(stringify_ty!(<Struct as Trait>::Type), "<Struct as Trait>::Type");
 | |
| 
 | |
|     // TyKind::TraitObject
 | |
|     assert_eq!(stringify_ty!(dyn Send), "dyn Send");
 | |
|     assert_eq!(stringify_ty!(dyn Send + 'a), "dyn Send + 'a");
 | |
|     assert_eq!(stringify_ty!(dyn 'a + Send), "dyn 'a + Send");
 | |
|     assert_eq!(stringify_ty!(dyn ?Sized), "dyn ?Sized");
 | |
|     assert_eq!(stringify_ty!(dyn ~const Clone), "dyn Clone"); // FIXME
 | |
|     assert_eq!(stringify_ty!(dyn for<'a> Send), "dyn for<'a> Send");
 | |
| 
 | |
|     // TyKind::ImplTrait
 | |
|     assert_eq!(stringify_ty!(impl Send), "impl Send");
 | |
|     assert_eq!(stringify_ty!(impl Send + 'a), "impl Send + 'a");
 | |
|     assert_eq!(stringify_ty!(impl 'a + Send), "impl 'a + Send");
 | |
|     assert_eq!(stringify_ty!(impl ?Sized), "impl ?Sized");
 | |
|     assert_eq!(stringify_ty!(impl ~const Clone), "impl Clone"); // FIXME
 | |
|     assert_eq!(stringify_ty!(impl for<'a> Send), "impl for<'a> Send");
 | |
| 
 | |
|     // TyKind::Paren
 | |
|     assert_eq!(stringify_ty!((T)), "(T)");
 | |
| 
 | |
|     // TyKind::Infer
 | |
|     assert_eq!(stringify_ty!(_), "_");
 | |
| 
 | |
|     // TyKind::MacCall
 | |
|     assert_eq!(stringify_ty!(mac!(...)), "mac!(...)");
 | |
|     assert_eq!(stringify_ty!(mac![...]), "mac![...]");
 | |
|     assert_eq!(stringify_ty!(mac! { ... }), "mac! { ... }");
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_vis() {
 | |
|     // VisibilityKind::Public
 | |
|     assert_eq!(stringify_vis!(pub), "pub ");
 | |
| 
 | |
|     // VisibilityKind::Restricted
 | |
|     assert_eq!(stringify_vis!(pub(crate)), "pub(crate) ");
 | |
|     assert_eq!(stringify_vis!(pub(self)), "pub(self) ");
 | |
|     assert_eq!(stringify_vis!(pub(super)), "pub(super) ");
 | |
|     assert_eq!(stringify_vis!(pub(in crate)), "pub(in crate) ");
 | |
|     assert_eq!(stringify_vis!(pub(in self)), "pub(in self) ");
 | |
|     assert_eq!(stringify_vis!(pub(in super)), "pub(in super) ");
 | |
|     assert_eq!(stringify_vis!(pub(in path::to)), "pub(in path::to) ");
 | |
|     assert_eq!(stringify_vis!(pub(in ::path::to)), "pub(in ::path::to) ");
 | |
|     assert_eq!(stringify_vis!(pub(in self::path::to)), "pub(in self::path::to) ");
 | |
|     assert_eq!(stringify_vis!(pub(in super::path::to)), "pub(in super::path::to) ");
 | |
| 
 | |
|     // VisibilityKind::Inherited
 | |
|     // Directly calling `stringify_vis!()` does not work.
 | |
|     macro_rules! stringify_inherited_vis {
 | |
|         ($vis:vis struct) => {
 | |
|             stringify_vis!($vis)
 | |
|         };
 | |
|     }
 | |
|     assert_eq!(stringify_inherited_vis!(struct), "");
 | |
| }
 | 
