Вышел Rust 1.99.0: функции с переменным числом аргументов можно писать на Rust

01.10.2026

Вышел Rust 1.99.0. Главное в релизе — язык научился объявлять функции с переменным числом аргументов в интерфейсе C и C-unwind: их больше не нужно писать на ассемблере. Также стабилизированы способы узнать размер и выравнивание значения по сырому указателю.

Функции с переменным числом аргументов

Вариативные функции принимают произвольное число аргументов, объявленное многоточием. Классический пример — printf. До этого Rust умел только вызывать такие функции, если они написаны на другом языке, но объявить свою такую функцию на Rust было нельзя: компилятор не генерировал ничего похожего на соглашение о вызове.

Теперь появился тип VaList, совместимый с C-типами va_list на всех поддерживаемых платформах, и трейт VaArgSafe, ограничивающий набор типов, которые можно прочитать из такого списка. Именно этот трейт делает подъём безопасным: он запрещает читать из списка типы, для которых нет гарантии о представлении, вместо того чтобы полагаться на проверку во время выполнения.

Вторым шагом стала поддержка вариативных функций с не-C интерфейсами — их по-прежнему нужно писать через инлайн-ассемблер, но теперь это хотя бы возможно.

Практическая польза — исчезновение целого класса ассемблерных вставок. Крейт, реализующий интерфейс к C-библиотеке, раньше обязан был либо генерировать пролог функции сам, либо звать обёртку на ассемблере. Теперь функция объявляется прямо на Rust, и её сигнатура проверяется компилятором, как любая другая.

Размер и выравнивание по сырому указателю

Три стабилизированные функции — Layout::for_value_raw, mem::size_of_val_raw и mem::align_of_val_raw — отвечают на вопрос о размере и выравнивании значения, на которое указывает указатель. Для типов с известным размером это было возможно и раньше, а вот для динамически размеченных — наподобие срезов и str — требовалосьunsafe-преобразование указателя в ссылку.

Смысл в том, чтобы не создавать ссылку там, где достаточно прочитать метаданные. Такое преобразование требует, чтобы указатель был корректным и выровненным, и компилятор вправе оптимизировать код исходя из этих гарантий. Ошибочный transmute здесь даёт не ошибку компиляции, а повреждение данных, поэтому новые функции безопаснее привычного обходного пути.

Не рекомендуется возвращать память обратно после Box::leak

Семантика языка не менялась, но в документации Box::leak теперь советуют не освобождать память, полученную через него, обратно. Обнаружено, что такой код плохо взаимодействует с текущими и будущими оптимизациями компилятора, и особенно неудобен в свете грядущей стабилизации пользовательских аллокаторов.

Рекомендуются Box::into_non_null и Box::into_raw. То же касается прочих функций с именем leak в стандартной библиотеке.

Стабилизированные API

  • IntoIterator для Box<[T; N]>, для ссылки на такой тип и для изменяемой ссылки — то есть массив в Box теперь перебирается как любой другой;
  • Vec::into_parts и Vec::from_parts — сведения о внутреннем устройстве вектора можно получить и собрать обратно без копирования;
  • Box::into_non_null и Box::from_non_null — переход к NonNull без промежуточного сырого указателя;
  • VecDeque::retain_back — обработка элементов с конца;
  • String::from_utf8_lossy_owned и FromUtf8Error::into_utf8_lossy — замена негодных байтов на U+FFFD с получением строки, а не среза;
  • FusedIterator для StepBy;
  • std::fs::set_times и std::fs::set_times_nofollow — установка времени доступа и изменения файла из стандартной библиотеки;
  • core::ffi::VaList — из предыдущего раздела.

Из не-API изменений: в сообщение паники добавлен идентификатор потока.

Оригинал

Announcing Rust 1.99.0 от 1 октября 2026 года; подробные примечания — в документации

Упоминаний: 1 · Просмотров: 4