1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-05-28 21:27:37 +02:00

Update to Rust 2024 edition. (#2658)

This commit is contained in:
Andrew Walbran 2025-05-23 19:03:03 +01:00 committed by GitHub
parent db47709e87
commit fc6e5c7526
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
83 changed files with 150 additions and 149 deletions

View File

@ -25,7 +25,7 @@ else
# Back-date the sources to POT-Creation-Date. The content lives in two
# directories:
rm -r src/ third_party/
git restore --source "$(git rev-list -n 1 --before "$pot_creation_date" @)" src/ third_party/
git restore --source "$(git rev-list -n 1 --before "$pot_creation_date" @)" src/ third_party/ book.toml
# Set language and adjust site URL. Clear the redirects since they are
# in sync with the source files, not the translation.
export MDBOOK_BOOK__LANGUAGE=$book_lang

View File

@ -161,9 +161,11 @@ jobs:
MDBOOK_OUTPUT='{"xgettext": {"pot-file": "messages.pot"}}' mdbook build -d po
msgfmt -o /dev/null --statistics po/messages.pot
- name: Install mdbook-linkcheck
- name: Install mdbook-linkcheck2
if: contains(fromJSON(env.LINK_CHECKED_LANGUAGES), matrix.language)
run: cargo install mdbook-linkcheck --locked --version 0.7.7
run: |
cargo uninstall mdbook-linkcheck || true
cargo install mdbook-linkcheck2 --locked --version 0.9.1
- name: Build ${{ matrix.language }} translation
run: |
@ -210,6 +212,9 @@ jobs:
with:
fetch-depth: 0
- name: Update Rust
run: rustup update
- name: Setup Rust cache
uses: ./.github/workflows/setup-rust-cache

View File

@ -13,6 +13,6 @@ runs:
run: |
sudo apt-get update
sudo apt-get install -y texlive texlive-luatex texlive-lang-cjk texlive-lang-arabic librsvg2-bin fonts-noto
curl -LsSf https://github.com/jgm/pandoc/releases/download/3.6.2/pandoc-3.6.2-linux-amd64.tar.gz | tar zxf -
echo "$PWD/pandoc-3.6.2/bin" >> $GITHUB_PATH
curl -LsSf https://github.com/jgm/pandoc/releases/download/3.7.0.1/pandoc-3.7.0.1-linux-amd64.tar.gz | tar zxf -
echo "$PWD/pandoc-3.7.0.1/bin" >> $GITHUB_PATH
shell: bash

View File

@ -35,6 +35,9 @@ jobs:
with:
fetch-depth: 0 # We need the full history for build.sh below.
- name: Update Rust
run: rustup update
- name: Setup Rust cache
uses: ./.github/workflows/setup-rust-cache

View File

@ -55,7 +55,7 @@ The course is built using a few tools:
- [mdbook-i18n-helpers and i18n-report](https://github.com/google/mdbook-i18n-helpers)
- [mdbook-exerciser](mdbook-exerciser/)
- [mdbook-course](mdbook-course/)
- [mdbook-linkcheck](https://github.com/Michael-F-Bryan/mdbook-linkcheck)
- [mdbook-linkcheck2](https://github.com/marxin/mdbook-linkcheck2)
First install Rust by following the instructions on https://rustup.rs/. Then
clone this repository:

View File

@ -5,7 +5,7 @@ src = "src"
title = "Comprehensive Rust 🦀"
[rust]
edition = "2021"
edition = "2024"
[build]
extra-watch-dirs = ["po", "third_party"]
@ -299,3 +299,12 @@ exclude = [
"comprehensive-rust-exercises.zip",
# "crates.io", # uncomment when follow-web-links is true
]
[output.linkcheck2]
optional = true
follow-web-links = false # change to true to check web links
exclude = [
"comprehensive-rust.pdf",
"comprehensive-rust-exercises.zip",
# "crates.io", # uncomment when follow-web-links is true
]

View File

@ -9,7 +9,7 @@
"command": "yapf3",
"exts": ["py"]
}, {
"command": "rustup run stable rustfmt --edition 2021",
"command": "rustup run stable rustfmt --edition 2024",
"exts": ["rs"]
}]
},

View File

@ -2,7 +2,7 @@
name = "mdbook-course"
version = "0.1.0"
authors = ["Dustin Mitchell <djmitche@google.com>"]
edition = "2021"
edition = "2024"
license = "Apache-2.0"
publish = false
repository = "https://github.com/google/comprehensive-rust"

View File

@ -35,8 +35,8 @@
//! item becomes the first slide in that segment. Any other sub-items of the
//! top-level item are treated as further slides in the same segment.
use crate::frontmatter::{split_frontmatter, Frontmatter};
use crate::markdown::{duration, Table};
use crate::frontmatter::{Frontmatter, split_frontmatter};
use crate::markdown::{Table, duration};
use mdbook::book::{Book, BookItem, Chapter};
use std::fmt::Write;
use std::path::PathBuf;
@ -318,7 +318,9 @@ impl Session {
}
format!(
"Including {BREAK_DURATION} minute breaks, this session should take about {}. It contains:\n\n{}",
duration(self.minutes()), segments)
duration(self.minutes()),
segments
)
}
/// Return the total duration of this session.
@ -337,11 +339,7 @@ impl Session {
///
/// This includes breaks between segments.
pub fn target_minutes(&self) -> u64 {
if self.target_minutes > 0 {
self.target_minutes
} else {
self.minutes()
}
if self.target_minutes > 0 { self.target_minutes } else { self.minutes() }
}
}

