Try   HackMD

Comma-Terminated Fragments and #[cfg]

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.


Can be decorated

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)
{}

Can not be decorated

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
}