Выпуск Rust 1.87

В день празднования десятилетия с момента выпуска языка программирования Rust 1.0 (проект Rust был основан в 2006 году, выпуск 0.1 был сформирован в 2012 году, а первая стабильная версия предложена в 2015 году) опубликован релиз Rust 1.87. Язык сфокусирован на безопасной работе с памятью и предоставляет средства для достижения высокого параллелизма выполнения заданий, при этом обходясь без использования сборщика мусора и runtime (runtime сводится к базовой инициализации и сопровождению стандартной библиотеки).

Методы работы с памятью в Rust избавляют разработчика от ошибок при манипулировании указателями и защищают от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п. Для распространения библиотек, обеспечения сборки и управления зависимостями проектом развивается пакетный менеджер Cargo. Для размещения библиотек поддерживается репозиторий crates.io.

Безопасная работа с памятью обеспечивается в Rust во время компиляции через проверку ссылок, отслеживание владения объектами, учёт времени жизни объектов (области видимости) и оценку корректности доступа к памяти во время выполнения кода. Rust также предоставляет средства для защиты от целочисленных переполнений, требует обязательной инициализации значений переменных перед использованием, лучше обрабатывает ошибки в стандартной библиотеке, применяет концепцию неизменяемости (immutable) ссылок и переменных по умолчанию, предлагает сильную статическую типизацию для минимизации логических ошибок.

Основные новшества:

  • В стандартную библиотеку добавлена поддержка неименованных каналов (anonymous pipe). Для создания неименованных каналов предложен метод std: io: pipe (), который может использоваться в сочетании с std: process: Command для обработки стандартных входных и выходных потоков, а также для объединения потоков stdout и stderr.
       use std::process::Command;
       use std::io::Read;
    
       let (mut recv, send) = std::io::pipe()?;
    
       let mut command = Command::new("path/to/bin")
           // объединение stdout и stderr в один канал
           .stdout(send.try_clone()?)
           .stderr(send)
           .spawn()?;
    
       let mut output = Vec::new();
       recv.read_to_end(&mut output)?;
    
       assert!(command.wait()?.success());
    
  • Разрешён вызов из safe-кода большинства встроенных в компилятор функций (Intrinsics) std: arch. Изменение применяется к встроенным функциям std: arch, которые помечены unsafe только из-за привязки к определённой функциональности, если эта функциональность включена. Например, _mm256_add_epi32 можно вызывать из safe-кода, если в приложении используется '#[target_feature (enable = «avx2»)]'.

  • Из блоков «asm!» с ассемблерным кодом разрешено осуществлять переходы на блоки с кодом на языке Rust, что упрощает разработку низкоуровневого кода, например, реализации оптимизаций в ядре или организации взаимодействия с оборудованием. Точка для перехода для ассемблерной команды «jmp» задаётся в макросе «asm!» при помощи нового операнда «label», содержащего блочное выражение с кодом на языке Rust.
    
       unsafe {
           asm!(
               "jmp {}",
               label {
                   println!("Jumped from asm!");
               }
           );
       }
    
  • Разрешено точно указывать захваченные обобщённые типы и время жизни в определениях типажей с использованием возвращаемых типов impl Trait.
       trait Foo {
           fn method‹'a›(&'a self) -› impl Sized;
         
           type Implicit1‹'a›: Sized;
           fn method_desugared‹'a›(&'a self) -› Self::Implicit1‹'a›;
       
           fn precise‹'a›(&'a self) -> impl Sized + use‹Self›;
        
           type Implicit2: Sized;
           fn precise_desugared‹'a›(&'a self) -› Self::Implicit2;
       }
    
  • В разряд стабильных переведена новая порция API, в том числе стабилизированы методы и реализации типажей:
    • Vec::extract_if
    • vec::ExtractIf
    • LinkedList::extract_if
    • linked_list::ExtractIf
    • ‹[T]›::split_off
    • ‹[T]›::split_off_mut
    • ‹[T]›::split_off_first
    • ‹[T]›::split_off_first_mut
    • ‹[T]›::split_off_last
    • ‹[T]›::split_off_last_mut
    • String::extend_from_within
    • os_str::Display
    • OsString::display
    • OsStr::display
    • io::pipe
    • io::PipeReader
    • io::PipeWriter
    • impl From‹PipeReader› for OwnedHandle
    • impl From‹PipeWriter› for OwnedHandle
    • impl From‹PipeReader› for Stdio
    • impl From‹PipeWriter› for Stdio
    • impl From‹PipeReader› for OwnedFd
    • impl From‹PipeWriter› for OwnedFd
    • Box‹MaybeUninit‹T››::write
    • impl TryFrom‹Vec‹u8›› for String
    • ‹*const T›::offset_from_unsigned
    • ‹*const T›::byte_offset_from_unsigned
    • ‹*mut T›::offset_from_unsigned
    • ‹*mut T›::byte_offset_from_unsigned
    • NonNull::offset_from_unsigned
    • NonNull::byte_offset_from_unsigned
    • ‹uN›::cast_signed
    • NonZero::‹uN›::cast_signed.
    • ‹iN›::cast_unsigned.
    • NonZero::‹iN›::cast_unsigned.
    • ‹uN›::is_multiple_of
    • ‹uN›::unbounded_shl
    • ‹uN›::unbounded_shr
    • ‹iN›::unbounded_shl
    • ‹iN›::unbounded_shr
    • ‹iN›::midpoint
    • ‹str›::from_utf8
    • ‹str›::from_utf8_mut
    • ‹str›::from_utf8_unchecked
    • ‹str›::from_utf8_unchecked_mut
  • Признак «const» применён в функциях:
    • core::str::from_utf8_mut
    • ‹[T]›::copy_from_slice
    • SocketAddr::set_ip
    • SocketAddr::set_port,
    • SocketAddrV4::set_ip
    • SocketAddrV4::set_port,
    • SocketAddrV6::set_ip
    • SocketAddrV6::set_port
    • SocketAddrV6::set_flowinfo
    • SocketAddrV6::set_scope_id
    • char::is_digit
    • char::is_whitespace
    • ‹N›>::as_flattened
    • ‹N›>::as_flattened_mut
    • String::into_bytes
    • String::as_str
    • String::capacity
    • String::as_bytes
    • String::len
    • String::is_empty
    • String::as_mut_str
    • String::as_mut_vec
    • Vec::as_ptr
    • Vec::as_slice
    • Vec::capacity
    • Vec::len
    • Vec::is_empty
    • Vec::as_mut_slice
    • Vec::as_mut_ptr
  • Удалён второй уровень поддержки для целевой платформы i586-pc-windows-msvc. Рекомендуется использовать платформу i686-pc-windows-msvc, которая отличается поддержкой инструкций SSE2. Платформа i586-pc-windows-msvc потеряла смысл, так как для Windows 10 необходима поддержка SSE2, а более ранние выпуски Windows в Rust не поддерживаются.



Источник: http://www.opennet.ru/opennews/art.shtml? num=63242

© OpenNet