يسر فريق Rust الإعلان عن إصدار جديد من Rust، 1.78.0. Rust هي لغة برمجة تمكّن الجميع من بناء برمجيات موثوقة وفعالة.
إذا كان لديك إصدار سابق من Rust مثبت عبر rustup، يمكنك الحصول على 1.78.0 باستخدام:
$ rustup update stable
إذا لم يكن لديك ذلك بالفعل، يمكنك الحصول على rustup من الصفحة المناسبة على موقعنا، والاطلاع على ملاحظات الإصدار التفصيلية لـ 1.78.0.
إذا كنت ترغب في مساعدتنا من خلال اختبار الإصدارات المستقبلية، فقد تفكر في التحديث محليًا لاستخدام قناة بيتا (rustup default beta) أو القناة الليلية (rustup default nightly). يرجى الإبلاغ عن أي أخطاء قد تواجهها!
تدعم Rust الآن مساحة اسم سمة #[diagnostic] للتأثير على رسائل خطأ المترجم. يتم التعامل معها كتلميحات لا يُطلب من المترجم استخدامها، وليس خطأً أيضًا تقديم تشخيص لا يتعرف عليه المترجم. تتيح هذه المرونة للكود المصدري تقديم تشخيصات حتى عندما لا تكون مدعومة من قبل جميع المترجمات، سواء كانت إصدارات مختلفة أو تطبيقات مختلفة تمامًا.
مع مساحة الاسم هذه تأتي السمة المدعومة الأولى، #[diagnostic::on_unimplemented]، والتي يمكن وضعها على سمة لتخصيص الرسالة عندما تكون هذه السمة مطلوبة ولكن لم يتم تنفيذها على نوع. ضع في اعتبارك المثال المقدم في طلب التثبيت:
#[diagnostic::on_unimplemented( message = "My Message for `ImportantTrait<{A}>` is not implemented for `{Self}`", label = "My Label", note = "Note 1", note = "Note 2" )] trait ImportantTrait<A> {} fn use_my_trait(_: impl ImportantTrait<i32>) {} fn main() { use_my_trait(String::new()); }
سابقًا، كان المترجم يعطي خطأ مدمجًا مثل هذا:
error[E0277]: the trait bound `String: ImportantTrait<i32>` is not satisfied --> src/main.rs:12:18 | 12 | use_my_trait(String::new()); | ------------ ^^^^^^^^^^^^^ the trait `ImportantTrait<i32>` is not implemented for `String` | | | required by a bound introduced by this call |
مع #[diagnostic::on_unimplemented]، تملأ رسالته المخصصة سطر الخطأ الأساسي، ويتم وضع تسميته المخصصة على مخرجات المصدر. لا تزال التسمية الأصلية مكتوبة كمخرجات مساعدة، وتتم كتابة أي ملاحظات مخصصة أيضًا. (هذه التفاصيل الدقيقة قابلة للتغيير.)
error[E0277]: My Message for `ImportantTrait<i32>` is not implemented for `String` --> src/main.rs:12:18 | 12 | use_my_trait(String::new()); | ------------ ^^^^^^^^^^^^^ My Label | | | required by a bound introduced by this call | = help: the trait `ImportantTrait<i32>` is not implemented for `String` = note: Note 1 = note: Note 2
بالنسبة لمؤلفي السمات، هذا النوع من التشخيص أكثر فائدة إذا كان بإمكانك تقديم تلميح أفضل من مجرد الحديث عن التنفيذ المفقود نفسه. على سبيل المثال، هذا نموذج مختصر من المكتبة القياسية:
#[diagnostic::on_unimplemented( message = "the size for values of type `{Self}` cannot be known at compilation time", label = "doesn't have a size known at compile-time" )] pub trait Sized {}
لمزيد من المعلومات، راجع قسم المرجع حول مساحة اسم سمة أداة diagnostic.
unsafeتحتوي مكتبة Rust القياسية على عدد من التأكيدات للشروط المسبقة لوظائف unsafe، ولكن تاريخيًا تم تمكينها فقط في بنيات #[cfg(debug_assertions)] للمكتبة القياسية لتجنب التأثير على أداء الإصدار. ومع ذلك، نظرًا لأن المكتبة القياسية عادة ما يتم تجميعها وتوزيعها في وضع الإصدار، فإن معظم مطوري Rust لم يقوموا بتنفيذ هذه الفحوصات على الإطلاق.
الآن، يتم تأخير شرط هذه التأكيدات حتى إنشاء الكود، لذلك سيتم فحصها اعتمادًا على إعداد المستخدم الخاص لتأكيدات التصحيح - ممكّنة افتراضيًا في بنيات التصحيح والاختبار. يساعد هذا التغيير المستخدمين على اكتشاف السلوك غير المحدد في الكود الخاص بهم، على الرغم من أن تفاصيل مقدار ما يتم فحصه ليست مستقرة بشكل عام.
على سبيل المثال، يتطلب slice::from_raw_parts مؤشرًا غير فارغ متوافقًا. الاستخدام التالي لمؤشر غير متوافق عمدًا له سلوك غير محدد، وبينما إذا كنت غير محظوظ فقد يبدو أنه "يعمل" في الماضي، يمكن لتأكيد التصحيح الآن اكتشافه:
fn main() { let slice: &[u8] = &[1, 2, 3, 4, 5]; let ptr = slice.as_ptr(); // Create an offset from `ptr` that will always be one off from `u16`'s correct alignment let i = usize::from(ptr as usize & 1 == 0); let slice16: &[u16] = unsafe { std::slice::from_raw_parts(ptr.add(i).cast::<u16>(), 2) }; dbg!(slice16); } thread 'main' panicked at library/core/src/panicking.rs:220:5: unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX` note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace thread caused non-unwinding panic. aborting.
تحتوي المكتبة القياسية على بعض الوظائف التي تغير محاذاة المؤشرات والشرائح، ولكن كانت لديها سابقًا تحذيرات جعلتها صعبة الاعتماد عليها في الممارسة العملية، إذا اتبعت وثائقها بدقة. كانت هذه التحذيرات موجودة بشكل أساسي كتحوط ضد تقييم const، لكنها مستقرة فقط للاستخدام غير const على أي حال. يتم الآن الوعد بأن يكون لها سلوك تشغيل متسق وفقًا لمدخلاتها الفعلية.
pointer::align_offset يحسب الإزاحة اللازمة لتغيير مؤشر إلى المحاذاة المحددة. يعيد usize::MAX إذا لم يكن ذلك ممكنًا، ولكن كان مسموحًا سابقًا بإرجاع usize::MAX دائمًا، والآن تمت إزالة هذا السلوك.slice::align_to و slice::align_to_mut كلاهما يحول الشرائح إلى شريحة وسطى متوافقة والشرائح الأمامية والخلفية غير المتوافقة المتبقية. تعد هذه الطرق الآن بإرجاع أكبر جزء وسطي ممكن، بدلاً من السماح للتنفيذ بإرجاع شيء أقل مثالية مثل إرجاع كل شيء كشريحة رأس.impl Read for &Stdin'static للعديد من تطبيقات std::error::Error ذات الصلةimpl<Fd: AsFd> impl تأخذ ?Sizedimpl From<TryReserveError> for io::Errorهذه واجهات برمجة التطبيقات مستقرة الآن في سياقات const:
Barrier::new()x86_64-pc-windows-msvci686-pc-windows-msvcx86_64-pc-windows-gnui686-pc-windows-gnux86_64-pc-windows-gnullvmi686-pc-windows-gnullvmu128/i128 المعلن عنه لأهداف x86-32 و x86-64. قد لا تزال الموزعون الذين يستخدمون LLVM الخاص بهم الأقدم من 18 يواجهون أخطاء اتفاقية الاستدعاء المذكورة في تلك المشاركة.تحقق من كل ما تغير في Rust و Cargo و Clippy.
اجتمع العديد من الأشخاص لإنشاء Rust 1.78.0. لم نكن لنتمكن من القيام بذلك بدونكم جميعًا. شكرًا!
فريق إصدار Rust
نُشر أيضًا هنا
صورة بواسطة عبيد إي. اليافعي على Unsplash