View File

@ -2,7 +2,7 @@
name = "mdbook-exerciser"
version = "0.1.0"
authors = ["Andrew Walbran <qwandor@google.com>"]
edition = "2021"
edition = "2024"
license = "Apache-2.0"
repository = "https://github.com/google/comprehensive-rust"
description = "A tool for extracting starter code for exercises from Markdown files."

View File

@ -14,7 +14,7 @@
use log::{info, trace};
use pulldown_cmark::{Event, Parser, Tag, TagEnd};
use std::fs::{create_dir_all, File};
use std::fs::{File, create_dir_all};
use std::io::Write;
use std::path::Path;

View File

@ -14,9 +14,9 @@
use anyhow::Context;
use log::trace;
use mdbook::BookItem;
use mdbook::book::Book;
use mdbook::renderer::RenderContext;
use mdbook::BookItem;
use mdbook_exerciser::process;
use std::fs::{create_dir, remove_dir_all};
use std::io::stdin;

View File

@ -15,9 +15,9 @@
// ANCHOR: hello
//! Rust <-> Java FFI demo.
use jni::JNIEnv;
use jni::objects::{JClass, JString};
use jni::sys::jstring;
use jni::JNIEnv;
/// HelloWorld::hello method implementation.
// SAFETY: There is no other global function of this name.

View File

@ -1,7 +1,7 @@
[package]
name = "android-testing"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[example]]

View File

@ -3,7 +3,7 @@
[package]
name = "alloc-example"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]

View File

@ -26,13 +26,14 @@ use buddy_system_allocator::LockedHeap;
#[global_allocator]
static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();
static mut HEAP: [u8; 65536] = [0; 65536];
const HEAP_SIZE: usize = 65536;
static mut HEAP: [u8; HEAP_SIZE] = [0; HEAP_SIZE];
pub fn entry() {
// SAFETY: `HEAP` is only used here and `entry` is only called once.
unsafe {
// Give the allocator some memory to allocate.
HEAP_ALLOCATOR.lock().init(HEAP.as_mut_ptr() as usize, HEAP.len());
HEAP_ALLOCATOR.lock().init(&raw mut HEAP as usize, HEAP_SIZE);
}
// Now we can do things that require heap allocation.

View File

@ -3,7 +3,7 @@
[package]
name = "ap-examples"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]

View File

@ -14,8 +14,8 @@
// ANCHOR: exceptions
use log::error;
use smccc::psci::system_off;
use smccc::Hvc;
use smccc::psci::system_off;
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]

View File

@ -23,8 +23,8 @@ use crate::pl011::Uart;
use core::fmt::Write;
use core::panic::PanicInfo;
use log::error;
use smccc::psci::system_off;
use smccc::Hvc;
use smccc::psci::system_off;
/// Base address of the primary PL011 UART.
const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;

View File

@ -22,9 +22,9 @@ mod pl011;
use crate::pl011::Uart;
use core::panic::PanicInfo;
use log::{error, info, LevelFilter};
use smccc::psci::system_off;
use log::{LevelFilter, error, info};
use smccc::Hvc;
use smccc::psci::system_off;
/// Base address of the primary PL011 UART.
const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;

View File

@ -24,8 +24,8 @@ use crate::pl011_minimal::Uart;
use core::fmt::Write;
use core::panic::PanicInfo;
use log::error;
use smccc::psci::system_off;
use smccc::Hvc;
use smccc::psci::system_off;
/// Base address of the primary PL011 UART.
const PL011_BASE_ADDRESS: *mut u8 = 0x900_0000 as _;

View File

@ -19,14 +19,14 @@
mod exceptions;
use aarch64_paging::paging::Attributes;
use aarch64_rt::{entry, initial_pagetable, InitialPagetable};
use aarch64_rt::{InitialPagetable, entry, initial_pagetable};
use arm_pl011_uart::{PL011Registers, Uart, UniqueMmioPointer};
use core::fmt::Write;
use core::panic::PanicInfo;
use core::ptr::NonNull;
use log::error;
use smccc::psci::system_off;
use smccc::Hvc;
use smccc::psci::system_off;
/// Base address of the primary PL011 UART.
const PL011_BASE_ADDRESS: NonNull<PL011Registers> =

View File

@ -3,7 +3,7 @@
[package]
name = "microcontroller-examples"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]

View File

@ -20,7 +20,7 @@ extern crate panic_halt as _;
use cortex_m_rt::entry;
use embedded_hal::digital::OutputPin;
use nrf52833_hal::gpio::{p0, Level};
use nrf52833_hal::gpio::{Level, p0};
use nrf52833_hal::pac::Peripherals;
#[entry]

View File

@ -1,7 +1,7 @@
[package]
name = "allocator-example"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]

View File

