- PVSM.RU - https://www.pvsm.ru -

Выпуск Rust 1.37.0: Profile-Guided Optimization, неименованные константы и cargo vendor

Представляем вашему вниманию перевод публикации [1] о новой версии всеми любимого языка программирования Rust [2].

Введение

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

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

$ rustup update stable

Если у вас ещё не установлен rustup, вы можете установить его [3] с соответствующей страницы нашего веб-сайта, а также посмотреть подробные примечания к выпуску [4] на GitHub.

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

Основные новшества в Rust 1.37.0 включают в себя ссылки на варианты перечисления (enum) через псевдонимы типов (type), встроенный cargo vendor, неименованные константы (const), profile-guided optimization, ключ default-run для Cargo проектов и #[repr(align(N))] для перечислений. Для получения дополнительной информации ознакомьтесь с подробными примечаниями к выпуску [4].

Ссылки на варианты перечисления (enum) через псевдонимы типов (type)

Начиная с Rust 1.37.0, ссылаться на варианты перечисления (enum) стало возможным через псевдонимы типов:

type ByteOption = Option<u8>;

fn increment_or_zero(x: ByteOption) -> u8 {
    match x {
        ByteOption::Some(y) => y + 1,
        ByteOption::None => 0,
    }
}

В impl блоках Self выступает в качестве псевдонима типа, поэтому в Rust 1.37.0 стало возможным ссылаться на варианты перечисления, используя синтаксическую конструкцию Self::Variant:

impl Coin {
    fn value_in_cents(&self) -> u8 {
        match self {
            Self::Penny => 1,
            Self::Nickel => 5,
            Self::Dime => 10,
            Self::Quarter => 25,
        }
    }
}

А точнее, теперь Rust позволяет ссылаться на варианты перечисления через "type-relative resolution", <MyType<..>>::Variant. Более подробное описание доступно в отчёте о стабилизации [5].

Встроенная поддержка Cargo для зависимостей поставщика

После нескольких лет существования в качестве отдельного пакета [6], команда cargo vendor теперь интегрирована в Cargo. Данная команда извлекает все зависимости вашего проекта в каталог vendor/ и показывает фрагмент конфигурации, необходимый для использования кода поставщика во время сборки.

cargo vendor уже применяется в реальных проектах: компилятор Rust rustc использует его для отправки всех своих зависимостей в tar-архивы выпусков, а проекты с монорепозиториями используют его для фиксации кода зависимостей в системе управления версиями.

Использование неименованных констант (const) в макросах

Теперь вы можете создавать неименованную (unnamed) константу (const) [7], подменив её идентификатор нижним подчёркиванием (_). Например, в компиляторе rustc мы нашли такой код:

/// Проверка размера типа, где первый параметр
/// это тип, а второй - ожидаемый размер.
#[macro_export]
macro_rules! static_assert_size {
    ($ty:ty, $size:expr) => {
        const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
        //    ^ Обратите внимание на подчеркивание.
    }
}

static_assert_size!(Option<Box<String>>, 8); // 1.
static_assert_size!(usize, 8); // 2.

Обратите внимание на второй static_assert_size!(..): благодаря использованию неименованных констант стало возможным предотвратить конфликт имён при объявлении новых элементов. Ранее вам нужно было бы написать static_assert_size!(MY_DUMMY_IDENTIFIER, usize, 8);. С введением неименованных констант становится проще создавать эргономичные и многократно используемые декларативные и процедурные макросы для целей статического анализа.

Profile-guided optimization

В компиляторе rustc теперь доступна Profile-Guided Optimization (PGO) [8], которую можно включить через флаги компилятора -C profile-generate и -C profile-use.

Profile-Guided Optimization [9] — это техника оптимизации программ компиляторами, анализирующая тестовые запуски, вместо исходного кода. Она работает путём компиляции программы для оптимизации в два этапа:

  1. Сперва программа создаётся средствами инструментария, встроенного в компилятор. Это делается путём передачи rustc флага -C profile-generate. Затем инструментальная программа должна быть запущена на образцах данных и впоследствии она запишет в файл данные профилирования.
  2. Затем программа снова собирается, на этот раз подавая собранные данные профилирования обратно в rustc с помощью флага -C profile-use. Эта сборка будет использовать собранные данные, чтобы позволить компилятору принимать лучшие решения о размещении кода, встраивании и других оптимизациях.

Для получения более подробной информации о Profile-Guided Optimization смотрите соответствующую главу в книге по компилятору rustc [10].

Выбор исполняемого файла в Cargo проектах

cargo run [11] является весьма удобным инструментом для быстрого тестирования консольных приложений. Когда в одном пакете присутствует несколько исполняемых файлов, необходимо явно объявить имя того исполняемого файла, который вы хотите запустить при помощи флага --bin. Это делает cargo run не таким эргономичным, как хотелось бы, особенно когда определённый исполняемый файл вызывается чаще, чем другие.

