Rust 1.85.0 и Rust 2024

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

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


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


$ rustup update stable

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


Если вы хотите помочь нам протестировать будущие выпуски, вы можете использовать канал beta (rustup default beta) или nightly (rustup default nightly). Пожалуйста, сообщайте обо всех встреченных вами ошибках.


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


Rust 2024


Мы рады сообщить, что редакция Rust 2024 теперь стабильна! Редакции — это наш механизм для внесения крупных изменений в язык, которые могут привести к нарушению обратной совместимости. Смотрите руководство по редакциям для общей информации о том, как это работает, и получения подробных инструкций по переносу.


Это самая крупная редакция, которую мы когда-либо выпускали. Подробная информация обо всех изменениях содержится в руководстве по редакциям, а здесь мы предоставим краткую выдержку:


  • Язык
    • RPIT lifetime capture rules — изменили захват параметров по умолчанию с помощью impl Trait типов, когда отсутствует use<..>.
    • Временная область if let — изменили область временных значений для выражений if let.
    • Временная область действия последнего выражения — изменили область действия временных параметров для последних выражений в блоке.
    • Соблюдение требований эргономики — запретили некоторые комбинации шаблонов, чтобы избежать путаницы и обеспечить возможность будущих улучшений.
    • Небезопасные extern-блоки — extern блоки теперь требуют ключевое слово unsafe.
    • Небезопасные атрибуты — атрибуты export_name, link_section и no_mangle теперь должны быть помечены как unsafe.
    • Предупреждение unsafe_op_in_unsafe_fn — проверка unsafe_op_in_unsafe_fn теперь по умолчанию предупреждающая и требует явных блоков unsafe {} в unsafe-функции.
    • Запрет ссылки на static mut — ссылки на static mut теперь запрещены по умолчанию и генерируют ошибку.
    • Изменение поведения приведения типа Never к любому другому — изменили способ принудительного вывода !, а также меняет поведение проверки never_type_fallback_flowing_into_unsafe на запрещающее.
    • Спецификаторы фрагмента макроса — спецификатор фрагмента макроса expr в macro_rules! теперь также соответствует выражениям const и _.
    • Отсутствующие спецификаторы фрагмента макроса — проверка missing_fragment_specifier теперь вызывает серьёзную ошибку, отклоняющую мета-переменные макроса без указания типа спецификатора фрагмента.
    • Ключевое слово gen — ключевое слово gen зарезервировано в ожидании добавления в будущем блоков генераторов.
    • Зарезервированный синтаксис строк — зарезервировали строки стиля #"foo"# и токены ## в ожидании изменения способа анализа защищённых строковых литералов в будущем.
  • Стандартная библиотека
    • Изменения в прелюдии — добавили в прелюдию Future и IntoFuture.
    • Добавили IntoIterator для Box<[T]> — изменили способ работы итераторов со срезами в куче.
    • Новые unsafe-функции — std::env::set_var, std::env::remove_var и std::os::unix::process::CommandExt::before_exec теперь являются небезопасными функциями.
  • Cargo
    • Cargo: распознаватель, учитывающий версию Rust — изменили поведение распознавателя зависимостей по умолчанию, теперь он учитывает поле rust-version.
    • Cargo: согласованность имён таблиц и ключей — удалили некоторые устаревшие ключи Cargo.toml.
    • Cargo: отклонение неиспользуемых унаследованных default-features — изменили способ работы default-features = false с унаследованными зависимостями рабочей области.
  • Rustdoc
    • Комбинированные тесты Rustdoc — документационные тесты теперь объединены в один исполняемый файл, что значительно повышает производительность.
    • Rustdoc: изменение вложенных include! — изменение относительного пути ко вложенным файлам include!.
  • Rustfmt
    • Rustfmt: стили редакций — представляем концепцию "стилей редакций", которая позволяет независимо управлять форматированием с учётом редакции Rust.
    • Rustfmt: исправления форматирования — большое количество исправлений для форматирования различных ситуаций.
    • Rustfmt: сортировка необработанных идентификаторов — изменили способ сортировки идентификаторов r#foo.
    • Rustfmt: сортировка по версиям — изменили способ сортировки идентификаторов, содержащих целые числа.

