Методы работы с памятью в Rust нацелены на исключение ошибок при манипулировании указателями и защиту от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п. Для распространения библиотек, обеспечения сборки и управления зависимостями проектом развивается пакетный менеджер Cargo. Для размещения библиотек поддерживается репозиторий crates.io.
Безопасная работа с памятью обеспечивается в Rust во время компиляции через проверку ссылок, отслеживание владения объектами, учёт времени жизни объектов (области видимости) и оценку корректности доступа к памяти во время выполнения кода. Rust также предоставляет средства для защиты от целочисленных переполнений, требует обязательной инициализации значений переменных перед использованием, лучше обрабатывает ошибки в стандартной библиотеке, применяет концепцию неизменяемости (immutable) ссылок и переменных по умолчанию, предлагает сильную статическую типизацию для минимизации логических ошибок.
Основные новшества:
- Стабилизирован тип "never", обозначаемый символом "!" и определяющий вычисления, никогда не приводящие к возврату значений, любой код следом за которыми недостижим. Например, тип "!" имеют выражения, прерывающие ход выполнения программы, такие как функция "exit", макрос "panic!", бесконечные циклы, ключевые слова "return", "break", "continue" и "become". Похожий тип Infallible, применяемый для обозначения ошибок, которые никогда не произойдут, теперь является псевдонимом типа "!". Поскольку тип "!" не имеет значений, его разрешено автоматически приводить к любым другим типам, например, для того чтобы не возвращать значение в одном из выражений конструкций "match" и "if".
Код:
fn mrrrow(option: Option‹u32›) {
let value = match option {
// x с типом u32
Some(x) => x,
// return имеет тип "!", который приводится к типу u32 для
соответствия типу выражения в match
None => return,
};
} - Стабилизирована часть API Allocator и типаж Allocator, позволяющие создавать собственные обработчики выделения памяти и использовать их вместе с типами стандартной библиотеки. На текущем этапе развития допускается создание аллокаторов только для типов Vec и Box.
- Добавлен вспомогательный тип DropGuard (core::mem::DropGuard), который позволяет гарантированно выполнить замыкание (closure) при любом выходе контролируемой переменной из области видимости (например, выполнении return, возврате ошибки через "?" или аварийном завершении) без необходимости создания отдельной обёртки и реализации для неё типажа Drop.
- Добавлена функция std::mem::conjure_zst для создания типов нулевого размера (ZST, Zero-Sized Type) в unsafe-коде, без трюков типа std::mem::transmute(()) и MaybeUninit::uninit().assume_init(). Подобные типы имеют размер 0 байт и могут принимать только одно пустое значение. Экземпляры данного типа используются как маркеры, подтверждающие выполнение определённых условий. Например, в библиотеке PyO3 подобный маркер указывает, что текущий поток удерживает глобальную блокировку (GIL, Global Interpreter Lock).
- В пакетный менеджер Cargo добавлены возможности для обнаружения неиспользуемых зависимостей на уровне пакета, не завязанные на вызов линтера (unused_crate_dependencies). Для исключения ложных срабатываний, предупреждение о неиспользуемой зависимости выводится только при сборке всех сборочных целей, которые теоретически могут использовать эту зависимость. Возможность реализована как часть более крупного проекта по добавлению в Cargo собственной системы линтинга. Правила проверок можно настраивать в Cargo.toml в секции "[lints.cargo]", аналогично тому, как настраиваются "[lints.rust]" и "[lints.clippy]".
- В Cargo переработана структура каталогов сборки (build-dir) для устранения коллизий в кэше при использовании разных конфигураций (например, разных наборов "--features"). Каталоги теперь группируются по этапам сборки (build step), а не по типам файлов, а хэш сборочной конфигурации применяется ко всему контенту и перенесён из имени файла в имя родительского каталога.
- В Cargo реализована настройка "global-min-publish-age", позволяющая задать "период охлаждения", допускающий установку новых версий при выполнении "cargo update" только если с момента их публикации прошло определённое время, иначе лишь выводится предупреждение о доступности новой версии, без её установки. Подобная задержка позволяет защититься от установки вредоносных версий пакетов, выпущенных в случае компрометации проектов. Как правило, подобные вредоносные публикации обнаруживаются сообществом в первые часы или дни после публикации. Для принудительного обновления в обход периода охлаждения можно использовать переменную кружения "CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow".
Код:
[registry]
global-min-publish-age = "3 days" - В разряд стабильных переведена новая порция API, в том числе стабилизированы методы и реализации типажей:
- impl PartialEq‹Cow‹'_, [U]›› for Vec‹T, A>
- impl PartialEq‹Cow‹'_, [U]›› for &[T]
- impl PartialEq‹Cow‹'_, [U]›› for &mut [T]
- std::alloc::Allocator
- std::alloc::Global
- std::alloc::System
- impl Allocator for Global
- impl Allocator for System
- impl‹A: Allocator> Allocator for &A
- impl‹T: Allocator, A: Allocator> Allocator for Box‹T, A>
- impl‹A: Allocator> Allocator for &mut A
- impl‹T: Allocator, A: Allocator> Allocator for Arc‹T, A>
- impl‹T: Allocator, A: Allocator> Allocator for Rc‹T, A>
- Box::new_in
- Box::from_raw_in
- Box::from_non_null_in
- Box::into_raw_with_allocator
- Box::into_non_null_with_allocator
- Box::allocator
- Vec::new_in
- Vec::with_capacity_in
- Vec::from_raw_parts_in
- Vec::from_parts_in
- Vec::into_raw_parts_with_allocator
- Vec::into_parts_with_allocator
- Vec::allocator
- Child::main_thread_handle
- impl Default for std::sync::Once
- bool::toggle
- Box::take
- Box::map
- Rc::map
- Arc::map
- impl AsRef‹T> for !
- impl AsMut‹T> for !
- core::mem::DropGuard
- core::mem::conjure_zst
- UnsafeCell::replace
- UnsafeCell::as_ref_unchecked
- UnsafeCell::as_mut_unchecked
- str::trim_prefix
- str::trim_suffix
- [T]::trim_prefix
- [T]::trim_suffix
- Path::trim_prefix
- Vec::from_fn
- os::windows::process::CommandExt::show_window
- Целевые платформы i686-pc-windows-gnu и wasm32-wasip3 переведены на второй уровень поддержки, который подразумевает гарантию сборки, но отсутствие гарантий при прохождении тестового набора.
- Добавлена поддержка платформы powerpc64-sony-ps3, для которой обеспечен третий уровень поддержки. Третий уровень охватывает базовую поддержку, но без автоматизированного тестирования, публикации официальных сборок и проверки возможности сборки кода.
Дополнительно можно отметить недавно анонсированные проекты и события, связанные с Rust:
- Компания Cloudflare в сотрудничестве с командой TypeScript разрабатывает порт компилятора TypeScript, написанный на языке Rust - tsrs. В проведённых тестах новая реализация оказалась в 8 раз быстрее и потребляла на 70% меньше памяти по сравнению с написанным на языке Go штатным компилятором из состава TypeScript 7.0. Часть появившихся в tsrs оптимизаций перенесена в основной состав TypeScript, что позволило до 2.5 раз поднять производительность штатного компилятора. Язык Rust выбран как позволяющий добиться большей эффективности при сборке в WebAssembly, так как в отличие от языка Go в Rust не используется сборщик муcора. Запуск в WebAssembly важен для Cloudflare для реализации поддержки TypeScript в Cloudflare Worker-ах.
- rustd - фоновый процесс для оптимизации компиляции кода на Rust, позволяющий до 25 раз ускорить повторные и параллельные сборки при помощи cargo за счёт сохранения состояния компиляции. В отличие от cargo и rustc, которые каждый раз анализируют и компилируют код с нуля, rustd хранит результаты анализа кода в оперативной памяти, а скомпилированные представления функций в кэше на диске. При внесении изменений перекомпилируются только изменившиеся функции. Проект актуален для систем, в которых приходится многократно и параллельно в нескольких рабочих деревьях собирать один и тот же код.
- FTL - операционная система для облачных систем, написанная на Rust и предоставляющая слой совместимости с Linux. В FTL применяется минималистичное ядро наподобие гипервизора, которое предоставляет базовые примитивы, такие как vCPU и виртуальное адресное пространство, и перенаправляет системные вызовы Linux в обработчик в пользовательском пространстве. В пользовательском пространстве в форме библиотек также реализованы стек TCP/IP, VFS и средства управления процессами.
По аналогии с gVisor каждый контейнер содержит собственный изолированный экземпляр ОС и может применяться для запуска Linux-контейнеров. Код поставляется под лицензией MIT. - Компания Collabora рассказала о прогрессе интеграции в основной состав ядра Linux драйвера Tyr для GPU ARM Mali-G610, написанного на Rust. В недавно выпущенное ядро Linux 7.3 вошли изменения, позволяющие загружать прошивки в формате Mali CSF, активировать виртуальную память GPU и запускать микроконтроллер (MCU) для обеспечения взаимодействия c GPU, но до полноценной замены драйвера Panthor ещё далеко.
- На языке Rust подготовлена альтернативная прошивка для USB-тестера Kowsi KWS-X1, предоставляющая такие расширенные возможности, как продвинутый графический интерфейс с графиками изменения напряжения, силы тока и мощности, диагностика и сканирование зарядных устройств, управление протоколами быстрой зарядки. Код открыт под лицензиями MIT и Apache-2.0.
- blackship - написанный на Rust инструментарий оркестровки Jail-окружений для FreeBSD, поддерживающий декларативную конфигурацию в формате TOML, интеграцию с ZFS, импорт содержимого через "zfs send | ssh zfs receive", VNET для сети, шаблоны Jailfile, управление зависимостями при запуске сервисов, обновление jail-окружений на лету, ограничение ресурсов, MCP-сервер и контроль над жизненным циклом jail-окружений.
Источник: https://www.opennet.ru/opennews/art.shtml?num=66680
(opennet.ru, основная лента)