@ -8,7 +8,7 @@ many elements are used and panics if you try to use more than are allocated.
<!-- mdbook-xgettext: skip -->
```rust,editable,compile_fail
use tinyvec::{array_vec, ArrayVec};
use tinyvec::{ArrayVec, array_vec};
fn main() {
let mut numbers: ArrayVec<[u32; 5]> = array_vec!(42, 66);

View File

@ -1,7 +1,7 @@
[package]
name = "zerocopy-example"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]

View File

@ -1,7 +1,7 @@
[package]
name = "borrowing"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[lib]

View File

@ -82,5 +82,5 @@ fn main() {
</details>
[1]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8f5896878611566845fe3b0f4dc5af68
[2]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f293a31f2d4d0d31770486247c2e8437
[1]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=8f5896878611566845fe3b0f4dc5af68
[2]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f293a31f2d4d0d31770486247c2e8437

View File

@ -72,4 +72,4 @@ Notes on stack returns and inlining:
</details>
[Playground]: https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=0cb13be1c05d7e3446686ad9947c4671
[Playground]: https://play.rust-lang.org/?version=stable&mode=release&edition=2024&gist=0cb13be1c05d7e3446686ad9947c4671

View File

@ -32,8 +32,8 @@ Key points:
- Dependencies can also be resolved from alternative [registries], git, folders,
and more.
- Rust also has [editions]: the current edition is Rust 2021. Previous editions
were Rust 2015 and Rust 2018.
- Rust also has [editions]: the current edition is Rust 2024. Previous editions
were Rust 2015, Rust 2018 and Rust 2021.
- The editions are allowed to make backwards incompatible changes to the
language.

View File

@ -10,11 +10,7 @@ A closure can capture variables from the environment where it was defined.
fn main() {
let max_value = 5;
let clamp = |v| {
if v > max_value {
max_value
} else {
v
}
if v > max_value { max_value } else { v }
};
dbg!(clamp(1));

View File

@ -17,7 +17,7 @@ the resulting variables. The `statement` result becomes the result of the
```rust,editable,compile_fail
use tokio::sync::mpsc;
use tokio::time::{sleep, Duration};
use tokio::time::{Duration, sleep};
#[tokio::main]
async fn main() {

View File

@ -1,7 +1,7 @@
[package]
name = "chat-async"
version = "0.1.0"
edition = "2021"
edition = "2024"
[dependencies]
futures-util = { version = "0.3.31", features = ["sink"] }

View File

@ -14,8 +14,8 @@
// ANCHOR: solution
// ANCHOR: setup
use futures_util::stream::StreamExt;
use futures_util::SinkExt;
use futures_util::stream::StreamExt;
use http::Uri;
use tokio::io::{AsyncBufReadExt, BufReader};
use tokio_websockets::{ClientBuilder, Message};

View File

@ -19,7 +19,7 @@ use futures_util::stream::StreamExt;
use std::error::Error;
use std::net::SocketAddr;
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::broadcast::{channel, Sender};
use tokio::sync::broadcast::{Sender, channel};
use tokio_websockets::{Message, ServerBuilder, WebSocketStream};
// ANCHOR_END: setup

View File

@ -45,7 +45,7 @@ can use the following `Cargo.toml`:
[package]
name = "dining-philosophers-async-dine"
version = "0.1.0"
edition = "2021"
edition = "2024"
[dependencies]
tokio = { version = "1.26.0", features = ["sync", "time", "macros", "rt-multi-thread"] }

View File

@ -15,7 +15,7 @@
// ANCHOR: solution
// ANCHOR: Philosopher
use std::sync::Arc;
use tokio::sync::{mpsc, Mutex};
use tokio::sync::{Mutex, mpsc};
use tokio::time;
struct Chopstick;

View File

@ -22,7 +22,7 @@ with some caveats:
```rust,editable,compile_fail
use async_trait::async_trait;
use std::time::Instant;
use tokio::time::{sleep, Duration};
use tokio::time::{Duration, sleep};
#[async_trait]
trait Sleeper {

View File

@ -20,7 +20,7 @@ location.
```rust,editable,compile_fail
use tokio::sync::{mpsc, oneshot};
use tokio::task::spawn;
use tokio::time::{sleep, Duration};
use tokio::time::{Duration, sleep};
// A work item. In this case, just sleep for the given time and respond
// with a message on the `respond_on` channel.

View File

@ -1,7 +1,7 @@
[package]
name = "sync-exercises"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[bin]]

View File

@ -51,7 +51,7 @@ You can use the following `Cargo.toml`:
[package]
name = "dining-philosophers"
version = "0.1.0"
edition = "2021"
edition = "2024"
```
<details>

View File

@ -14,7 +14,7 @@
// ANCHOR: solution
// ANCHOR: Philosopher
use std::sync::{mpsc, Arc, Mutex};
use std::sync::{Arc, Mutex, mpsc};
use std::thread;
use std::time::Duration;

View File

@ -34,7 +34,7 @@ The `cargo add` calls will update the `Cargo.toml` file to look like this:
[package]
name = "link-checker"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]

View File

@ -13,12 +13,12 @@
// limitations under the License.
// ANCHOR: solution
use std::sync::{mpsc, Arc, Mutex};
use std::sync::{Arc, Mutex, mpsc};
use std::thread;
// ANCHOR: setup
use reqwest::blocking::Client;
use reqwest::Url;
use reqwest::blocking::Client;
use scraper::{Html, Selector};
use thiserror::Error;

View File

@ -1,7 +1,7 @@
[package]
name = "control-flow-basics"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[bin]]

View File

@ -8,11 +8,7 @@ minutes: 3
```rust,editable
fn gcd(a: u32, b: u32) -> u32 {
if b > 0 {
gcd(b, a % b)
} else {
a
}
if b > 0 { gcd(b, a % b) } else { a }
}
fn main() {

View File

@ -1,7 +1,7 @@
[package]
name = "error-handling"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]

