Rust 1.100 chính thức ổn định kiểu never type sau 10 năm
Rust 1.100.0 đánh dấu cột mốc quan trọng khi kiểu never (!) chính thức được ổn định sau 10 năm và 5 lần thất bại. Bản phát hành này còn ổn định phần lõi của allocator_api, thêm DropGuard, conjure_zst, cùng nhiều cải tiến cho Cargo như phát hiện dependency thừa và cơ chế cooldown chống tấn công chuỗi cung ứng.

Nhóm phát triển Rust vừa công bố phiên bản Rust 1.100.0, đánh dấu một cột mốc đáng chú ý: kiểu never type (kiểu không bao giờ có giá trị, ký hiệu !) chính thức được ổn định sau 10 năm và 5 lần thất bại trong việc ổn định hóa. Đây cũng là bản phát hành hoàn thành mục tiêu dự án (project goal) cho hạng mục công việc này.
Người dùng đã cài Rust qua rustup có thể nâng cấp lên 1.100.0 bằng lệnh cập nhật thông thường.
Kiểu never type đã ổn định
Kiểu never, viết là ! trong mã nguồn, là kiểu không có giá trị hợp lệ (uninhabited type) chính thống. Nó đại diện cho kiểu của các phép tính phân kỳ (diverging computations) — những phép tính không bao giờ trả về giá trị nào, khiến mọi đoạn mã phía sau trở nên không thể chạm tới. Các biểu thức kết thúc luồng điều khiển như return, break hay std::process::exit cũng có kiểu !.
Vì không thể tồn tại một giá trị thuộc kiểu never, Rust cho phép ép kiểu never-to-any (never-to-any coercion), tức chuyển ! thành bất kỳ kiểu nào khác — đây chính là điểm khác biệt so với các kiểu uninhabited khác. Ứng dụng điển hình là không trả về giá trị từ một nhánh của match hoặc if.
Trước đây kiểu never đã có thể dùng và quan sát theo cách này, thậm chí đặt trong kiểu trả về của hàm (-> !), nhưng bản phát hành lần này cho phép đặt tên kiểu never ở bất kỳ vị trí nào.
Bản phát hành cũng thay đổi Infallible thành một alias của kiểu never. Nhờ đó, mọi API cũ dùng Infallible trở nên tương thích với !. Đây là kế hoạch có từ khi Infallible ra đời và cũng là một lý do khiến việc ổn định kiểu never khó khăn đến vậy.
Thay đổi có thể gây phá vỡ tương thích
Để đổi được Infallible, nhóm phát triển buộc phải đưa vào một thay đổi phá vỡ tương thích (breaking change): "never type fallback" chuyển từ () sang ! ở các edition trước 2024 (tức 2015, 2018 và 2021), tương tự điều đã làm ở edition 2024. Thay đổi này phần lớn khó nhận ra, nhưng có thể ảnh hưởng tới mã nguồn trong vài trường hợp hiếm, chẳng hạn khi bỏ qua kết quả của một hàm trả về tham số generic. Nó cũng có thể khiến trình biên dịch phát hiện nhiều đoạn mã là không thể chạm tới hơn.
Nhóm phát triển đã cố gắng giảm thiểu tác động bằng cách đưa ra cảnh báo tương thích tương lai từ sớm và phát hành bản vá cho các crate công khai bị ảnh hưởng. Nếu một dependency gặp lỗi do vấn đề kiểu never, nên thử cập nhật vì bản vá có thể đã có sẵn.
allocator_api: tự định nghĩa allocator
Bản phát hành ổn định phần lõi của allocator_api, cho phép tác giả thư viện định nghĩa allocator tùy chỉnh dùng được với một số kiểu trong thư viện chuẩn — hiện tại là Vec và Box, thông qua trait Allocator mới được ổn định.
Đây là nền tảng của mục tiêu dự án Allocators 1.0. Còn nhiều việc phải làm, gồm mở rộng bề mặt API dùng được với allocator tùy chỉnh và ổn định việc sử dụng chúng trên nhiều collection và kiểu con trỏ hơn, nhưng với trait lõi và thiết kế đã xong, dự kiến sẽ có thêm nhiều thứ được ổn định trong thời gian tới.
DropGuard và conjure_zst
Trait Drop trong Rust cho phép chạy mã khi một biến ra khỏi phạm vi, bất kể ta trả về, dùng ? hay panic. Nhưng việc triển khai Drop có thể bất tiện khi chỉ muốn chạy một đoạn mã vô điều kiện lúc hàm kết thúc. Vì vậy bản phát hành giới thiệu core::mem::DropGuard: một kiểu trợ giúp chạy closure khi bị drop.
DropGuard nhận hai tham số: một biến và một closure. Nó triển khai Deref và DerefMut để có thể tiếp tục làm việc với biến như bình thường, nhưng khi bị drop sẽ chạy closure và tiêu thụ biến. DropGuard còn có phương thức dismiss trả lại biến mà không chạy destructor, giúp nhanh chóng xây dựng các API kiểu giao dịch "được ăn cả, ngã về không" với cơ chế rollback — ví dụ một parser dùng guard để hoàn tác thay đổi khi gặp lỗi.
Về hướng dẫn mã unsafe, Rust 1.100 trả lời câu hỏi về việc tạo zero-sized type (ZST) một cách an toàn bằng một hàm duy nhất: std::mem::conjure_zst. Thay vì transmute(()), MaybeUninit::uninit().assume_init() hay nhiều mánh khác, đây là cách chuyên dụng để tạo giá trị của một zero-sized type khi biết chắc việc đó an toàn. Với kiểu inhabited không có kích thước, ta biết chính xác giá trị của nó: không gì cả.
Tất nhiên, nhiều API dựa vào việc không thể tạo ra những kiểu này để đảm bảo an toàn, nên hàm được đánh dấu unsafe. Ví dụ, token Python của PyO3 là một marker zero-sized đại diện cho việc giữ GIL (global interpreter lock) của Python; tạo token từ hư không sẽ cho phép các lệnh gọi PyO3 an toàn vi phạm điều kiện tiên quyết đó.
Cargo nâng cấp mạnh
Phát hiện dependency không dùng: Các dependency thừa hoặc chỉ cần cho nền tảng cụ thể làm chậm quá trình build. Trước đây rustc có lint unused_crate_dependencies nhưng báo sai khi dùng với Cargo, vì dependency có thể được chia sẻ giữa nhiều build target. Nay Cargo báo trực tiếp cho người dùng các dependency không được dùng.
Hạn chế của cảnh báo này là nó chỉ xuất hiện khi build mọi build target có thể dùng một mục trong bảng dependencies. Chẳng hạn, chạy cargo check --bin foo sẽ không hiện cảnh báo cho [dependencies] không dùng, vì có thể còn một binary khác dùng chúng. Không có cảnh báo cho dev-dependencies không dùng vì không có cách đảm bảo mọi build target phát triển đều được build. Cảnh báo này là phần của hệ thống lint mới cho Cargo, điều khiển qua bảng [lints.cargo] trong Cargo.toml.
Bố cục build-dir: Cargo build mọi thư viện và binary trong build-dir rồi chuyển artifact cuối cùng sang target-dir. Các cấu hình build khác nhau (như --features) có thể tạo ra nhiều bản sao thư viện và binary trong build-dir, được phân biệt bằng hash cấu hình build — nhưng hash này không phải lúc nào cũng được áp dụng do ràng buộc nền tảng. Điều này gây rebuild thừa, bỏ lỡ rebuild, nhầm lẫn về binary được dùng, và trầm trọng hơn khi chia sẻ build-dir giữa nhiều git worktree.
Nay build-dir áp dụng nhất quán hash cấu hình build cho mọi nội dung bằng cách tổ chức thư mục theo bước build thay vì theo loại file, và chuyển hash từ tên file sang thư mục cha. Công việc này khởi đầu từ mục tiêu dự án bố cục build directory năm 2025 và là cột mốc mở đường cho các cải tiến như dọn dẹp cache (garbage collection), khử trùng lặp cache giữa các workspace, cache liên workspace và khóa chi tiết (fine grain locking). Đây là thay đổi nội bộ nhưng có thể làm hỏng quy trình build và test vốn dùng workaround cho các tính năng thiếu hoặc chưa hoàn thiện; một số workaround giờ không cần nữa.
Cooldown dependency: Các phiên bản package độc hại thường bị phát hiện trong vòng vài giờ hoặc vài ngày sau khi phát hành, nhờ scanner tự động hoặc cộng đồng. Rust 1.100 ổn định cơ chế phân giải dependency theo tuổi phát hành tối thiểu (min-publish-age aware dependency resolution), cho phép chờ khoảng thời gian đó trước khi chọn phiên bản mới phát hành. Cách làm này còn gọi là dependency cooldowns.
Khi chọn phiên bản, Cargo bỏ qua bất kỳ phiên bản nào vừa được phát hành gần hơn mốc đó và thông báo những gì bị giữ lại. Khi cần phiên bản mới ngay, có thể bỏ qua kiểm tra cho một lần cập nhật; phiên bản mới sẽ được ghi vào Cargo.lock và giữ nguyên cho đến lần cargo update sau. Cơ chế này dựa vào việc registry ghi lại thời điểm phát hành từng phiên bản; phiên bản không có trường pubtime trong index sẽ không bị giữ lại. Lệnh cargo install bỏ qua tuổi phát hành tối thiểu, với cả crate được cài lẫn dependency của nó — có thể ghim phiên bản bằng cargo install [email protected] nếu cần.
Cooldown giảm rủi ro từ một số tấn công chuỗi cung ứng (supply chain attack) nhưng không phải lá chắn hoàn chỉnh; vẫn cần xem xét kỹ các cập nhật dependency như thường lệ. Các công việc bảo vệ hệ sinh thái khác đang được lên kế hoạch trong mục tiêu dự án tăng cường bảo mật chuỗi cung ứng cho crates.io, gồm hỗ trợ cách ly (quarantine) và tự động phát hiện bản phát hành đáng ngờ.
Góc nhìn
Với lập trình viên Rust tại Việt Nam, điểm đáng chú ý nhất là sự thay đổi never type fallback ở edition 2015, 2018 và 2021. Các dự án cũ nếu đang bỏ qua kết quả trả về của hàm generic có thể gặp hành vi mới hoặc cảnh báo nhiều hơn khi nâng cấp; nên thử build và chạy test kỹ trước khi đưa lên môi trường thật, và cập nhật các dependency đã được vá liên quan tới kiểu never.
Cơ chế cooldown dependency là một lớp phòng thủ dễ bật và nên cân nhắc cho các dự án production, đặc biệt với những đội ít có điều kiện rà soát từng bản phát hành. Dù vậy, nó chỉ bù đắp một phần rủi ro chuỗi cung ứng, nên vẫn phải duyệt thay đổi dependency như thường lệ. Với các đội tận dụng CI đa nền tảng và nhiều worktree, bố cục build-dir mới có thể là điểm cần kiểm tra lại script build — nhưng đổi lại là tiềm năng giảm rebuild thừa và tiến gần hơn tới cache dùng chung hiệu quả.
Nguồn: blog.rust-lang.org · Quy trình biên tập
Bài viết liên quan

Công nghệ
Rust 1.100.0 ra mắt: ổn định kiểu never, allocator tùy biến
13 tháng 11, 2026

Công nghệ
Rust 1.96 chính thức ra mắt: Kiểu Range mới, Macro khớp mẫu và nâng cấp WebAssembly
29 tháng 5, 2026

Phần mềm
Lỗ hổng âm thanh (soundness) 11 năm tuổi trong trình kiểm tra mượn (borrow checker) của Rust
13 tháng 10, 2026