Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2024-05-02-Rust-1.78.0.md #136

Merged
merged 7 commits into from
May 3, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions ru/announcements/2024-05-02-Rust-1.78.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
---
layout: post
title: Анонс Rust 1.78.0
author: The Rust Release Team
release: 'true'
---

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

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

```console
$ rustup update stable
```

Если у вас ещё не установлен `rustup`, вы можете установить его с [соответствующей страницы](https://www.rust-lang.org/install.html) нашего веб-сайта, а также посмотреть [подробные примечания к выпуску](https://doc.rust-lang.org/nightly/releases.html#version-1780-2024-05-02) на GitHub.

Если вы хотите помочь нам протестировать будущие выпуски, вы можете использовать канал beta (`rustup default beta`) или nightly (`rustup default nightly`). Пожалуйста, [сообщайте](https://github.com/rust-lang/rust/issues/new/choose) обо всех встреченных вами ошибках.

## Что стабилизировано в 1.78.0

### Диагностические атрибуты

Теперь Rust поддерживает пространство имён атрибута `#[diagnostic]`, что позволяет влиять на сообщения ошибок компилятора. Теперь они рассматриваются как подсказки, которые компилятору *не требуется* использовать, а также больше не является ошибкой предоставление диагностики, которую компилятор не распознаёт. Такая гибкость позволяет исходному коду предоставлять диагностику, даже если она не поддерживается всеми компиляторами, будь то разные версии или совершенно разные реализации языка.
funkill marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Теперь Rust поддерживает пространство имён атрибута `#[diagnostic]`, что позволяет влиять на сообщения ошибок компилятора. Теперь они рассматриваются как подсказки, которые компилятору *не требуется* использовать, а также больше не является ошибкой предоставление диагностики, которую компилятор не распознаёт. Такая гибкость позволяет исходному коду предоставлять диагностику, даже если она не поддерживается всеми компиляторами, будь то разные версии или совершенно разные реализации языка.
Теперь Rust поддерживает пространство имён атрибута `#[diagnostic]`, что позволяет влиять на сообщения об ошибках компилятора. Теперь они рассматриваются как подсказки, которые компилятору *не требуется* использовать, а также больше не является ошибкой предоставление диагностики, которую компилятор не распознаёт. Такая гибкость позволяет исходному коду предоставлять диагностику, даже если она не поддерживается всеми компиляторами, будь то разные версии или совершенно разные реализации языка.


В этом пространстве имён появляется первый поддерживаемый атрибут `#[diagnostic::on_unimplemented]`, который можно поместить на типаж для настройки сообщения, в котором этот типаж требуется, но не реализован у типа. Рассмотрим пример, приведённый в [запросе на стабилизацию](https://github.com/rust-lang/rust/pull/119888/):
funkill marked this conversation as resolved.
Show resolved Hide resolved

```rust
#[diagnostic::on_unimplemented(
message = "My Message for `ImportantTrait<{A}>` is not implemented for `{Self}`",
label = "My Label",
note = "Note 1",
note = "Note 2"
)]
trait ImportantTrait<A> {}

fn use_my_trait(_: impl ImportantTrait<i32>) {}

fn main() {
use_my_trait(String::new());
}
```

Ранее компилятор выдал бы такую ​​встроенную ошибку:

```
error[E0277]: the trait bound `String: ImportantTrait<i32>` is not satisfied
--> src/main.rs:12:18
|
12 | use_my_trait(String::new());
| ------------ ^^^^^^^^^^^^^ the trait `ImportantTrait<i32>` is not implemented for `String`
| |
| required by a bound introduced by this call
|
```

Теперь с помощью `#[diagnostic::on_unimplemented]` пользовательское сообщение заполняет основную строку ошибки, а пользовательская метка помещается в исходный вывод. Исходная метка по-прежнему записывается как справочная информация, а также записываются все пользовательские примечания (эти данные могут быть изменены).

```
error[E0277]: My Message for `ImportantTrait<i32>` is not implemented for `String`
--> src/main.rs:12:18
|
12 | use_my_trait(String::new());
| ------------ ^^^^^^^^^^^^^ My Label
| |
| required by a bound introduced by this call
|
= help: the trait `ImportantTrait<i32>` is not implemented for `String`
= note: Note 1
= note: Note 2
```

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

```rust
#[diagnostic::on_unimplemented(
message = "the size for values of type `{Self}` cannot be known at compilation time",
label = "doesn't have a size known at compile-time"
)]
pub trait Sized {}
```

Дополнительные сведения смотрите в справочном разделе [инструмент `diagnostic` пространства имён атрибутов](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace).
funkill marked this conversation as resolved.
Show resolved Hide resolved

### Проверка предусловий `unsafe`

Стандартная библиотека Rust содержит ряд утверждений для предварительных условий `unsafe` функций, но исторически они были включены только в сборках стандартной библиотеки при помощи `#[cfg(debug_assertions)]`, чтобы избежать влияния на производительность release сборки. Однако, поскольку стандартная библиотека обычно компилируется и распространяется с release профилем, большинство разработчиков Rust вообще никогда не выполняют эти проверки.

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

Например, [`slice::from_raw_parts`](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html) требует выровненный ненулевой указатель. Следующее использование намеренно смещённого указателя приводит к неопределённому поведению и, хотя это может не иметь очевидных последствий, debug-проверка теперь может перехватить его:

```rust
fn main() {
let slice: &[u8] = &[1, 2, 3, 4, 5];
let ptr = slice.as_ptr();

// Создание отступа от `ptr` что всегда будет единственным отличием от корректного смещения `u16`
let i = usize::from(ptr as usize & 1 == 0);

let slice16: &[u16] = unsafe { std::slice::from_raw_parts(ptr.add(i).cast::<u16>(), 2) };
dbg!(slice16);
}
```

```
thread 'main' panicked at library/core/src/panicking.rs:220:5:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.
```

### Детерминированное повторное выравнивание

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

- [`pointer::align_offset`](https://doc.rust-lang.org/std/primitive.pointer.html#method.align_offset) вычисляет смещение, необходимое для изменения указателя на заданное выравнивание. Эта функция возвращает `usize::MAX`, если смещение невозможно, хотя раньше ей было разрешено *всегда* возвращать `usize::MAX`. Теперь такое поведение удалено.

- Функции [`slice::align_to`](https://doc.rust-lang.org/std/primitive.slice.html#method.align_to) и [`slice::align_to_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.align_to_mut) преобразуют срезы в выровненный срез средней части данных и невыровненные головной и хвостовой. Теперь они обещают возвращать максимально возможную среднюю часть — вместо того, чтобы позволять реализации возвращать что-то менее оптимальное. Например, возвращать всё в виде головного среза.

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

- [`impl Read for &Stdin`](https://doc.rust-lang.org/stable/std/io/struct.Stdin.html#impl-Read-for-%26Stdin)
- [В зависимости от реализации разрешены не-`'static` времена жизни для некоторых `std::error::Error`](https://github.com/rust-lang/rust/pull/113833/)
- [`impl<Fd: AsFd>` имплементирует `?Sized`](https://github.com/rust-lang/rust/pull/114655/)
- [`impl From<TryReserveError> for io::Error`](https://doc.rust-lang.org/stable/std/io/struct.Error.html#impl-From%3CTryReserveError%3E-for-Error)

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

- [`Barrier::new()`](https://doc.rust-lang.org/stable/std/sync/struct.Barrier.html#method.new)

### Замечания о совместимости

- Как [ранее анонсировалось](https://blog.rust-lang.org/2024/02/26/Windows-7.html), в Rust 1.78 поднимается минимальное требование до Windows 10 для следующих целевых платформ:
- `x86_64-pc-windows-msvc`
- `i686-pc-windows-msvc`
- `x86_64-pc-windows-gnu`
- `i686-pc-windows-gnu`
- `x86_64-pc-windows-gnullvm`
- `i686-pc-windows-gnullvm`
- В Rust 1.78 обновлён встроенный LLVM до версии 18, завершено изменение ABI для [`u128`/`i128`](https://blog.rust-lang.org/2024/03/30/i128-layout-update.html) для x86-32 и x86-64 платформ. Дистрибьюторы, которые используют свою собственную LLVM старше 18 лет, всё ещё могут сталкиваться с ошибками в соглашении о вызовах, упомянутыми в этом посте.

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

Проверьте всё, что изменилось в [Rust](https://github.com/rust-lang/rust/releases/tag/1.78.0), [Cargo](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-178-2024-05-02) и [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-178).

## Кто работал над 1.78.0

Многие люди собрались вместе, чтобы создать Rust 1.78.0. Без вас мы бы не справились. [Спасибо!](https://thanks.rust-lang.org/rust/1.78.0/)
Loading