View File

@ -15,7 +15,7 @@ writing out trait impls explicitly for custom error types.
[`thiserror`]: https://docs.rs/thiserror/
```rust,editable,compile_fail
use anyhow::{bail, Context, Result};
use anyhow::{Context, Result, bail};
use std::fs;
use std::io::Read;
use thiserror::Error;

View File

@ -3,7 +3,7 @@
[package]
name = "compass"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]

View File

@ -26,12 +26,12 @@ use embedded_hal::digital::InputPin;
use lsm303agr::{
AccelMode, AccelOutputDataRate, Lsm303agr, MagMode, MagOutputDataRate,
};
use microbit::Board;
use microbit::display::blocking::Display;
use microbit::hal::twim::Twim;
use microbit::hal::uarte::{Baudrate, Parity, Uarte};
use microbit::hal::{Delay, Timer};
use microbit::pac::twim0::frequency::FREQUENCY_A;
use microbit::Board;
const COMPASS_SCALE: i32 = 30000;
const ACCELEROMETER_SCALE: i32 = 700;

View File

@ -3,7 +3,7 @@
[package]
name = "rtc"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]

View File

@ -14,8 +14,8 @@
use arm_gic::gicv3::GicV3;
use log::{error, info, trace};
use smccc::psci::system_off;
use smccc::Hvc;
use smccc::psci::system_off;
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]

View File

@ -23,20 +23,20 @@ mod logger;
mod pl031;
use crate::pl031::Rtc;
use arm_gic::{irq_enable, wfi, IntId, Trigger};
use arm_gic::{IntId, Trigger, irq_enable, wfi};
use chrono::{TimeZone, Utc};
use core::hint::spin_loop;
// ANCHOR: imports
use aarch64_paging::paging::Attributes;
use aarch64_rt::{entry, initial_pagetable, InitialPagetable};
use arm_gic::gicv3::registers::{Gicd, GicrSgi};
use aarch64_rt::{InitialPagetable, entry, initial_pagetable};
use arm_gic::gicv3::GicV3;
use arm_gic::gicv3::registers::{Gicd, GicrSgi};
use arm_pl011_uart::{PL011Registers, Uart, UniqueMmioPointer};
use core::panic::PanicInfo;
use core::ptr::NonNull;
use log::{error, info, trace, LevelFilter};
use smccc::psci::system_off;
use log::{LevelFilter, error, info, trace};
use smccc::Hvc;
use smccc::psci::system_off;
/// Base addresses of the GICv3.
const GICD_BASE_ADDRESS: *mut Gicd = 0x800_0000 as _;

View File

@ -1,7 +1,7 @@
[package]
name = "generics"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[lib]

View File

@ -9,11 +9,7 @@ Rust supports generics, which lets you abstract algorithms or data structures
```rust,editable
fn pick<T>(cond: bool, left: T, right: T) -> T {
if cond {
left
} else {
right
}
if cond { left } else { right }
}
fn main() {
@ -31,19 +27,11 @@ fn main() {
```rust
fn pick_i32(cond: bool, left: i32, right: i32) -> i32 {
if cond {
left
} else {
right
}
if cond { left } else { right }
}
fn pick_char(cond: bool, left: char, right: char) -> char {
if cond {
left
} else {
right
}
if cond { left } else { right }
}
```

View File

@ -1,7 +1,7 @@
[package]
name = "iterators"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[lib]

View File

@ -87,4 +87,4 @@ elements of `some_vector`.
</details>
[1]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=947e371c7295af758504f01f149023a1
[1]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=947e371c7295af758504f01f149023a1

View File

@ -1,11 +1,11 @@
[package]
name = "lifetimes"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]
thiserror = "*"
thiserror = "2.0.11"
[lib]
name = "protobuf"

View File

@ -29,11 +29,7 @@ job.
struct Point(i32, i32);
fn left_most(p1: &Point, p2: &Point) -> &Point {
if p1.0 < p2.0 {
p1
} else {
p2
}
if p1.0 < p2.0 { p1 } else { p2 }
}
fn main() {

View File

@ -1,7 +1,7 @@
[package]
name = "memory-management"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[bin]]

View File

@ -1,7 +1,7 @@
[package]
name = "methods-and-traits"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[bin]]

