Attributes
Attributes |
Lint attributes |
Automatically derive common traits |
Mark as must use |
Mark as deprecated |
Compile conditionally |
[attributes.incl: fix (P1)](https://github.com/john-cd/rust_howto/issues/537)
Attributes
Attributes can take arguments with different syntaxes:
#[attribute = "value"]
#[attribute(key = "value")]
#[attribute(value)]
#[attribute(value, value2)]
Inner attributes #![attr]
apply to the item that the attribute is declared within.
Lint attributes
During early development, place the following attributes at the top of main.rs
or lib.rs
#![allow(unused_variables)] #![allow(unused_mut)] #![allow(unused_imports)] #![allow(unused_must_use)] // or simply: #![allow(unused)] #![allow(dead_code)] #![allow(missing_docs)] // This import is not used anywhere use std::thread; // This struct is public but is not documented pub struct S; #[must_use] fn required() -> u32 { 42 } // Nothing calls this function fn dead_code() {} fn main() { // This variable is not used let x = 1; // This mutable variable is not used let mut m = 2; // The return value of this function is not used required(); println!("Done!"); }
For production-ready code, replace the above by the following, for example.
//! Crate documentation goes here. #![warn(unused, missing_debug_implementations, missing_docs, rust_2018_idioms)] // You may also add `missing_copy_implementations` if desirable. // It detects potentially-forgotten implementations of Copy for public types. // `deny` creates an error in case of violation #![deny(unreachable_pub)] // Prohibit unsafe blocks / functions // `forbid` is the same as `deny`, but also forbids changing the lint level // afterwards #![forbid(unsafe_code)] // WARNING: fn dead_code() {} // ERROR: unsafe fn unsafe_func() {} // ERROR // fn unsafe_block() { // unsafe { // } // } /// This is the required documentation for S /// We had to derive Debug to avoid a warning #[derive(Debug)] pub(crate) struct S; /// Here is the required documentation /// for the main function. fn main() { let s = S; println!("{:?}", s); }
You also apply these attributes to specific functions:
// Disables the `dead_code` lint #[allow(dead_code)] fn unused_function() {} fn main() { println!("Nobody is calling `unused_function`."); }
List of lint checks: rustc -W help
. rustc
⮳ also recognizes the tool lints for "clippy" and "rustdoc" e.g. #![warn(clippy::pedantic)]
Automatically derive common traits
See Automatic derivation.
Mark as must use
// Must use the results of the fn // Also applies to traits, structs, enums... #[must_use] fn add(a: i32, b: i32) -> i32 { a + b } fn main() { println!("{}", add(1, 2)); }
Mark as deprecated
#![allow(deprecated)] // Mark a function as deprecated // That also works for structs, enums, etc... #[deprecated(since = "5.2.0", note = "Use bar instead")] pub fn foo() { println!("foo"); } fn main() { // Use of a deprecated item foo(); // Normally we would get a warning. // In this case, we used the module-wide #![allow(deprecated)] attribute // (first line above) to suppress it. }
Compile conditionally
// This function only gets compiled if the target OS is linux #[cfg(target_os = "linux")] fn are_you_on_linux() { println!("You are running Linux!"); } // And this function only gets compiled if the target OS is *not* // linux #[cfg(not(target_os = "linux"))] fn are_you_on_linux() { println!("You are *not* running Linux!"); } fn main() { are_you_on_linux(); println!("Are you sure?"); if cfg!(target_os = "linux") { // alternative: use cfg! println!("Yes. It's definitely Linux!"); } else { println!("Yes. It's definitely *not* Linux!"); } }