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

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


    Введение


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


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


    $ rustup update stable

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


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


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


    Ссылки на варианты перечисления (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. Более подробное описание доступно в отчёте о стабилизации.


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


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


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


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


    Теперь вы можете создавать неименованную (unnamed) константу (const), подменив её идентификатор подчёркиванием (_). Например, в компиляторе 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), которую можно включить через флаги компилятора -C profile-generate и -C profile-use.


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


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

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


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


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


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


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


    Начиная с Rust 1.37.0, атрибут #[repr(align(N))] может быть использован для определения выравнивания перечислений в памяти (ранее данный атрибут был разрешён только для структур (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 стабилизировал следующие компоненты стандартной библиотеки:



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


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


    Участники 1.37.0


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


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


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


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

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


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


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

    Поддержать автора
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 14

      +3

      Неплохой релиз! Среди прочего особенно приятно видеть инфраструктурных спонсоров для Rust :)

        +1
        Да. С такими спонсорами можно быть спокойным за будущее Rust.
          +1

          Ну да, съехали с Travis+AppVeyor потому что перестали влезать в 3-часовой лимит. Осталось всего лишь дождаться, когда билд и в Azure влезать перестанет. Как-то я не очень спокоен за будущее Rust в этом плане.

            +1

            А как гуглохромы тогда тестируют?

        +6

        Недавно пробовал вернуться в C++ (хочу написать маленькую игрушку), но понял что он на каком месте был лет 10 назад, на таком и остался. Пакетные менеджеры в него так и не пришли. За целостность проекта следить приходится ручками… В итоге решил посмотреть на rust. Первое впечатление — очень круто, моим запросом пока удовлетворяет. Библиотеки свежии. Вендоринг официальный подъехал.

          +1
          Для C++ есть два хороших менеджера пакетов: conan и vcpkg.
            +1
            Да, есть, но по удобству сильно уступает npm и pip. Cargo тоже будет поудобнее в некоторых моментов чем тот же vcpkg. К тому же, когда я последний раз пользовался vcpkg у него явно была проблема с поддержкой т.к. многие разработчики на C++, с которыми я общался, считают что должен быть только один пакетный менеджер — системный (WTF???)
          –1
          новых спонсоров инфраструктуры Rust, предоставивших ресурсы, необходимых для создания Rust 1.37.0: Amazon Web Services (AWS) и Microsoft Azure

          Не первый раз уже вижу MS в списке контрибьюторов раста, кто-нибудь объяснит, какой у них здесь коммерческий интерес?


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


          Crates.io требует Github аккаунта и вообще Cargo гвоздями прибит к Github. Rust-doc построен на HTML+JS (тк там есть динамические фичи, например поиск) и справка очень жирная, у меня каталог /usr/share/doc/rust-doc занимает почти 300 Мб. Чат разработчиков идёт в Telegram (привет проприетарщина с идентификацией по номеру телефона). Теперь вот завязывание инфраструктуры тестов на azure и aws. Был бы я управленцем MS, я бы точно теперь попытался пропихнуть в cargo что-нибудь вроде команд для развёртывания в azure.

            0
            где-то читал что Microsoft говорили что ~70% проблем безопасности связаны с безопасностью использования памяти
            +4
            кто-нибудь объяснит, какой у них здесь коммерческий интерес?

            Собственно, в основном, azure продвигать прямо и косвенно. Тут все прозрачно, кмк.


            Какие-то отделы экспериментально могут раст именно как яп использовать, но это вряд ли к текущему спонсорству отношение имеет.


            у такого крутого языка куча зависимостей от внешней инфраструктуры

            Этот вопрос там-сям всплывает периодически, но в целом аргументация растокоманды сводится к практичности и недостатку ресурсов.


            Crates.io требует Github аккаунта

            Это вот сюда — https://github.com/rust-lang/crates.io/issues/326 — старый вопрос. TLDR (как я его понимаю) в том, что это просто и практичное решение, которое устраивает абсолютное большинство текущих пользователей, а запилить свой независимый вариант так, что бы это точно не вышло боком — требует ресурсов и не так уж тривиально, поэтому отложено в бэклог.


            и вообще Cargo гвоздями прибит к Github

            Аналогично. Хотя надо упомянуть, на всякий, что желающие могут развернуть альтернативные регистры — https://doc.rust-lang.org/cargo/reference/registries.html — без всяких гитхабов.


            Rust-doc построен на HTML+JS (тк там есть динамические фичи, например поиск) и справка очень жирная, у меня каталог /usr/share/doc/rust-doc занимает почти 300 Мб

            А какой основной формат выдачи у генератора доков должен быть? Вроде как это ровно то, что нужно большинству пользователей. Что доки весят порядочно — ну да, не очень приятный момент, но стандартные, насколько помню, можно не выкачивать, а для своего проекта генерить, например, только для определенного набора зависимостей. Ну и хз, на фоне многогигабайтного веса target директории размер генеренных доков лично меня никогда не волновал))


            Чат разработчиков идёт в Telegram (привет проприетарщина с идентификацией по номеру телефона).

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


            Англоязычных средств общения тоже каких угодно хватает — как проприетарного дискорда, так и все еще живой ирки, открытого zulip, discourse'овых URLO/IRLO и т.п.


            Теперь вот завязывание инфраструктуры тестов на azure и aws.

            Ну, я так понимаю, это опять же вопрос доступных ресурсов. Было бы доступно свое железо в нужном количестве — строили бы все независимое, но денег на это нету.


            я бы точно теперь попытался пропихнуть в cargo что-нибудь вроде команд для развёртывания в azure

            В сам cargo сильно вряд ли выйдет, но вот удобное расширение cargo наверняка будет (или даже уже есть? надо прогуглить это дело).

              0

              Интересно, а openid уже совсем умер?


              Кстати, можно наверное сделать какой-нибудь легковесный генератор доков, который их будет в виде пачки md файлов делать, правда тогда полетят линки в доке.

                0

                Стандартные линки можно опознавать и исправлять соответственно новой адресации — это не должно оказаться сложной задачей.

              0

              Да вы и без Microsoft вполне сможете написать расширение для cargo которое будет это делать. Называешь крейт cargo-mystuff, ставишь в .cargo/bin и можно делать cargo mystuff. А можно не запариваться и назвать его сразу mystuff ибо деплой в Azure едва ли требует какой-то особый доступ к компилятору или артефактам компиляции. AWS почти так и поступила

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое