This is meant as a mostly exhaustive list of every comma-terminated (explicit or implicit) fragment type in the language, and whether or not it can be decorated with a cfg-attribute. Note that macros are excluded from this list because they would just try to match on the cfg-attribute syntax, and I don't see a strong reason to try to change that behavior.
Function arguments in signatures
fn foo(#[cfg(all())] a: u32) {} // OK
Function arguments for invocation
foo(#[cfg(all())] 1); // OK
Closure arguments
let a = |#[cfg(all())] a: u32| {}; // OK
Generic type arguments in signatures and declarations
fn foo<#[cfg(all())] T>(t: T) {} // OK
struct Foo<#[cfg(all())] T> { // OK
t: T,
}
Arguments for impl
(but oddly not for the struct argument, see below)
impl<#[cfg(all())] T> Foo<T> { } // OK
Associated type arguments
trait Foo {
type Inner<#[cfg(all())] 'a>; // OK
}
impl Foo for Bar {
type Inner<#[cfg(all())] 'a> = &'a u32; // OK
}
Struct fields (both types) and union fields:
struct Foo {
#[cfg(all())] t: u32, // OK
}
struct Foo (
#[cfg(all())] u32, // OK
);
#[repr(C)]
union Foo {
a: u32,
#[cfg(all())] b: f32, // OK
}
Struct initialization (both types) and tuple initialization
let x = Foo {
#[cfg(all())] t: 1u32, // OK
};
let x = Foo(
#[cfg(all())] 1u32, // OK
);
let x = (#[cfg(all())] 1u32,); // OK
Enums and match
enum Foo {
A,
#[cfg(all())] B, // OK
}
fn foo(a: Foo) -> u32 {
match a {
Foo::A => 1,
#[cfg(all())] Foo::B => 2, // OK
}
}
Arrays
fn foo() {
let x = [0, #[cfg(all())] 1][0]; // OK
}
Where clauses (in progress, see accepted RFC 3399 and tracking issue #115590):
impl<T> SomeTrait<T> for Foo
where
#[cfg(all())] T: SomeRequirementA, // OK (Eventually)
{}
Tuple type declaration (proposed, see open RFC 3532):
type Foo = (#[cfg(all())] u32,); // BAD
Explicit generic arguments in invocation:
foo::<#[cfg(all())] u32>(1); // BAD
Struct generic arguments, including in impl
struct Bar {
f: Foo<#[cfg(all())] u32>, // BAD
}
impl<#[cfg(all())] T> Foo<#[cfg(all())] T> { }
// ^^^^^^^^^^^^^ OK ^^^^^^^^^^^^^ BAD
Braced multi-use statements (this is a little silly)
use std::{ptr, #[cfg(all())] mem}; // BAD
Pattern matching
fn bar(v: (u32, u32)) {
let (a, #[cfg(all())] b) = v; // BAD
}