Переход на редакцию 2024


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


Обратите внимание, что автоматические исправления с помощью cargo fix очень консервативны и будут избегать изменения семантики вашего кода. Во многих случаях вы захотите сохранить свой код прежним, используя при этом новую семантику Rust 2024. Например, продолжая использовать средство сопоставления макросов expr и игнорируя преобразования условных выражений, потому что вам нужна новая семантика порядка выполнения Drop. Результат cargo fix не следует рассматривать как рекомендацию, это просто консервативное преобразование, которое сохраняет поведение.


Над созданием этого издания работало множество людей. Мы хотели бы поблагодарить их всех за усердную работу!


async closures


Rust теперь поддерживает асинхронные замыкания, такие как async ||{}, которые при вызове возвращают футуры. Они работают подобно async fn, которые также могут захватывать значения из локальной среды. Разница между ними точно такая же, как между обычными замыканиями и функциями. Эта функциональность также включает в себя 3 аналогичных трейта в прелюдии стандартной библиотеки: AsyncFn, AsyncFnMut и AsyncFnOnce.


В некоторых случаях вы могли создать нечто подобное с помощью обычного замыкания и асинхронного блока, например || async {} — но футура, возвращаемая таким внутренним блоком, не может быть заимствована из перехватов замыкания. Однако это работает с async-замыканиями:


let mut vec: Vec<String> = vec![];

let closure = async || {
    vec.push(ready(String::from("")).await);
};

Также было невозможно правильно выразить сигнатуры функций более высокого ранга с помощью трейтов Fn, возвращающих Future. Впрочем, вы могли сделать это с помощью трейтов AsyncFn:


use core::future::Future;
async fn f<Fut>(_: impl for<'a> Fn(&'a u8) -> Fut)
where
    Fut: Future<Output = ()>,
{ todo!() }

async fn f2(_: impl for<'a> AsyncFn(&'a u8))
{ todo!() }

async fn main() {
    async fn g(_: &u8) { todo!() }
    f(g).await;
    //~^ ERROR mismatched types
    //~| ERROR one type is more general than the other

    f2(g).await; // ok!
}

Таким образом, async-замыкания предоставляют первоклассные решения для обеих этих проблем! Более подробную информацию смотрите в RFC 3668 и в отчёте о стабилизации.


Скрытие реализаций трейтов от диагностики


Новый атрибут #[diagnostic::do_not_recommend] является подсказкой компилятору не показывать аннотированную реализацию трейта как часть диагностического сообщения. Для авторов библиотек это способ уберечь компилятор от внесения предложений, которые могут оказаться бесполезными или вводящими в заблуждение. Например:


pub trait Foo {}
pub trait Bar {}

impl<T: Foo> Bar for T {}

struct MyType;

fn main() {
    let _object: &dyn Bar = &MyType;
}

error[E0277]: the trait bound `MyType: Bar` is not satisfied
 --> src/main.rs:9:29
  |
9 |     let _object: &dyn Bar = &MyType;
  |                             ^^^^ the trait `Foo` is not implemented for `MyType`
  |
note: required for `MyType` to implement `Bar`
 --> src/main.rs:4:14
  |
4 | impl<T: Foo> Bar for T {}
  |         ---  ^^^     ^
  |         |
  |         unsatisfied trait bound introduced here
  = note: required for the cast from `&MyType` to `&dyn Bar`

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


#[diagnostic::do_not_recommend]
impl<T: Foo> Bar for T {}

error[E0277]: the trait bound `MyType: Bar` is not satisfied
  --> src/main.rs:10:29
   |
10 |     let _object: &dyn Bar = &MyType;
   |                             ^^^^ the trait `Bar` is not implemented for `MyType`
   |
   = note: required for the cast from `&MyType` to `&dyn Bar`

Смотрите RFC 2397, чтобы узнать первоначальную мотивацию изменения и текущий reference для получения более подробных деталей.


