ประกาศ Rust 1.96.0
(blog.rust-lang.org)- Rust 1.96.0 สามารถติดตั้งได้ด้วย
rustup update stableและสามารถมีส่วนร่วมในการตรวจสอบรีลีสถัดไปได้ผ่านช่องทาง beta/nightly - ชนิด
core::range::Range*ใหม่ใช้ IntoIterator แทนIteratorจึงสามารถ implementCopyได้ และมีแผนจะเป็นชนิดพื้นฐานของไวยากรณ์ช่วงในอนาคต - assert_matches! และ
debug_assert_matches!จะแสดงค่าในรูปแบบDebugเมื่อแพตเทิร์นไม่ตรงกัน ทำให้วิเคราะห์สาเหตุของการทดสอบที่ล้มเหลวได้ง่ายขึ้น - เป้าหมาย WebAssembly จะไม่ส่ง
--allow-undefinedเป็นค่าเริ่มต้นอีกต่อไป ทำให้ สัญลักษณ์ที่ยังไม่ได้กำหนด กลายเป็นข้อผิดพลาดของลิงเกอร์แทนที่จะเป็น import - Cargo รวมการแก้ไข CVE-2026-5223 และ
CVE-2026-5222สำหรับผู้ใช้ third-party registry และผู้ใช้ crates.io จะไม่ได้รับผลกระทบ
การเปลี่ยนแปลงสำคัญใน Rust 1.96.0
-
การอัปเดตและช่องทางทดสอบ
- ผู้ใช้ที่ติดตั้ง Rust เดิมด้วย
rustupสามารถรับ Rust 1.96.0 ได้ด้วยrustup update stable - หากยังไม่มี
rustupสามารถติดตั้งได้จากหน้าติดตั้ง rustupบนเว็บไซต์ Rust และมีการเผยแพร่บันทึกประจำรุ่นฉบับเต็มของ 1.96.0แล้ว - หากต้องการมีส่วนร่วมในการตรวจสอบรีลีสในอนาคต สามารถใช้ ช่องทาง beta/nightly ได้ด้วย
rustup default betaหรือrustup default nightlyและรายงานบั๊กได้ที่ Rust issue tracker
- ผู้ใช้ที่ติดตั้ง Rust เดิมด้วย
-
ชนิด
Range*ใหม่- เดิมที
Rangeและชนิดที่เกี่ยวข้องในcore::opsเป็นสิ่งที่ผู้ใช้จำนวนมากคาดหวังว่าจะเป็นCopyแต่เนื่องจากมีการ implementIteratorโดยตรง จึงไม่ได้ implementCopyร่วมด้วย - แนวทาง implement ทั้ง
IteratorและCopyบนชนิดเดียวกันถือเป็น footgun ที่ Clippy เตือน จึงมีการหลีกเลี่ยงมาโดยตลอด - RFC3550 เสนอชนิดช่วงทางเลือกที่ implement
IntoIteratorแทนIteratorและโครงสร้างนี้ทำให้ชนิดเหล่านี้สามารถ implementCopyได้ด้วย - ในไลบรารีมาตรฐาน มีการทำให้
core::range::Range,core::range::RangeFrom,core::range::RangeInclusiveและ iterator ที่เกี่ยวข้องมีสถานะ stable แล้ว - ใน Rust เวอร์ชันใกล้เคียงในอนาคต จะมีการเพิ่ม
core::range::RangeFullและcore::range::RangeToที่ re-export จากcore::opsอีกครั้ง รวมถึงcore::range::legacy::*ซึ่งจะเป็นตำแหน่งใหม่ของชนิดช่วงปัจจุบัน - ไวยากรณ์ช่วง อย่าง
0..1ตอนนี้ยังสร้างชนิดแบบ legacy อยู่ แต่ใน edition ถัดไปมีแผนจะเปลี่ยนเป็นชนิดในcore::range - การทำให้ stable ครั้งใหม่นี้ช่วยให้สามารถเก็บตัวเข้าถึง slice ไว้ในชนิด
Copyได้โดยไม่ต้องแยกstartและend - ตัวอย่าง:
use core::range::Range; #[derive(Clone, Copy)] pub struct Span(Range<usize>); impl Span { pub fn of(self, s: &str) -> &str { &s[self.0] } } RangeInclusiveแบบใหม่เปิดเผยฟิลด์ และไม่จำเป็นต้องหลีกเลี่ยงการเปิดเผยสถานะ iterator ที่ใช้หมดแล้วเหมือนเวอร์ชัน legacy- ชนิดใหม่นี้ต้องถูกแปลงก่อนเริ่มทำการวนซ้ำ ดังนั้นฟิลด์ที่เปิดเผยจึงไม่เป็นปัญหา
- ผู้เขียนไลบรารีควรพิจารณาใช้
impl RangeBoundsใน public API เพื่อรองรับทั้งชนิดช่วงแบบ legacy และแบบใหม่ - หากจำเป็นต้องใช้ชนิดแบบเจาะจง แนะนำให้เลือก ชนิดช่วงใหม่ ซึ่งจะกลายเป็นค่าเริ่มต้นในอนาคต
- เดิมที
-
แมโครสำหรับยืนยันการจับคู่แพตเทิร์น
- แมโครใหม่
assert_matches!และdebug_assert_matches!ใช้ตรวจสอบว่าค่าตรงกับแพตเทิร์นที่กำหนดหรือไม่ และหากไม่ตรงจะ panic พร้อมแสดงค่าในรูปแบบDebug - โดยพื้นฐานแล้วทั้งสองแมโครเทียบเท่ากับ
assert!(matches!(..))และdebug_assert!(matches!(..))แต่การแสดงค่าตอนล้มเหลวช่วยเพิ่ม ความสามารถในการวินิจฉัย - เนื่องจากอาจชนกับ third-party crate ยอดนิยมที่มีแมโครชื่อเดียวกัน จึงไม่ได้ถูกเพิ่มเข้าไปใน standard prelude
- ก่อนใช้งานต้อง import โดยตรงจาก
coreหรือstd - ตัวอย่าง:
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); }
- แมโครใหม่
-
การเปลี่ยนแปลงของเป้าหมาย WebAssembly
- เป้าหมาย WebAssembly จะไม่ส่ง
--allow-undefinedไปยังลิงเกอร์อีกต่อไป - ระหว่างการลิงก์ สัญลักษณ์ที่ยังไม่ได้กำหนด จะไม่ถูกแปลงเป็น WebAssembly import ของโมดูล
"env"แต่จะกลายเป็นข้อผิดพลาดของลิงเกอร์แทน - หากสัญลักษณ์ที่เกี่ยวกับการลิงก์ยังไม่ได้กำหนดทั้งหมด โมดูลจะไม่สามารถลิงก์ได้ ซึ่งช่วยจับบั๊กได้เร็วขึ้นและป้องกันปัญหาที่เกิดขึ้นโดยไม่ตั้งใจ เช่น ชื่อสัญลักษณ์ผิด
- โดยทั่วไปแล้วสัญลักษณ์ที่เกี่ยวกับการลิงก์ที่ยังไม่ได้กำหนดมักชี้ถึงบั๊กในช่วง build หรือการตั้งค่าที่ผิดพลาด
- หากต้องการพฤติกรรมเดิมโดยตั้งใจ สามารถย้อนกลับได้ด้วย
RUSTFLAGS=-Clink-arg=--allow-undefinedหรือใช้#[link(wasm_import_module = "env")]กับบล็อกที่กำหนดสัญลักษณ์ในซอร์สโค้ด - การเปลี่ยนแปลงนี้ถูกนำมาใช้ใน Rust 1.96 หลังจาก ประกาศในบล็อกก่อนหน้านี้
- เป้าหมาย WebAssembly จะไม่ส่ง
API ที่ทำให้ stable และการแก้ไขด้านความปลอดภัย
-
API ที่ทำให้ stable
-
คำแนะนำด้านความปลอดภัยของ Cargo 2 รายการ
- Rust 1.96 รวมการแก้ไข ช่องโหว่ของ Cargo 2 รายการ สำหรับผู้ใช้ third-party registry
- CVE-2026-5223 เป็นช่องโหว่ระดับ ความรุนแรงปานกลาง ที่เกี่ยวข้องกับการแตกไฟล์ tarball ของ crate ที่มี symbolic link
- CVE-2026-5222 เป็นช่องโหว่ระดับ ความรุนแรงต่ำ ที่เกี่ยวข้องกับการยืนยันตัวตนผ่าน URL ที่ถูกทำให้เป็น canonical แล้ว
- ผู้ใช้ crates.io จะไม่ได้รับผลกระทบจากทั้งสองช่องโหว่
-
การเปลี่ยนแปลงเพิ่มเติม
1 ความคิดเห็น
ความคิดเห็นจาก Lobste.rs
รู้สึกว่าอยากมี
assert_matchesใช้อยู่เรื่อย ๆ แต่ทุกครั้งก็ต้องชั่งใจว่าจะเพิ่ม crate ใหม่หรือเขียนขึ้นมาเองอีกรอบเพราะงั้นเลยดีใจที่มันเข้าไปอยู่ใน standard library
ชอบขั้นตอนที่กำลังจะทำให้ช่วงค่าเป็น ชนิด
Copyบางครั้งผมเคยตกใจที่ต้อง clone ช่วงค่า และมันก็ตรงกับสัญชาตญาณมากกว่าว่า
12..34ควรเป็นข้อมูลเล็ก ๆ ที่คัดลอกได้แต่ถ้ามีหลายชนิดที่ชื่อเดียวกัน ก็แอบกังวลนิดหน่อยว่าเวลาที่ VS Code เพิ่ม
useให้อัตโนมัติครั้งหน้า มันอาจดึงชนิดผิดมาสำหรับผู้ใช้ส่วนใหญ่ ข้อดีของชนิดใหม่คงมีไม่มาก เลยใช้ชนิดเดิมต่อไปได้ และพอถึงขอบเขตของ edition ถัดไปก็จะเปลี่ยนไปใช้ชนิดใหม่ให้อัตโนมัติ
น่าจะเป็นพวกคนเขียนไลบรารีที่ต้องการรองรับทั้งสองเวอร์ชันอย่างชัดเจนเป็นหลักที่ต้อง import ชนิดเหล่านี้
สามารถเปลี่ยน prelude ได้โดยไม่ทำให้โปรเจ็กต์เดิมพัง