Phát hành Rust 1.96.0
(blog.rust-lang.org)- Rust 1.96.0 có thể được cài bằng
rustup update stable, và việc kiểm chứng các bản phát hành sắp tới có thể tham gia qua kênh beta/nightly - Các kiểu
core::range::Range*mới triển khai IntoIterator thay vìIterator, nhờ đó có thể triển khaiCopy, và sẽ trở thành kiểu mặc định của cú pháp phạm vi trong tương lai - assert_matches! và
debug_assert_matches!sẽ in kèm biểu diễnDebugcủa giá trị khi không khớp mẫu, giúp chẩn đoán lỗi kiểm thử dễ hơn - Với mục tiêu WebAssembly,
--allow-undefinedkhông còn được truyền mặc định nữa, nên symbol chưa được định nghĩa sẽ trở thành lỗi linker thay vì import - Cargo bao gồm bản vá cho CVE-2026-5223 và
CVE-2026-5222dành cho người dùng registry bên thứ ba; người dùng crates.io không bị ảnh hưởng
Những thay đổi chính trong Rust 1.96.0
-
Cập nhật và kênh kiểm thử
- Người dùng đã cài Rust bằng
rustupcó thể nhận Rust 1.96.0 bằngrustup update stable - Nếu chưa có
rustup, có thể cài từ trang cài đặtrustuptrên website Rust, vàghi chú phát hành chi tiết của 1.96.0cũng đã được công bố - Nếu muốn tham gia kiểm chứng các bản phát hành trong tương lai, có thể dùng kênh beta/nightly bằng
rustup default betahoặcrustup default nightly, và có thể báo lỗi tại Rust issue tracker
- Người dùng đã cài Rust bằng
-
Các kiểu
Range*mới- Kiểu
Rangehiện tại và các kiểu liên quan trongcore::opslà thứ nhiều người dùng kỳ vọng cóCopy, nhưng vì chúng trực tiếp triển khaiIteratornên không triển khai thêmCopy - Cách triển khai đồng thời
IteratorvàCopycho cùng một kiểu là một footgun mà Clippy cảnh báo, nên trước đây đã tránh cách này - RFC3550 đề xuất các kiểu phạm vi thay thế triển khai
IntoIteratorthay vìIterator, và với cấu trúc này các kiểu đó cũng có thể triển khaiCopy - Thư viện chuẩn đã ổn định hóa
core::range::Range,core::range::RangeFrom,core::range::RangeInclusivevà các iterator liên quan - Trong một phiên bản Rust sắp tới gần đây sẽ bổ sung
core::range::RangeFull,core::range::RangeTođược tái xuất từcore::ops, cùngcore::range::legacy::*, nơi mới của các kiểu phạm vi hiện tại - Cú pháp phạm vi như
0..1hiện tạo ra các kiểu legacy, nhưng trong một edition tương lai sẽ chuyển sang các kiểucore::range - Việc ổn định hóa mới này cho phép lưu bộ truy cập slice trong kiểu
Copymà không cần táchstartvàend - Ví dụ:
use core::range::Range; #[derive(Clone, Copy)] pub struct Span(Range<usize>); impl Span { pub fn of(self, s: &str) -> &str { &s[self.0] } } RangeInclusivemới công khai các trường, vì không cần tránh việc lộ trạng thái iterator đã cạn như ở phiên bản legacy- Các kiểu mới phải được chuyển đổi trước khi bắt đầu lặp, nên việc công khai trường không thành vấn đề
- Tác giả thư viện nên cân nhắc dùng
impl RangeBoundstrong API công khai để chấp nhận cả kiểu phạm vi legacy lẫn kiểu mới - Nếu cần kiểu cụ thể, khuyến nghị ưu tiên kiểu phạm vi mới, vốn sẽ trở thành mặc định trong tương lai
- Kiểu
-
Macro khẳng định khớp mẫu
- Hai macro mới
assert_matches!vàdebug_assert_matches!kiểm tra xem một giá trị có khớp với mẫu cho trước hay không, và nếu không sẽ panic kèm biểu diễnDebugcủa giá trị đó - Về bản chất, hai macro này tương đương
assert!(matches!(..))vàdebug_assert!(matches!(..)), nhưng giá trị được in ra khi thất bại giúp cải thiện khả năng chẩn đoán - Do có thể xung đột với các crate bên thứ ba phổ biến cũng cung cấp macro cùng tên, chúng không được thêm vào standard prelude
- Trước khi dùng, cần import trực tiếp từ
corehoặcstd - Ví dụ:
use core::assert_matches; /// [Random Number](https://xkcd.com/221/) fn get_random_number() -> u32 { // chosen by a fair dice roll. // guaranteed to be random. 4 } fn main() { assert_matches!(get_random_number(), 1..=6); }
- Hai macro mới
-
Thay đổi với mục tiêu WebAssembly
- Các mục tiêu WebAssembly không còn truyền
--allow-undefinedcho linker nữa - Khi liên kết, symbol chưa được định nghĩa sẽ không còn được chuyển thành WebAssembly import của module
"env", mà sẽ trở thành lỗi linker - Nếu toàn bộ symbol liên quan đến liên kết đều không được định nghĩa thì module sẽ không liên kết được, nhờ đó có thể phát hiện bug sớm hơn và ngăn các vấn đề vô tình phát sinh từ tên symbol
- Các symbol liên quan đến liên kết nhưng chưa được định nghĩa thường cho thấy bug trong thời gian build hoặc lỗi cấu hình
- Nếu hành vi cũ là chủ đích, có thể quay lại bằng
RUSTFLAGS=-Clink-arg=--allow-undefined, hoặc dùng#[link(wasm_import_module = "env")]trong khối định nghĩa symbol ở mã nguồn - Thay đổi này được áp dụng trong Rust 1.96 sau thông báo trên blog trước đó
- Các mục tiêu WebAssembly không còn truyền
API được ổn định hóa và bản vá bảo mật
-
API được ổn định hóa
-
2 cảnh báo bảo mật của Cargo
- Rust 1.96 bao gồm bản vá cho 2 lỗ hổng Cargo dành cho người dùng registry bên thứ ba
- CVE-2026-5223 là lỗ hổng mức độ trung bình liên quan đến việc giải nén tarball crate có symbolic link
- CVE-2026-5222 là lỗ hổng mức độ thấp liên quan đến xác thực thông qua URL đã được chuẩn hóa
- Người dùng crates.io không bị ảnh hưởng bởi cả hai lỗ hổng này
-
Các thay đổi bổ sung
1 bình luận
Ý kiến trên Lobste.rs
Tôi cứ thấy mình muốn có
assert_matches, nhưng mỗi lần lại phải cân nhắc giữa việc thêm một crate mới hay tự triển khai lạiVì vậy việc nó được đưa vào thư viện chuẩn là điều đáng mừng
Tôi thích bước tiến hướng tới việc biến phạm vi thành kiểu
CopyThỉnh thoảng tôi lại ngạc nhiên vì phải clone một phạm vi, và điều này cũng hợp hơn với trực giác rằng
12..34nên là dữ liệu nhỏ và có thể sao chép đượcTuy vậy, nếu xuất hiện nhiều kiểu cùng tên thì tôi hơi lo VS Code lần tới khi tự thêm khai báo
usesẽ lấy nhầm kiểuVới đa số người dùng, lợi ích của kiểu mới là nhỏ nên cứ tiếp tục dùng kiểu cũ là được, rồi đến ranh giới edition tiếp theo thì kiểu mới sẽ tự động được dùng
Có lẽ chủ yếu là các tác giả thư viện muốn hỗ trợ rõ ràng cả hai phiên bản mới phải import các kiểu này
Có thể thay đổi prelude mà không làm hỏng các dự án hiện có