FromIterator и Extend для кортежей


В более ранних версиях Rust были реализованы удобные функции для итераторов из пар кортежей (T, U), которые вели себя как Iterator::unzip, с Extend в версии 1.56 и FromIterator в версии 1.79. Теперь они были расширены для большего количества кортежей, начиная с одноэлементного (T,) и заканчивая кортежами длиной в 12 элементов, (T1, T2, .., T11, T12). Например, теперь вы можете использовать collect() для создания нескольких коллекций одновременно:


use std::collections::{LinkedList, VecDeque};
fn main() {
    let (squares, cubes, tesseracts): (Vec<_>, VecDeque<_>, LinkedList<_>) =
        (0i32..10).map(|i| (i * i, i.pow(3), i.pow(4))).collect();
    println!("{squares:?}");
    println!("{cubes:?}");
    println!("{tesseracts:?}");
}

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
[0, 1, 16, 81, 256, 625, 1296, 2401, 4096, 6561]

Обновления в std::env::home_dir()


std::env::home_dir() уже много лет считается устаревшим, поскольку может давать неожиданные результаты в некоторых конфигурациях Windows, когда установлена переменная среды HOME (что не является ситуацией по умолчанию). Ранее мы избегали изменений этой функции из-за вопросов совместимости с кодом, зависящим от этой нестандартной конфигурации. Но, учитывая, как долго эта функция была устаревшей, мы сейчас обновляем её поведение заодно с исправлением других ошибок, так что в следующих выпусках она больше не будет помечена устаревшей.


Стабилизированные API


  • BuildHasherDefault::new
  • ptr::fn_addr_eq
  • io::ErrorKind::QuotaExceeded
  • io::ErrorKind::CrossesDevices
  • {float}::midpoint
  • Беззнаковые {integer}::midpoint
  • NonZeroU*::midpoint
  • impl std::iter::Extend для кортежей с размерностью от 1 до 12
  • FromIterator<(A, ...)> для кортежей с размерностью от 1 до 12
  • std::task::Waker::noop

Следующие API теперь можно использовать в контексте const:


  • mem::size_of_val
  • mem::align_of_val
  • Layout::for_value
  • Layout::align_to
  • Layout::pad_to_align
  • Layout::extend
  • Layout::array
  • std::mem::swap
  • std::ptr::swap
  • NonNull::new
  • HashMap::with_hasher
  • HashSet::with_hasher
  • BuildHasherDefault::new
  • <float>::recip
  • <float>::to_degrees
  • <float>::to_radians
  • <float>::max
  • <float>::min
  • <float>::clamp
  • <float>::abs
  • <float>::signum
  • <float>::copysign
  • MaybeUninit::write

Прочие изменения


Проверьте всё, что изменилось в Rust, Cargo и Clippy.


Кто работал над 1.85.0


Многие люди собрались вместе, чтобы создать Rust 1.85.0. Без вас мы бы не справились. Спасибо!


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


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

Источник: https://habr.com/ru/articles/884770/


Интересные статьи

Интересные статьи

Начнем с небольшого предисловия. Битрикс24 позволяет автоматизировать множество разных процессов внутри компании. В частности в Битрикс есть большой и сильный блок автоматизации процессов работы с кли...
Самый действенный способ изучить фреймворк — написать пет-проект. Например, свою социальную платформу на Django. Во время реализации можно попрактиковаться в работе с формами, представлениями, сигна...
Привет, Хабр!В этой статье представлен алгоритм быстрого поиска подграфов, изоморфных заданному, рассматриваются только направленные графы.Сначала будет приведён алгоритм поиска паттернов рекуррентным...
Автокэширование в 1с-Битрикс — хорошо развитая и довольно сложная система, позволяющая в разы уменьшить число обращений к базе данных и ускорить выполнение страниц.
Как обновить ядро 1С-Битрикс без единой секунды простоя и с гарантией работоспособности платформы? Если вы не можете закрыть сайт на техобслуживание, и не хотите экстренно разворачивать сайт из бэкапа...