What are Attributes in Rust?
In Rust, attributes are declarative tags placed above function definitions, modules, items, etc. They provide additional information or alter the behaviour of the code. Attributes in Rust start with a hashtag (#) and are placed inside square brackets ([]). For instance, an attribute could look like this: #[attribute].
Attributes are divided into three main categories: conditional compilation, crate-level attributes, and function and module-level attributes.
Conditional Compilation
Conditional compilation is controlled through attributes, allowing parts of the code to be compiled conditionally. Rust supports this through two key attributes:
- cfg: This attribute includes code based on a flag passed to the compiler. It can be used where an item is defined, such as functions, implementations, structs, etc.
#[cfg(target_os = "linux")]
fn are_you_on_linux() {
println!("You're running linux!");
}
2. cfg_attr: This attribute allows you to include other attributes based on a configuration flag conditionally.
#[cfg_attr(feature = "debug-mode", derive(Debug))]
struct Test {
value: i32,
}
In the above code, the Debug trait is derived for the struct Test only when the debug-mode feature is enabled.
Crate-level Attributes
Crate-level attributes apply to the entire crate. They are usually placed at the top of the main file (lib.rs or main.rs). Some commonly used crate-level attributes are:
- crate_name: This attribute lets you set the name of the crate manually.
#![crate_name = "my_crate"]
2. crate_type: This attribute lets you define the type of crate (library, binary, etc.).
#![crate_type = "lib"]
3. deny, warn, allow, forbid: These attributes are used for handling warnings or lint checks at the crate level.
#![deny(missing_docs)]
4. macro_use: This attribute allows macros to be used from external crates.
#[macro_use]
extern crate log;
Function and Module-level Attributes
These attributes apply to functions, modules, structs, enums, traits, etc. Here are some common ones:
- test: This attribute marks a function as a unit test.
#[test]
fn test_addition() {
assert_eq!(2 + 2, 4);
}
2. derive: This attribute automatically creates implementations of traits for user-defined types.
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
3. inline: This attribute suggests to the compiler that it should place a copy of the function's code inline to its caller, thus potentially improving runtime performance.