View File

@ -1,7 +1,7 @@
[package]
name = "modules"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[bin]]

View File

@ -75,4 +75,4 @@ fn main() {
</details>
[1]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3e61f43c88de12bcdf69c1d6df9ab3da
[1]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=3e61f43c88de12bcdf69c1d6df9ab3da

View File

@ -1,7 +1,7 @@
[package]
name = "pattern-matching"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[lib]

View File

@ -1,7 +1,7 @@
[package]
name = "references"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[bin]]

View File

@ -1,7 +1,7 @@
[package]
name = "smart-pointers"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[lib]

View File

@ -1,7 +1,7 @@
[package]
name = "std-traits"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[lib]

View File

@ -1,7 +1,7 @@
[package]
name = "std-types"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[bin]]

View File

@ -1,7 +1,7 @@
[package]
name = "testing"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[lints.rust]

View File

@ -44,4 +44,4 @@ pub fn shorten_string(s: &str, length: usize) -> &str {
- Adding `#` in the code will hide it from the docs, but will still compile/run
it.
- Test the above code on the
[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3ce2ad13ea1302f6572cb15cd96becf0).
[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=3ce2ad13ea1302f6572cb15cd96becf0).

View File

@ -1,7 +1,7 @@
[package]
name = "tuples-and-arrays"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[bin]]

View File