Rust 1.37.0 решает данную проблему путём добавления нового ключа default-run [12] в Cargo.toml (секция [package]). Таким образом, при необнаружении флага --bin, Cargo запустит двоичный файл, объявленный в конфигурации.

#[repr(align(N))] для перечислений

Начиная с Rust 1.37.0, атрибут #[repr(align(N))] [13] может быть использован для определения выравнивания [14] перечислений в памяти (ранее данный атрибут был разрешён только для структур (struct) и объединений (union)). Например, перечисление Align16 будет, как и ожидалось, иметь выравнивание в 16 байт, тогда как естественное выравнивание без #[repr(align(16))] будет 4:

#[repr(align(16))]
enum Align16 {
    Foo { foo: u32 },
    Bar { bar: u32 },
}

Семантика использования #[repr(align(N)) для перечислений такая же, как определение обёртки для структуры AlignN<T> с этим выравниванием, а затем использование AlignN<MyEnum>:

#[repr(align(N))]
struct AlignN<T>(T);

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

Rust 1.37.0 стабилизировал следующие компоненты стандартной библиотеки:

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

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

Участники 1.37.0

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

Новые спонсоры инфраструктуры Rust

Мы хотели бы поблагодарить двух новых спонсоров инфраструктуры Rust, предоставивших ресурсы, необходимых для создания Rust 1.37.0: Amazon Web Services (AWS) and Microsoft Azure:

  • AWS предоставили хостинг [27] для артефактов выпуска (компиляторы, библиотеки, инструменты и исходный код), дали доступ до этих артефактов пользователям через CloudFront, предотвратили регрессии на EC2 с Crater и управляли другой инфраструктурой, связанной с Rust, размещённой на AWS.
  • Для чрезвычайно ресурсоёмкого тестирования репозитория rust-lang/rust Microsoft Azure предоставила сборщики.

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

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

Данную статью совместными усилиями перевели andreevlex [30], ozkriff [31], funkill [32] и Gymmasssorla [33].

Автор: Gymmasssorla

Источник [34]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/open-source/327172

Ссылки в тексте:

[1] публикации: https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html

[2] Rust: https://www.rust-lang.org/

[3] установить его: https://www.rust-lang.org/install.html

[4] подробные примечания к выпуску: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1370-2019-08-15

[5] отчёте о стабилизации: https://github.com/rust-lang/rust/pull/61682/#issuecomment-502472847

[6] отдельного пакета: https://crates.io/crates/cargo-vendor

[7] неименованную (unnamed) константу (const): https://github.com/rust-lang/rust/pull/61347/

[8] Profile-Guided Optimization (PGO): https://github.com/rust-lang/rust/pull/61268/

[9] Profile-Guided Optimization: https://en.wikipedia.org/wiki/Profile-guided_optimization

[10] в книге по компилятору rustc: https://doc.rust-lang.org/rustc/profile-guided-optimization.html

[11] cargo run: https://doc.rust-lang.org/cargo/commands/cargo-run.html

[12] default-run: https://doc.rust-lang.org/cargo/reference/manifest.html#the-default-run-field

[13] #[repr(align(N))]: https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers

[14] выравнивания: https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment

[15] BufReader::buffer: https://doc.rust-lang.org/std/io/struct.BufReader.html#method.buffer

[16] BufWriter::buffer: https://doc.rust-lang.org/std/io/struct.BufWriter.html#method.buffer

[17] Cell::from_mut: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.from_mut

[18] Cell::as_slice_of_cells: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_slice_of_cells

[19] DoubleEndedIterator::nth_back: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.nth_back

[20] Option::xor: https://doc.rust-lang.org/std/option/enum.Option.html#method.xor

[21] {i,u}{8,16,64,128,size}::reverse_bits: https://doc.rust-lang.org/std/primitive.u8.html#method.reverse_bits

[22] Wrapping::reverse_bits: https://doc.rust-lang.org/std/num/struct.Wrapping.html#method.reverse_bits

[23] slice::copy_within: https://doc.rust-lang.org/std/primitive.slice.html#method.copy_within

[24] пакетный менеджер Cargo: https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-137-2019-08-15

[25] анализатор Clippy: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-137

[26] спасибо!: https://thanks.rust-lang.org/rust/1.37.0/

[27] хостинг: https://www.reg.ru/?rlink=reflink-717

[28] русскоязычном Телеграм-чате: https://t.me/rustlang_ru

[29] чате для новичковых вопросов: https://t.me/rust_beginners_ru

[30] andreevlex: https://habr.com/ru/users/andreevlex/

[31] ozkriff: https://habr.com/ru/users/ozkriff/

[32] funkill: https://habr.com/ru/users/funkill/

[33] Gymmasssorla: https://habr.com/ru/users/gymmasssorla/

[34] Источник: https://habr.com/ru/post/463823/?utm_campaign=463823&utm_source=habrahabr&utm_medium=rss