Rust 2024 Edition

Edition-Specific Best Practices

Writing idiomatic Rust 2024 edition code takes advantage of the edition's cleaner lifetime defaults, stricter unsafe boundaries, unified Cargo resolver, and modern standard library additions to eliminate legacy boilerplate.

Rust 2024 Idiomatic Checklist:
  1. Manifest:     `edition = "2024"` + `rust-version = "1.85"` (activates MSRV Resolver v3)
  2. Prelude:      Use `Future` and `IntoFuture` directly without `use std::future::...`
  3. Lifetimes:    Let `-> impl Trait` capture lifetimes automatically; use `+ use<...>` to restrict
  4. Strings/FFI:  Use `c"literal"` for static `CStr`s, `unsafe extern "C"`, & `#[unsafe(no_mangle)]`
  5. Unsafe Code:  Keep `unsafe_op_in_unsafe_fn = "deny"` and replace `static mut` with Atomics/Locks
  6. Control Flow: Flatten nested conditionals with `if let ... && ...` let-chains and `let ... else`
  7. Lints:        Use `#[expect(lint, reason = "...")]` instead of `#[allow(lint)]`

Comparing Legacy Idioms vs Rust 2024 Best Practices

Task Pre-2024 Workaround / Legacy Style Idiomatic Rust 2024 Best Practice
Static C-String Literal CStr::from_bytes_with_nul(b"hi\0").unwrap() c"hi" (&'static CStr validated at compile time)
Returning Borrowed impl Iterator -> impl Iterator<Item = T> + '_ -> impl Iterator<Item = T> (captures in-scope lifetimes automatically)
Excluding a Lifetime from impl Trait Custom Captures trait trick -> impl Trait + use<'kept, T>
Consuming a Box<[T]> by Value Vec::from(boxed_slice).into_iter() boxed_slice.into_iter() (yields owned T directly in 2024!)
Suppressing a Local Warning #[allow(dead_code)] #[expect(dead_code, reason = "...")] (warns when obsolete!)
Raw Pointer to Packed / Static Field std::ptr::addr_of!(s.field) &raw const s.field / &raw mut s.field
Inline Compile-Time Assertion / Table Separate const TMP: ... = ...; item const { assert!(N > 0); N * 2 } inline const block

Complete Showcase of Idiomatic Rust 2024 Code

#![deny(unsafe_op_in_unsafe_fn)]

use core::ffi::CStr;

/// Uses Rust 2024 inline `const { ... }` block to enforce compile-time capacity invariants!
pub struct FixedPacket<const CAP: usize> {
    buf: [u8; CAP],
    len: usize,
}

impl<const CAP: usize> FixedPacket<CAP> {
    pub const fn new() -> Self {
        // Inline `const` block evaluated at monomorphization / compile time:
        const {
            assert!(CAP > 0 && CAP <= 4096, "CAP must be in 1..=4096");
        }
        Self {
            buf: [0u8; CAP],
            len: 0,
        }
    }
}

/// Uses Rust 2024 `Future` directly from the prelude, `c"..."` literal,
/// `Box<[T]>::into_iter()` by value, and `-> impl Iterator` automatic lifetime capture!
pub fn filter_valid_tags<'a>(
    tags: Box<[&'a str]>,
    required_prefix: &str,
) -> impl Iterator<Item = &'a str> {
    let default_c_tag: &'static CStr = c"default_tag";
    assert_eq!(default_c_tag.to_bytes(), b"default_tag");

    // In Rust 2024:
    // 1. `tags.into_iter()` yields `&'a str` by value directly from `Box<[&'a str]>`!
    // 2. `-> impl Iterator` captures both `'a` and `required_prefix`'s lifetime automatically!
    tags.into_iter()
        .filter(move |t| t.starts_with(required_prefix))
}

fn main() {
    let _pkt = FixedPacket::<256>::new();

    let boxed_tags: Box<[&str]> = Box::new(["v1:auth", "v2:metrics", "v1:storage"]);
    let prefix = String::from("v1:");

    let matching: Vec<&str> = filter_valid_tags(boxed_tags, &prefix).collect();
    assert_eq!(matching, vec!["v1:auth", "v1:storage"]);

    // Native `&raw const` pointer creation syntax (replaces `ptr::addr_of!`):
    let x = 42u32;
    let raw_ptr: *const u32 = &raw const x;
    assert!(raw_ptr.is_aligned());

    println!("Rust 2024 showcase matched tags: {matching:?}");
}
Rust 2024 showcase matched tags: ["v1:auth", "v1:storage"]