@ -40,8 +40,8 @@ fn main() {
// ANCHOR_END: main
// ANCHOR_END: solution
// This test does not appear in the exercise, as this is very early in the course, but it verifies
// that the solution is correct.
// This test does not appear in the exercise, as this is very early in the
// course, but it verifies that the solution is correct.
#[test]
fn test_transpose() {
let matrix = [

View File

@ -1,7 +1,7 @@
[package]
name = "types-and-values"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[bin]]

View File

@ -1,11 +1,11 @@
[package]
name = "unsafe-rust"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]
tempfile = "*"
tempfile = "3.17.1"
[[bin]]
name = "listdir"

View File

@ -22,6 +22,7 @@ static mut COUNTER: u32 = 0;
fn add_to_counter(inc: u32) {
// SAFETY: There are no other threads which could be accessing `COUNTER`.
#[allow(static_mut_refs)]
unsafe {
COUNTER += inc;
}
@ -31,6 +32,7 @@ fn main() {
add_to_counter(42);
// SAFETY: There are no other threads which could be accessing `COUNTER`.
#[allow(static_mut_refs)]
unsafe {
dbg!(COUNTER);
}
@ -40,12 +42,16 @@ fn main() {
<details>
- The program here is safe because it is single-threaded. However, the Rust
compiler is conservative and will assume the worst. Try removing the `unsafe`
and see how the compiler explains that it is undefined behavior to mutate a
static from multiple threads.
- Using a mutable static is generally a bad idea, but there are some cases where
it might make sense in low-level `no_std` code, such as implementing a heap
allocator or working with some C APIs.
compiler reasons about functions individually so can't assume that. Try
removing the `unsafe` and see how the compiler explains that it is undefined
behavior to access a mutable static from multiple threads.
- Rust 2024 edition goes further and makes accessing a mutable static by
reference an error by default. We work around this in the example with
`#[allow(static_mut_refs)]`. Don't do this.
- Using a mutable static is almost always a bad idea, you should use interior
mutability instead.
- There are some cases where it might be necessary in low-level `no_std` code,
such as implementing a heap allocator or working with some C APIs. In this
case you should use pointers rather than references.
</details>

View File

@ -11,9 +11,13 @@ preconditions to avoid undefined behaviour.
/// The pointers must be valid, properly aligned, and not otherwise accessed for
/// the duration of the function call.
unsafe fn swap(a: *mut u8, b: *mut u8) {
let temp = *a;
*a = *b;
*b = temp;
// SAFETY: Our caller promised that the pointers are valid, properly aligned
// and have no other access.
unsafe {
let temp = *a;
*a = *b;
*b = temp;
}
}
fn main() {
@ -35,9 +39,9 @@ fn main() {
We wouldn't actually use pointers for a `swap` function --- it can be done
safely with references.
Note that unsafe code is allowed within an unsafe function without an `unsafe`
block. We can prohibit this with `#[deny(unsafe_op_in_unsafe_fn)]`. Try adding
it and see what happens. This will
[change in the 2024 Rust edition](https://github.com/rust-lang/rust/issues/120535).
Note that Rust 2021 and earlier allow unsafe code within an unsafe function
without an `unsafe` block. This changed in the 2024 edition. We can prohibit it
in older editions with `#[deny(unsafe_op_in_unsafe_fn)]`. Try adding it and see
what happens.
</details>

View File

@ -1,7 +1,7 @@
[package]
name = "user-defined-types"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[[bin]]

View File

@ -14,11 +14,7 @@ const DIGEST_SIZE: usize = 3;
const FILL_VALUE: u8 = calculate_fill_value();
const fn calculate_fill_value() -> u8 {
if DIGEST_SIZE < 10 {
42
} else {
13
}
if DIGEST_SIZE < 10 { 42 } else { 13 }
}
fn compute_digest(text: &str) -> [u8; DIGEST_SIZE] {

View File

@ -137,6 +137,8 @@ function playground_text(playground, hidden = true) {
edition = "2018";
} else if(classes.contains("edition2021")) {
edition = "2021";
} else if(classes.contains("edition2024")) {
edition = "2024";
}
var params = {
backtrace: true,

View File

@ -1,6 +1,7 @@
fn main() {
// Find target directory, either from CARGO_TARGET_DIR or in-tree if unset.
let mut src_dir = std::env::var_os("CARGO_TARGET_DIR").unwrap_or("../../../target".into());
let mut src_dir =
std::env::var_os("CARGO_TARGET_DIR").unwrap_or("../../../target".into());
src_dir.push("/cxxbridge/demo/src");
cxx_build::bridge("src/main.rs")

View File

@ -1,7 +1,7 @@
[package]
name = "xtask"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]

View File

@ -19,7 +19,7 @@
//! `cargo xtask install-tools` and the logic defined here will install
//! the tools.
use anyhow::{anyhow, Ok, Result};
use anyhow::{Ok, Result, anyhow};
use clap::{Parser, ValueEnum};
use std::path::Path;
use std::{env, process::Command};
@ -79,10 +79,10 @@ fn install_tools() -> Result<()> {
let install_args = vec![
// The --locked flag is important for reproducible builds. It also
// avoids breakage due to skews between mdbook and mdbook-svgbob.
vec!["mdbook", "--locked", "--version", "0.4.44"],
vec!["mdbook-svgbob", "--locked", "--version", "0.2.1"],
vec!["mdbook-pandoc", "--locked", "--version", "0.9.3"],
vec!["mdbook-i18n-helpers", "--locked", "--version", "0.3.5"],
vec!["mdbook", "--locked", "--version", "0.4.48"],
vec!["mdbook-svgbob", "--locked", "--version", "0.2.2"],
vec!["mdbook-pandoc", "--locked", "--version", "0.10.4"],
vec!["mdbook-i18n-helpers", "--locked", "--version", "0.3.6"],
vec!["i18n-report", "--locked", "--version", "0.2.0"],
// Mdbook-exerciser and mdbook-course are located in this repository.
// To make it possible to install them from any directory we need to