Выпуск Rust 1.29 +34


Команда разработчиков Rust рада сообщить о выпуске новой версии Rust: 1.29.0. Rust — это системный язык программирования, нацеленный на безопасность, скорость и параллельное выполнение кода.


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


$ rustup update stable

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


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


1.29 привносит не очень много изменений. Ожидается что Rust 1.30 и 1.31 будут очень значительными, так что большая часть 1.29 итерации ушла на подготовку к будущим изменениям. Два самых заметных нововведения этого выпуска даже не касаются самого языка: это две новые возможности Cargo и обе они касаются предупреждений.


  • cargo fix автоматически исправляет предупреждения в коде
  • cargo clippy — статический анализатор Rust кода, помогающий поймать распространенные ошибки и просто улучшить код

cargo fix


С выпуском Rust 1.29 у Cargo появляется новая подкоманда: cargo fix. Если вы когда-либо писали на Rust, то скорее всего уже сталкивались с предупреждениями компилятора. Например, рассмотрим такой код:


fn do_something() {}

fn main() {
    for i in 0..100 {
        do_something();
    }
}

В нем мы вызываем do_something сто раз, но никогда не используем переменную i. Rust предупреждает нас об этом:


> cargo build
   Compiling myprogram v0.1.0 (file:///path/to/myprogram)
warning: unused variable: `i`
 --> src\main.rs:4:9
  |
4 |     for i in 1..100 {
  |         ^ help: consider using `_i` instead
  |
  = note: #[warn(unused_variables)] on by default

    Finished dev [unoptimized + debuginfo] target(s) in 0.50s

Видите подсказку о переименовании в _i? Мы можем автоматически применить ее при помощи cargo fix:


> cargo fix
    Checking myprogram v0.1.0 (file:///C:/Users/steve/tmp/fix)
      Fixing src\main.rs (1 fix)
    Finished dev [unoptimized + debuginfo] target(s) in 0.59s

Если теперь мы откроем src\main.rs, то увидим исправленный код:


fn do_something() {}

fn main() {
    for _i in 0..100 {
        do_something();
    }
}

Теперь в коде используется _i, и предупреждение больше не выдается.


Первая версия cargo fix исправляет далеко не все предупреждения. Для своей работы cargo fix использует специальный API компилятора, который предлагает исправлять только те предупреждения, в которых мы абсолютно уверены. Со временем их список будет расширяться.


cargo clippy


Еще о предупреждениях: теперь вы можете попробовать cargo-clippy через Rustup. Clippy это статический анализатор, который выполняет много дополнительных проверок вашего кода.


Например:


let mut lock_guard = mutex.lock();

std::mem::drop(&lock_guard)

operation_that_requires_mutex_to_be_unlocked();

Синтаксически это правильный код, но мы можем получить дедлок, потому что вызвали drop для _ссылки на lock_guard_, а не для самого lock_guard. Вызов drop для ссылки имеет мало смысла и почти наверняка является ошибкой.


Установим предварительную версию Clippy через Rustup:


$ rustup component add clippy-preview

и запустим ее:


$ cargo clippy
error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing.
 --> src\main.rs:5:5
  |
5 |     std::mem::drop(&lock_guard);
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[deny(drop_ref)] on by default
note: argument has type &std::result::Result<std::sync::MutexGuard<'_, i32>, std::sync::PoisonError<std::sync::MutexGuard<'_, i32>>>
 --> src\main.rs:5:20
  |
5 |     std::mem::drop(&lock_guard);
  |                    ^^^^^^^^^^^
  = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#drop_ref

Как видно из примечания к сообщению, вы можете получить полный список всех возможных предупреждений по ссылке.


Обратите внимание, что это только ознакомительная версия; Clippy еще не достиг 1.0, поэтому набор и поведение проверок еще могут меняться. Мы выпустим компонент clippy, как только он будет стабилизирован, а пока просим вас посмотреть на деле предварительную версию и рассказать нам о своем опыте.


Да, есть еще нюанс: к сожалению, пока что нельзя использовать clippy вместе с cargo-fix. Работа над этим ведется.


Подробности смотрите в примечаниях к выпуску.


Стабилизация стандартной библиотеки


В этом выпуске были стабилизированы следующие API:



Также, теперь вы можете сравнивать &str и OsString.


Подробности смотрите в примечаниях к выпуску.


Улучшения в Cargo


Выше мы уже описали две новые подкоманды Cargo. Также Cargo теперь будет автоматически пытаться починить Cargo.lock файлы, испорченные git mergeом. Это поведение можно отключить флагом --locked.


cargo doc обзавелся новым флагом: --document-private-items. По умолчанию, cargo doc документирует только публичные части API, потому что предназначен для генерации пользовательской документации. Но если вы работаете над своим пакетом и в нем есть внутренняя документация, то --document-private-items включит генерацию документации вообще для всего.


Подробности смотрите в примечаниях к выпуску.


Разработчики 1.29.0


Множество людей участвовало в разработке Rust 1.29. Мы не смогли бы завершить работу без участия каждого из вас. Спасибо!


От переводчика: Благодарю @Revertron за помощь в переводе.

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (24):

  1. inv2004
    /#19109015

    ещё обновили LLVM.

    • VadimVP
      /#19109913

      И procedural macro API стабилизировали.

      • ozkriff
        /#19110055

        steveklabnik1: 1.29 stabilizes parts of the proc_macro crate, but you can’t actually bring proc macros into scope without use, which was what I was referring to and lands in 1.30. As such we’re not really advertising the 1.29 stabilization broadly; it can be used by some crates, like serde, for better error messages, but that’s about it, making it minor enough for to not talk much about.

        Т.е. в текущей итерации стабилизации процедурные макросы еще почти бесполезны. Ждем стабилизации остальной нужной для их использования обвязки в 1.30, тогда и в новости про них расписано будет.

        • VadimVP
          /#19110217 / +1

          #[proc_macro_derive] давно стабилен и использует proc macro API, прямо или через инфраструктурные крейты типа syn/proc-macro2.
          До 1.29 всё делалось через строки, а 1.29 стабилизировал полноценное API для токенов, на которое все инфраструктурные крейты, например, сразу же перешли, это большое дело на самом деле.
          Обычно все добавления в библиотеку анонсируются, даже крошечные, а в этом случае начались какое-то маневры ?_(?)_/?

          • ozkriff
            /#19110453

            Как я это вижу:


            Это важное изменение, но пока только для авторов хардкорных библиотек. А они и так в курсе этих изменений, потому что точно следят за разработкой языка хотя бы на уровне чтения TWIRов.


            Посты же в официальном журнале Ржавчины, как я понимаю, ориентированы на максимально широкую аудиторию, включая тех кто вообще не сильно в язык погружен. Такой ЦА прямой пользы от вышеописанной стабилизации пока нет, а вот запутаться в объяснениях "это стабилизировано, но вот только такое, а тут надо через это, а вот это пока нельзя и вот тут три нюанса" — раз плюнуть.

  2. ozkriff
    /#19109027 / +1

    Rust 1.30 и 1.31 будут очень значительными

    Точного списка пока нет, но насколько я понял, ожидается что:





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

  3. kurojneko
    /#19109165

    Когда уже rust приедет на микроконтроллеры? Пока все что я нашел — это упоминание что раст можно компилировать под контроллеры и блог одного товарища, который с костылями и доработками это вроде как сделал… Может я не туда смотрю?

    • Misaka10032
      /#19109249

      ИМХО, чтобы rust приехал на МК — под него должны быть адаптированы популярные библиотеки. Пока не будут FreeRTOS и lwip заводиться без костылей — лично я и не подумаю переходить. Ибо толку, если я перейду, а все остальные разработчики на работе — нет?

      • VadimVP
        /#19109901 / +1

        Ибо толку, если я перейду, а все остальные разработчики на работе — нет?

        Эта проблема от платформы и библиотек не сильно зависит.
        "Остальные разработчики" в принципе редко хотять переходить на что-то другое если то что есть и так работает.

        • Misaka10032
          /#19119535

          «Остальные разработчики» в принципе редко хотять переходить на что-то другое если то что есть и так работает.

          Тут согласен, но дело в том, что прямо сейчас пересаживаться на Rust я тоже не вижу смысла, к своему сожалению.
          Начать пересаживаться на Rust сейчас — значит вывести разработчиков из рабочего процесса на… неопределённое время, учить язык и переписывать кодовую базу.
          Можно новые проекты начать потихоньку пилить на Rust, но… надо учить язык, а он окончательно ещё не устоялся.
          В итоге — для хобби, где время жизни проекта редко превышает год — сойдёт.
          Для кровавого энтерпрайза — извините, но пока что нет, как бы язык ни был хорош :(

          • ozkriff
            /#19120417

            переписывать кодовую базу

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


            По этой теме недавно доклад от разработчиков Tor'а был на растконфе:


            https://www.youtube.com/watch?v=WI4ApeHH9QE


            Это все раво не так просто как с самого начала проект на расте начать, конечно, но уже намного более реальный путь чем "просто берем и RIIR!!! переписываем разом весь код ржавчину", о котором многие думают в первую очередь.


            надо учить язык, а он окончательно ещё не устоялся

            Этот момент немного смутил. Если речь о том что какой-то конкретной вещи в языке еще не хатает (async/await того же) — может и имеет смысл подождать ее выпуска и стабилизации.


            Но в целом, 1.0 с гарантиями обратной совместимости давно уже вышел и однажды написанный корректный код так и продолжит работать, а какие-то доработки в язык так и будут вноситься до самой его смерти скорее всего.

    • ozkriff
      /#19109253 / +1

      rust-embedded/wg + rust-embedded/awesome-embedded-rust — тут вот довольно много ссылок есть как на библиотеки/инстурменты, так и на связанные ресурсы.


      Не так давно своими глазами видел живое демо на питерской сходке, процесс выглядел не сильно костыльно.

      • ozkriff
        /#19109315

        Из телеграма подсказывают:


        http://embedonomicon.rust-embedded.org/preface.html — небольшая дока чисто для понимания no_std и линковки.
        стоит почитать блог Japaric: https://blog.japaric.io/
        ну и как обычно, жапариковские крейты bare-metal, cortex-m, cortex-m-rt, stm32f103xx и так далее, там много полезного для себя можно откопать.
        https://github.com/m-labs/smoltcp — ip стек, но это для хардкорных парней уже

        "… блог одного товарища..." — Скорее всего это и есть журнал Japaric'а :)

        • kurojneko
          /#19109397

          Да, именно про этого шведа(кажется) я и говорил. По английски понимаю плохо, но из того что я понял, дабы запустить все это дело, надо очень сложный танец с бубном исполнить.
          Спасибо за ссылки, обязательно поковыряю )

    • TargetSan
      /#19109403

      Боюсь, весьма не скоро. Давеча общался с товарищем, который пилит прошивки для медтехники. Компилятор С самопальный от вендора, местами я так понимаю даже не ANSI. IDE — какая-то сборка на базе эклипса.

    • /#19111891 / +1

      Я год назад делал маленький проект, было плюс-минус без костылей (хотя, наверное, xargo можно за костыль посчитать). Всё компилировалось, прошивалось, отлаживалось, под STM32. По-моему, даже прямо из CLion-а у меня получалось отлаживать, но это не точно. gdb точно работал (или lldb? один из них :) ).

      Но там всё постоянно меняется — это один из рисков. С тех пор они там какие-то HAL-ы напилили — про это ничего не знаю.

      Моя оценка примерно такая:
      1) Для хобби — сойдёт (проекты относительно маленькие), если есть желание. Мне понравился мой опыт, причём это был мой первый проект на Rust.
      2) Для новых крупных проектов — если есть желание рискнуть, можно сделать ставку на Rust. Я слышал разные страшные истории от одного разработчика в одной всем известной компании про то, как у них низкоуровневый софт пишется (Raspberry PI, хотя это уже не совсем «микроконтроллер») — Rust бы там, как мне кажется, пришёлся бы в тему.
      3) Для средних проектов — не знаю, там, наверное, проще взять готовые библиотеки. Хотя с другой стороны, Rust хорошо встраивается в C, наверное, можно кусочно на Rust делать (но FFI — это вдвойне опасная тема).

  4. domix32
    /#19110093

    cargo fix будет фиксить различия 2018 edition?

  5. Zanak
    /#19111211

    Возможно плохо искал, но не увидел: планируется возможность увидеть список исправлений без накатывания cargo fix сразу на весь проект? Каким бы умным анализатор ни был, всегда есть место для сомнений.

    • ozkriff
      /#19111237

      Судя по наличию флагов


              --allow-no-vcs              Fix code even if a VCS was not detected                 
              --allow-dirty               Fix code even if the working directory is dirty  

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

      • Zanak
        /#19112339

        Наличие гита означает хорошие шансы не потерять проект, но про «сделать его лучше» речи не идет.

        • ozkriff
          /#19112627

          Почему не идет? Я теперь не уверен что понял изначальный вопрос.


          Вроде как мы запускаем rustfix, смотрим через git diff что он сделал — если не нравится, то откатываем или частично, или целиком до последнего комита репозитория.