Rust 2024 Edition

Changes to gen as a Reserved Keyword

In the Rust 2024 edition, gen is reserved as a strict language keyword to prepare for generator blocks (gen { yield x; } and gen fn) that ergonomically produce Iterator and Stream implementations. Consequently, existing code that used gen as a variable, function, method, or module name must use the raw identifier syntax r#gen (or rename the identifier) when compiling under edition = "2024".

Rust 2021:   `let gen = 42;`         (Valid identifier)
Rust 2024:   `let gen = 42;`         (Compile Error: `gen` is a reserved keyword!)
             `let r#gen = 42;`       (Valid raw identifier matching `"gen"`)

Compile-Time Error When Using gen as an Identifier in Rust 2024

// ❌ does not compile
fn gen(seed: u64) -> u64 {
    seed.wrapping_mul(6364136223846793005).wrapping_add(1)
}

fn main() {
    let val = gen(1);
    println!("{val}");
}
error: `gen` is a keyword in the 2024 edition
 --> src/main.rs:2:4
  |
2 | fn gen(seed: u64) -> u64 {
  |    ^^^ help: you can use a raw identifier to stay compatible: `r#gen`
  |
  = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!

Interoperating with Pre-2024 Crates Using Raw Identifiers (r#gen)

What if your Rust 2024 crate depends on a Rust 2021 library crate (such as an older version of rand or a custom crate) that exposes a public method named .gen()?

Because r#gen is stripped to the exact identifier gen after lexing, calling rng.r#gen() in a Rust 2024 crate calls the .gen() method defined in a Rust 2021 crate seamlessly! (Note that rand v0.9+ also renamed .gen() to .random() so modern callers don't even need r#gen.)

pub struct LinearCongruentialRng {
    state: u64,
}

impl LinearCongruentialRng {
    pub const fn new(seed: u64) -> Self {
        Self { state: seed }
    }

    /// Using raw identifier `r#gen` keeps backward compatibility with callers
    /// expecting a method named `gen`, while `next_u64` provides a clean modern name!
    pub fn r#gen(&mut self) -> u64 {
        self.state = self
            .state
            .wrapping_mul(6364136223846793005)
            .wrapping_add(1442695040888963407);
        self.state
    }
}

fn main() {
    let mut rng = LinearCongruentialRng::new(42);
    let sample = rng.r#gen();
    println!("Generated pseudorandom u64 via r#gen(): {sample}");
}
Generated pseudorandom u64 via r#gen(): 1442695043559898017

Automated Rewriting via cargo fix --edition

When you run cargo fix --edition before switching Cargo.toml to edition = "2024", the compiler's keyword_idents_2024 lint automatically rewrites every identifier occurrence of gen in your crate to r#gen.