Attributes and Conditional Compilation

#[deprecated]

#[deprecated] marks a public or internal item (function, method, struct, enum, variant, field, trait, constant, type alias, or module) as superseded, causing the compiler to emit a deprecated warning diagnostic whenever caller code references the item and adding a prominent deprecation banner in generated rustdoc HTML documentation.

Syntactic Forms of #[deprecated]

// 1. Bare attribute:
#[deprecated]

// 2. Shorthand message string:
#[deprecated = "use `connect_with_timeout` instead"]

// 3. Structured `since` version + `note` migration guide (Recommended):
#[deprecated(since = "1.4.0", note = "use `Client::builder()` instead")]
Field Purpose Best Practice
since = "X.Y.Z" Records the exact crate version in which the item was deprecated (or "TBD" if slated for next release) Allows callers to plan upgrades across semver versions
note = "..." Explains why the item was deprecated and names the exact replacement function or type Include backticks around the replacement path (use \new_fn` instead`)

Deprecating Legacy APIs While Calling Them Internally Without Warnings

Inside the implementation of a deprecated function (or inside backwards-compatibility unit tests that verify the deprecated function still works), place #[allow(deprecated)] on the test or forwarding block so your own crate compiles with zero warnings while external callers still see the deprecation warning:

pub struct Connection {
    pub endpoint: String,
}

impl Connection {
    #[deprecated(
        since = "0.2.0",
        note = "use `Connection::connect(url)` instead; `open` will be removed in 1.0"
    )]
    pub fn open(url: &str) -> Self {
        Self::connect(url)
    }

    pub fn connect(url: &str) -> Self {
        Self {
            endpoint: url.to_string(),
        }
    }
}

#[allow(deprecated, reason = "Testing backwards-compatible deprecated wrapper")]
fn verify_legacy_open() -> Connection {
    Connection::open("https://api.example.com")
}

fn main() {
    let modern = Connection::connect("https://modern.example.com");
    let legacy = verify_legacy_open();

    println!("modern: {}, legacy: {}", modern.endpoint, legacy.endpoint);
}
modern: https://modern.example.com, legacy: https://api.example.com

When a caller without #[allow(deprecated)] calls Connection::open(...), the compiler prints:

warning: use of deprecated associated function `Connection::open`: use `Connection::connect(url)` instead; `open` will be removed in 1.0
  --> src/main.rs:28:18
   |
28 |     let legacy = Connection::open("https://api.example.com");
   |                  ^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(deprecated)]` on by default