Выпуск Rust 1.86. Подготовка официальной спецификации языка Rust

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

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

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

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

  • Добавлена поддержка приведения (upcast) типажей к базовому супертипажу (supertrait), т.е. появилась возможность прямого преобразования ссылки на объект типажа в ссылку на объект супертипажа без необходимости создания специального метода в типаже, возвращающего ссылку на супертипаж.
    Аналогичную операцию можно выполнять и с другими видами умных указателей, например, “Arc -> Arc” и “*const dyn Trait -> *const dyn Supertrait”. trait Trait: Supertrait {} trait Supertrait {} fn upcast(x: &dyn Trait) -> &dyn Supertrait { x }
  • В HashMap и срезы (slice) добавлен метод get_disjoint_mut() для одновременного получения нескольких изменяемых ссылок на элементы. Ранее borrow checker не допускал одновременное использование ссылок, полученных при помощи метода get_mut(). let v = &mut [1, 2, 3]; if let Ok([a, b]) = v.get_disjoint_mut([0, 2]) { *a = 413; *b = 612; } assert_eq!(v, &[413, 2, 612]); if let Ok([a, b]) = v.get_disjoint_mut([0..1, 1..3]) { a[0] = 8; b[0] = 88; b[1] = 888; } assert_eq!(v, &[8, 88, 888]);
  • Разрешено маркировать safe-функции при помощи атрибута “#[target_feature]”, указывающего, что функция использует заданные возможности CPU. Safe-функцию, помеченную
    атрибутом “#[target_feature]”, другая safe-функция может безопасно вызвать только при условии, что она тоже помечена “#[target_feature]” (иначе подобные функции нужно вызывать в unsafe-блоке). При этом их нельзя передавать в функции, принимающие обобщенные (generic) параметры, ограниченные типажами Fn*. Ранее атрибут “#[target_feature]” мог применяться только к функциям, помеченным как “unsafe”. #[target_feature(enable = “avx2”)] fn requires_avx2() { // … } #[target_feature(enable = “avx2”)] fn safe_callsite() { requires_avx2(); } fn unsafe_callsite() { if is_x86_feature_detected!(“avx2”) { unsafe { requires_avx2() }; } }
  • В компиляторе Rust включена подстановка отладочных проверок (debug-assert), что указатель не содержит значение NULL при чтении и записи ненулевых размеров, а также при повторном заимствовании (reborrow) указателя в ссылку. Например, при включении отладочных проверок нижеприведённый код теперь будет приводить к состоянию “panic”: let _x = *std::ptr::null::(); let _x = &*std::ptr::null::();
  • По умолчанию включена lint-проверка “missing_abi”, приводящая к выводу предупреждения, если после ключевого слова extern не указан ABI. Ранее, если после extern не указан ABI, подразумевалось, что используется ABI “C”. Теперь рекомендуется явно указывать ABI “C”, например, ‘extern “C” {}’ и ‘extern “C” fn’
  • В разряд стабильных переведена новая порция API, в том числе стабилизированы методы и реализации типажей:
    • {float}::next_down
    • {float}::next_up
    • <[_]>::get_disjoint_mut
    • <[_]>::get_disjoint_unchecked_mut
    • slice::GetDisjointMutError
    • HashMap::get_disjoint_mut
    • HashMap::get_disjoint_unchecked_mut
    • NonZero::count_ones
    • Vec::pop_if
    • sync::Once::wait
    • sync::Once::wait_force
    • sync::OnceLock::wait
  • Признак “const” применён в функциях:
    • hint::black_box
    • io::Cursor::get_mut
    • io::Cursor::set_position
    • str::is_char_boundary
    • str::split_at
    • str::split_at_checked
    • str::split_at_mut
    • str::split_at_mut_checked
  • Реализован третий уровень поддержки для платформ {aarch64-unknown,x86_64-pc}-nto-qnx710_iosock, {aarch64-unknown,x86_64-pc}-nto-qnx800, {x86_64,i686}-win7-windows-gnu, amdgcn-amd-amdhsa, x86_64-pc-cygwin, {mips,mipsel}-mti-none-elf, m68k-unknown-none-elf, armv7a-nuttx-{eabi,eabihf}, aarch64-unknown-nuttx и thumbv7a-nuttx-{eabi,eabihf}. Третий уровень подразумевает базовую поддержку, но без автоматизированного тестирования, публикации официальных сборок и проверки возможности сборки кода.
  • Добавлено предупреждение о прекращении второго уровня поддержки для целевой платформы i586-pc-windows-msvc в следующем выпуске (1.87). Рекомендуется использовать платформу i686-pc-windows-msvc, которая отличается поддержкой инструкций SSE2. Платформа i586-pc-windows-msvc потеряла смысл, так как для Windows 10 необходима поддержка SSE2, а более ранние выпуски Windows в Rust не поддерживаются.

Дополнительно можно отметить, что компания Ferrocene передала сообществу спецификацию на язык Rust (FLS – Ferrocene Language Specification), созданную в процессе разработки своего компилятора Rust для критически важных систем и периодически синхронизируемую с актуальным состоянием основного компилятора Rust. Спецификация FLS включает структурированное и детальное руководство по синтаксису, семантике и поведению Rust, пригодное для верификации, оценки совместимости и стандартизации.

Переданные материалы будут использованы для создания эталонной спецификации на язык Rust, которую можно будет использовать при разработке альтернативных компиляторов и для проверки компилятора в областях, критически важных с точки зрения безопасности.

Release. Ссылка here.