| /// Tests that the `#[rustc_splat]` attribute is preserved by rustfmt. |
| /// This attribute is currently unstable, and its syntax might change in future. |
| /// It currently uses the default formatting for attributes. |
| |
| // These snippets are mainly from rust/tests/ui/splat |
| |
| // Rejected by rustc, but still needs to be formatted correctly |
| |
| // Can't have rust-call and splat on the same function |
| trait Trait: Tuple + Sized { |
| extern "rust-call" fn method(#[rustc_splat] self: Self); |
| } |
| |
| extern "rust-call" fn f(#[rustc_splat] _: ()); |
| |
| fn wrong_type(#[rustc_splat] _x: u32) {} |
| |
| // Can't have multiple splats in the same function |
| fn multi_splat_bad(#[rustc_splat] (_a, _b): (u32, i8), #[rustc_splat] (_c, _d): (u32, i8)) {} |
| |
| // Multiple splats on the same argument are redundant |
| fn multisplat_arg_bad( |
| #[rustc_splat] |
| #[rustc_splat] |
| (_a, _b): (u32, i8), |
| ) { |
| } |
| |
| fn multisplat_arg_fn_bad( |
| #[rustc_splat] |
| #[rustc_splat] |
| (_a, _b): (u32, i8), |
| #[rustc_splat] (_c, _d): (u32, i8), |
| ) { |
| } |
| |
| // Can't have variadic and splat on the same function |
| unsafe extern "C" fn splat_variadic(#[rustc_splat] (_a, _b): (u32, i8), varargs: ...) {} |
| unsafe extern "C" fn splat_variadic2(varargs: ..., #[rustc_splat] (_a, _b): (u32, i8)) {} |
| |
| // Accepted by rustc |
| struct Foo; |
| |
| impl Foo { |
| fn method(&self, #[rustc_splat] args: impl MethodArgs) -> String {} |
| fn tuple_1(#[rustc_splat] (_a,): (u32,)) {} |
| fn tuple_3(#[rustc_splat] (_a, _b, _c): (u32, i32, i8)) {} |
| } |
| |
| fn generic<T: Tuple + Debug>(#[rustc_splat] a: T) -> String { |
| String::new() |
| } |
| |
| fn splat_non_terminal_arg(#[rustc_splat] (a, b): (u32, i8), c: f64) -> (i8, f64, u32) { |
| (a, b, c) |
| } |
| |
| const X: fn(#[rustc_splat] (f32,)) = None.unwrap(); |
| |
| fn main() { |
| struct Type<T: ?Sized>(T); |
| |
| // Rejected by rustc, but still needs to be formatted correctly |
| // Closures |
| (|#[rustc_splat] x: i32| {})(1); |
| |
| // Function pointer types |
| |
| // Rust-call and splat aren't allowed in the same function |
| let f_: extern "rust-call" fn(#[rustc_splat] ()) = f; |
| |
| let wrong_type_: fn(#[rustc_splat] _x: u32) = wrong_type; |
| |
| let multi_splat_bad_: fn(#[rustc_splat] (u32, i8), #[rustc_splat] (u32, i8)) = multi_splat_bad; |
| let multisplat_arg_bad_: fn( |
| #[rustc_splat] |
| #[rustc_splat] |
| (u32, i8), |
| ) = multisplat_arg_bad; |
| let multisplat_arg_fn_bad_: fn( |
| #[rustc_splat] |
| #[rustc_splat] |
| (u32, i8), |
| #[rustc_splat] (u32, i8), |
| ) = multisplat_arg_fn_bad; |
| |
| // Splat and variadic aren't allowed in the same function |
| let splat_variadic_: unsafe extern "C" fn(#[rustc_splat] (u32, i8), ...) = splat_variadic; |
| let splat_variadic2_: unsafe extern "C" fn(..., #[rustc_splat] (u32, i8)) = splat_variadic2; |
| |
| // Accepted by rustc |
| // Function pointer types |
| |
| // Only one splatted arg |
| let fn_ptr: fn(#[rustc_splat] (u32, i8)) -> String = |
| generic as fn(#[rustc_splat] (u32, i8)) -> String; |
| impl Type<fn(#[rustc_splat] (u8, u32))> {} |
| |
| // Leading splatted arg |
| let fn_pp: *const fn(#[rustc_splat] (u32, i8), f64) -> (i8, f64, u32) = |
| &(splat_non_terminal_arg as fn(#[rustc_splat] (u32, i8), f64) -> (i8, f64, u32)); |
| |
| // Trailing splatted arg |
| impl Type<*mut fn(u32, i8, #[rustc_splat] (f64,))> {} |
| |
| // Middle splatted arg |
| impl Type<&fn(u32, #[rustc_splat] (i8, f32, usize), f64)> {} |
| |
| // Splats within splats |
| impl Type<Box<fn(u32, #[rustc_splat] (fn(#[rustc_splat] ()), i8), f64)>> {} |
| } |