InnerAttribute :
# ! [ Attr ]

OuterAttribute :
# [ Attr ]

Attr :
SimplePath AttrInput?

AttrInput :
| = LiteralExpressionwithout suffix

An attribute is a general, free-form metadatum that is interpreted according to name, convention, language, and compiler version. Attributes are modeled on Attributes in ECMA-335, with the syntax coming from ECMA-334 (C#).

Inner attributes, written with a bang (!) after the hash (#), apply to the item that the attribute is declared within. Outer attributes, written without the bang after the hash, apply to the thing that follows the attribute.

The attribute consists of a path to the attribute, followed by an optional delimited token tree whose interpretation is defined by the attribute. Attributes other than macro attributes also allow the input to be an equals sign (=) followed by a literal expression. See the meta item syntax below for more details.

Attributes can be classified into the following kinds:

Attributes may be applied to many things in the language:

Some examples of attributes:

fn main() {
// General metadata applied to the enclosing module or crate.
#![crate_type = "lib"]

// A function marked as a unit test
fn test_foo() {
    /* ... */

// A conditionally-compiled module
#[cfg(target_os = "linux")]
mod bar {
    /* ... */

// A lint attribute used to suppress a warning/error
type int8_t = i8;

// Inner attribute applies to the entire function.
fn some_unused_variables() {

  let x = ();
  let y = ();
  let z = ();

Meta Item Attribute Syntax

A "meta item" is the syntax used for the Attr rule by most built-in attributes. It has the following grammar:

MetaItem :
| SimplePath = LiteralExpressionwithout suffix
| SimplePath ( MetaSeq? )

MetaSeq :
MetaItemInner ( , MetaItemInner )* ,?

MetaItemInner :
| LiteralExpressionwithout suffix

Literal expressions in meta items must not include integer or float type suffixes.

Various built-in attributes use different subsets of the meta item syntax to specify their inputs. The following grammar rules show some commonly used forms:



IDENTIFIER ( ( SimplePath (, SimplePath)* ,? )? )


IDENTIFIER ( ( MetaNameValueStr (, MetaNameValueStr)* ,? )? )

Some examples of meta items are:

Style Example
MetaWord no_std
MetaNameValueStr doc = "example"
MetaListPaths allow(unused, clippy::inline_always)
MetaListIdents macro_use(foo, bar)
MetaListNameValueStr link(name = "CoreFoundation", kind = "framework")

Active and inert attributes

An attribute is either active or inert. During attribute processing, active attributes remove themselves from the thing they are on while inert attributes stay on.

The cfg and cfg_attr attributes are active. The test attribute is inert when compiling for tests and active otherwise. Attribute macros are active. All other attributes are inert.

Tool attributes

The compiler may allow attributes for external tools where each tool resides in its own namespace. The first segment of the attribute path is the name of the tool, with one or more additional segments whose interpretation is up to the tool.

When a tool is not in use, the tool's attributes are accepted without a warning. When the tool is in use, the tool is responsible for processing and interpretation of its attributes.

Tool attributes are not available if the no_implicit_prelude attribute is used.

fn main() {
// Tells the rustfmt tool to not format the following element.
struct S {

// Controls the "cyclomatic complexity" threshold for the clippy tool.
#[clippy::cyclomatic_complexity = "100"]
pub fn f() {}

Note: rustc currently recognizes the tools "clippy" and "rustfmt".

Built-in attributes index

The following is an index of all built-in attributes.

  • Conditional compilation
    • cfg — Controls conditional compilation.
    • cfg_attr — Conditionally includes attributes.
  • Testing
    • test — Marks a function as a test.
    • ignore — Disables a test function.
    • should_panic — Indicates a test should generate a panic.
  • Derive
  • Macros
  • Diagnostics
  • ABI, linking, symbols, and FFI
    • link — Specifies a native library to link with an extern block.
    • link_name — Specifies the name of the symbol for functions or statics in an extern block.
    • no_link — Prevents linking an extern crate.
    • repr — Controls type layout.
    • crate_type — Specifies the type of crate (library, executable, etc.).
    • no_main — Disables emitting the main symbol.
    • export_name — Specifies the exported symbol name for a function or static.
    • link_section — Specifies the section of an object file to use for a function or static.
    • no_mangle — Disables symbol name encoding.
    • used — Forces the compiler to keep a static item in the output object file.
    • crate_name — Specifies the crate name.
  • Code generation
    • inline — Hint to inline code.
    • cold — Hint that a function is unlikely to be called.
    • no_builtins — Disables use of certain built-in functions.
    • target_feature — Configure platform-specific code generation.
    • track_caller - Pass the parent call location to std::panic::Location::caller().
  • Documentation
  • Preludes
  • Modules
    • path — Specifies the filename for a module.
  • Limits
  • Runtime
  • Features
    • feature — Used to enable unstable or experimental compiler features. See The Unstable Book for features implemented in rustc.
  • Type System
    • non_exhaustive — Indicate that a type will have more fields/variants added in future.

© 2010 The Rust Project Developers
Licensed under the Apache License, Version 2.0 or the MIT license, at your option.