Выпуск Rust 1.78. Язык Borgo, сочетающий сильные стороны Go и Rust

Опубликован релиз языка программирования общего назначения Rust 1.78, основанного проектом Mozilla, но ныне развиваемого под покровительством независимой некоммерческой организации Rust Foundation. Язык сфокусирован на безопасной работе с памятью и предоставляет средства для достижения высокого параллелизма выполнения заданий, при этом обходясь без использования сборщика мусора и runtime (runtime сводится к базовой инициализации и сопровождению стандартной библиотеки).

Методы работы с памятью в Rust избавляют разработчика от ошибок при манипулировании указателями и защищают от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п. Для распространения библиотек, обеспечения сборки и управления зависимостями проектом развивается пакетный менеджер Cargo. Для размещения библиотек поддерживается репозиторий crates.io.

Безопасная работа с памятью обеспечивается в Rust во время компиляции через проверку ссылок, отслеживание владения объектами, учёт времени жизни объектов (области видимости) и оценку корректности доступа к памяти во время выполнения кода. Rust также предоставляет средства для защиты от целочисленных переполнений, требует обязательной инициализации значений переменных перед использованием, лучше обрабатывает ошибки в стандартной библиотеке, применяет концепцию неизменяемости (immutable) ссылок и переменных по умолчанию, предлагает сильную статическую типизацию для минимизации логических ошибок.

Основные новшества:

  • Предложено новое пространство имён атрибутов “#[diagnostic]”, предоставляющее средства для влияния на выдаваемые компилятором сообщения об ошибках. Первым в новом пространстве реализован атрибут
    “#[diagnostic::on_unimplemented]”, который может использоваться для настройки сообщений об ошибках, выдаваемых в ситуации, когда требуется использовать типаж, который не реализован для типа. #[diagnostic::on_unimplemented( message = “My Message for ‘ImportantTrait’ is not implemented for ‘{Self}'”, label = “My Label”, note = “Note 1”, note = “Note 2” )] trait ImportantTrait {} fn use_my_trait(_: impl ImportantTrait) {} fn main() { use_my_trait(String::new()); } error[E0277]: My Message for ‘ImportantTrait’ 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’ is not implemented for ‘String’ = note: Note 1 = note: Note 2
  • Предварительные assert-проверки, применяемые к unsafe-функциями, теперь могут откладываться до стадии генерации кода, что позволяет выполнять данные проверки без необходимости сборки стандартной библиотеки в режиме “#[cfg(debug_assertions)]”. Для срабатывания проверок теперь достаточно включения отладочных assert-ов для тестовых или отладочных сборок своего кода.
  • Поведение функций в стандартной библиотеке, влияющих на выравнивание указателей и срезов (slice), теперь предсказуемо во время выполнения и зависит от входных данных. Функция pointer::align_offset, вычисляющая смещение для выравнивания указателя, теперь возвращает usize::MAX только при невозможности выполнения операции. Функции slice::align_to и slice::align_to_mut both, преобразующие срезы в представление с выровненным средним срезом и исходными начальным и конечным срезами, теперь всегда возвращают самую большую среднюю часть.
  • В разряд стабильных переведены:
    • impl Read for &Stdin
    • Разрешено использование нестатичного (не ‘static) времени жизни для некоторых реализаций, связанных с std::error::Error.
    • В реализации impl разрешено использование
      значения ?Sized.
    • impl From for io::Error
  • Функция Barrier::new() стабилизирована для использования с признаком “const” в любом контексте вместо констант.
  • Для целевых платформ x86_64-pc-windows-msvc, i686-pc-windows-msvc, x86_64-pc-windows-gnu, i686-pc-windows-gnu, x86_64-pc-windows-gnullvm и i686-pc-windows-gnullvm теперь требуется как минимум версия Windows 10.
  • Реализован третий уровень поддержки для платформ wasm32-wasip2, arm64ec-pc-windows-msvc, armv8r-none-eabihf и loongarch64-unknown-linux-musl. Третий уровень подразумевает базовую поддержку, но без автоматизированного тестирования, публикации официальных сборок и проверки возможности сборки кода.
  • Реализован второй уровень поддержки целевой платформы Add wasm32-wasip1. Второй уровень поддержки подразумевает гарантию сборки.
  • Платформа wasm32-wasi-preview1-threads переименована в wasm32-wasip1-threads.
  • Компилятор переведён на использование LLVM 18. При использовании LLVM 18 для архитектур x86-32 и x86-64 изменён ABI, связанный с типами u128 и i128.
  • В пактом менеджере Cargo стабилизирована 4 версия файлов-блокировок (lockfile v4).
  • В Cargo cтабилизирован глобальный кэш с информацией о последнем использовании данных. Кэш размещается в файле $CARGO_HOME/.global-cache при помощи SQLite, обновляется автоматически и отражает последние изменения, связанные с индексом, crate-файлом, каталогом с кодом, git clone и git checkout.

Дополнительно можно отметить язык программирования Borgo, который пытается быть более выразительным, чем язык Go, но менее сложным, чем язык Rust. Borgo комбинирует лучшие черты Go и Rust, восполняя недостатки каждого из языков. Например, язык Go прост и понятен, но не предоставляет расширенных средств для обеспечения безопасности при работе с типами. Язык Rust предоставляет средства для безопасного программирования, но переусложнён.


В Borgo используется статическая типизация, аналогичные языку Go типы и элементы синтаксиса, похожие на Rust. Указание точек с запятой в конце строк в коде на Borgo не является обязательным. Код на языке Borgo компилируется в представление на языке Go, которое полностью совместимо с существующими пакетами для языка Go. Код компилятора написан на языке Rust и распространяется под лицензией ISC.

Release. Ссылка here.