Pull to refresh

Выпуск Rust 1.38.0: конвейерная компиляция, #[deprecated] для макросов и std::any::type_name

Reading time 4 min
Views 3.9K
Original author: The Rust Release Team

Команда разработчиков Rust рада сообщить о выпуске новой версии, 1.38.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.


Если вы установили предыдущую версию Rust средствами rustup, то для обновления до версии 1.38.0 вам достаточно выполнить следующую команду:


rustup update stable

Если у вас ещё не установлен rustup, вы можете установить его с соответствующей страницы нашего веб-сайта.


Что вошло в стабильную версию?


Изюминка данного выпуска — конвейерная компиляция.


Конвейерная компиляция


Компилятору нужны не полностью собранные зависимости для сборки пакета, а лишь их "метаданные" (список типов, зависимостей, экспортов и т.д.), генерируемые на ранней стадии компиляции. Начиная с Rust 1.38.0, Cargo будет сразу же начинать сборку зависимых пакетов, как только их метаданные будут доступны.


Время сборки одного пакета не уменьшилось, но наши тесты показали, что скорость компиляции возрастает на 10%-20% в случае оптимизированных сборок (где некоторые зависимости уже скомпилированы). Для других же пакетов сильного прироста скорости компиляции не произошло. Время, необходимое для сборки пакета, зависит от компьютера, поэтому показатели могут отличаться. Конвейерная компиляция включена автоматически с версии 1.38.0.


Проверка некоторых неправильных использований mem::{uninitialized, zeroed}


Как ранее анонсировалось, std::mem::uninitialized не рекомендуется к применению. Вместо неё должен использоваться MaybeUninit<T>.


Функция mem::uninitialized ещё не обозначена устаревшей, но это будет сделано в следующих выпусках. Но несмотря на это, начиная с 1.38.0, rustc совершает проверку для узкого класса неправильных инициализаций с использованием mem::uninitialized или mem::zeroed.


Для некоторых типов, таких как &T и Box<T>, нулевое значение считается неопределённым поведением, так как они представляют собой подобные указателю объекты, которые не должны быть null. Будет ошибкой использовать mem::uninitialized или mem::zeroed для инициализации этих типов, поэтому компилятор будет пытаться предупредить вас, если какая-либо из этих функций используется для инициализации указанных выше объектов, и не важно, будут ли они инициализированы напрямую или в качестве поля большой структуры. Данная проверка рекурсивная, так что следующий код влечёт за собой предупреждение:


struct Wrap<T>(T);
struct Outer(Wrap<Wrap<Wrap<Box<i32>>>>);
struct CannotBeZero {
    outer: Outer,
    foo: i32,
    bar: f32
}

...

let bad_value: CannotBeZero = unsafe { std::mem::uninitialized() };

Внимательные читатели могут заметить, что стандартная библиотека содержит больше типов, которые не должны быть заполнены нулями, особенно NonNull<T> и NonZero<T>. Пока что инициализация этих структур посредством mem::uninitialized или mem::zeroed не проверяется.


Данные проверки не покрывают все случаи ненадлежащего использования mem::uninitialized или mem::zeroed, но позволяют обнаружить гарантированно неверный код, который должен перейти на использование MaybeUninit.


#[deprecated] для макросов


Атрибут #[deprecated], впервые представленный в Rust 1.9.0, позволяет авторам пакетов уведомлять пользователей об устаревающей функциональности, которую планируется удалить в последующих выпусках. Rust 1.38.0 позволяет применять данный атрибут и для макросов.


std::any::type_name


Строковое представление используемого типа может понадобиться при отладке кода. Например, в теле обобщённой функции вы можете захотеть напечатать тип переданного аргумента. Теперь это осуществимо посредством std::any::type_name:


fn gen_value<T: Default>() -> T {
    println!("Initializing an instance of {}", std::any::type_name::<T>());
    Default::default()
}

fn main() {
    let _: i32 = gen_value();
    let _: String = gen_value();
}

Результат:


Initializing an instance of i32
Initializing an instance of alloc::string::String

Как и все функции стандартной библиотеки, предназначенные только для отладки, данная функция точное содержание и формат строки не гарантирует. Возвращаемое значение является лучшим описанием типа; несколько типов могут быть представимы одним и тем же type_name, но оно может измениться в будущих версиях компилятора.


Изменения в стандартной библиотеке



Кроме того, некоторые функции были стабилизированы:



Другие изменения


Синтаксис, пакетный менеджер Cargo и анализатор Clippy также претерпели некоторые изменения.


Участники 1.38.0


Множество людей собрались вместе, чтобы создать Rust 1.38.0. Мы не смогли бы сделать это без всех вас, спасибо!


От переводчиков


С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов.


Данную статью совместными усилиями перевели andreevlex, nlinker, funkill и Gymmasssorla.

Tags:
Hubs:
+41
Comments 3
Comments Comments 3

Articles