Rust 1.16

2 года ago admin 0

Представлен релиз Rust 1.16 — системного языка программирования, нацеленного на безопасную работу с ресурсами, скорость и параллельное выполнение кода. В этот релиз вошли 1364 патча от 137 разработчиков.

Если у вас уже установлена предыдущая версия Rust, то обновиться до Rust 1.16 очень легко:

$ rustup update stable

Самое крупное нововведение в Rust 1.16 — новая субкоманда cargo check направленная на ускорение процесса разработки.

Что она делает? Давайте рассмотрим как rustc компилирует код. Компиляция происходит в несколько проходов, шагов от исходного кода до исполняемого файла. Все эти шаги (и затраченные на них ресурсы) можно увидеть, передав компилятору ночной ветки -Z time-passes

rustc .hello.rs -Z time-passes
time: 0.003; rss: 16MB  parsing
time: 0.000; rss: 16MB  recursion limit
time: 0.000; rss: 16MB  crate injection
time: 0.000; rss: 16MB  plugin loading
time: 0.000; rss: 16MB  plugin registration
time: 0.049; rss: 34MB  expansion

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

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

  • Пишем немного кода.
  • Запускаем cargo build, чтобы проверить, что код компилируется.
  • Повторяем предыдущие шаги N раз.
  • Запускаем cargo test, чтобы убедиться, что все тесты проходят успешно.
  • Возвращаемся в начало.

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

Другие улучшения

Для работы cargo check компилятор научился генерировать новый формат файлов: .rmeta. Такие файлы содержат метаданные о каком-либо одном крейте. cargo check использует эти данные для анализа зависимостей проекта и позволяет компилятору сделать проверки типов из сторонних библиотек.

Удалена диагностика consider using an explicit lifetime parameter, появляющаяся если в коде были использованы неправильные аннотации времени жизни. Рассмотрим пример:

use std::str::FromStr;
pub struct Name<'a> {
    name: &'a str,
}
impl<'a> FromStr for Name<'a> {
    type Err = ();
    fn from_str(s: &str) -> Result<Name, ()> {
        Ok(Name { name: s })
    }
}

Здесь компилятор не уверен, что делать с временем жизни: код не гарантирует что s проживет столько же, сколько Name, как того требуется. Компилятор Rust 1.15 выведет:

> rustc +1.15.1 foo.rs --crate-type=lib
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements
  --> .foo.rs:10:5
   |
10 |       fn from_str(s: &str) -> Result<Name, ()> {
   |  _____^ starting here...
11 | |         Ok(Name { name: s })
12 | |     }
   | |_____^ ...ending here
   |
help: consider using an explicit lifetime parameter as shown: fn from_str(s: &'a str) -> Result<Name, ()>
  --> .foo.rs:10:5
   |
10 |       fn from_str(s: &str) -> Result<Name, ()> {
   |  _____^ starting here...
11 | |         Ok(Name { name: s })
12 | |     }
   | |_____^ ...ending here

Компилятор описывает проблему и дает рекомендации по исправлению. Модифицируем код согласно им и пробуем снова:

> rustc +1.15.1 .foo.rs --crate-type=lib
error[E0308]: method not compatible with trait
  --> .foo.rs:10:5
   |
10 |       fn from_str(s: &'a str) -> Result<Name, ()> {
   |  _____^ starting here...
11 | |         Ok(Name { name: s })
12 | |     }
   | |_____^ ...ending here: lifetime mismatch
   |
help: consider using an explicit lifetime parameter as shown: fn from_str(s: &'a str) -> Result<Name<'a>, ()>
  --> .foo.rs:10:5
   |
10 |       fn from_str(s: &'a str) -> Result<Name, ()> {
   |  _____^ starting here...
11 | |         Ok(Name { name: s })
12 | |     }
   | |_____^ ...ending here

Всё ещё не работает. Предлагается добавить еще одно время жизни, на этот раз для Name

> rustc +1.15.1 .foo.rs --crate-type=lib
help: consider using an explicit lifetime parameter as shown: fn from_str(s: &'a str) -> Result<Name<'a>, ()>
  --> .foo.rs:10:5

…и наконец код скомпилировался.

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

Есть и другие изменения, касающиеся диагностик. Предыдущая версия Rust уже научилась предлагать исправления опечаток:

let foo = 5;
println!("{}", ffo)
error[E0425]: cannot find value `ffo` in this scope
 --> foo.rs:4:20
  |
4 |     println!("{}", ffo);
  |                    ^^^ did you mean `foo`?

Но это происходило только для опечаток в локальных переменных и полей в структурах. Сейчас Rust предлагает исправления опечаток почти везде.

Стабилизация библиотек

Также стабилизированы некоторые мелкие улучшения:

  • writeln! теперь можно вызывать без аргументов, как println!, для перевода строки.
  • Все структуры в стандартной библиотеке теперь реализуют Debug

Улучшен формат ошибок при получении среза &str. Например:

&"abcαβγ"[..4]

Этот код содержит ошибку:

thread 'str::test_slice_fail_boundary_1' panicked at 'byte index 4 is not
a char boundary; it is inside 'α' (bytes 3..5) of `abcαβγ`

Часть после ; — новая.

Возможности Cargo

Дополнительно к cargo check, Cargo и crates.io получили пару новых возможностей.

  • cargo build и cargo doc теперь принимают флаг --all для сборки и документации всех крейтов в рабочем пространстве одной командой.
  • Cargo теперь принимает флаги --version --verbose, по образу rustc.
  • Crates.io может отображать значки AppVeyor и TravicCI на странице крейта.
  • В Cargo и crates.io появились категории. В отличие от ключевых слов, категории модерируются. Ключевые слова используются для поиска, категории — нет. Другими словами, ключевые слова помогают искать крейты, а категории — просматривать.
  • На crates.io теперь можно просматривать крейты по категориям.

Больше информации можно узнать в развернутых release notes.

>>> Подробности


Source: linux.org.ru