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.