How does Rust prevent data races at compile time

Rust prevents data races at compile time by enforcing strict ownership and borrowing rules that disallow simultaneous mutable access to shared data.

Rust prevents data races at compile time through its Ownership system, specifically the Borrow Checker and the Send and Sync traits. The compiler enforces rules that ensure data is either owned by a single thread or shared via immutable references, rejecting code that allows simultaneous mutable access from multiple threads.

use std::thread;

fn main() {
    let data = String::from("hello");
    // This code fails to compile because `data` is moved to the thread
    // and cannot be accessed mutably in the main thread simultaneously.
    let handle = thread::spawn(|| {
        println!("{}", data); 
    });
    handle.join().unwrap();
}