LINUX.ORG.RU

Rust 1.17

 ,


3

9

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

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

$ rustup update stable

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

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

Выпуск Rust 1.17.0 в основном вносит небольшие улучшения, преимущественно касающиеся удобства использования. Например, время жизни 'static теперь автоматически подразумевается для констант или статических переменных. При создании константы или статической переменной:

const NAME: &'static str = "Ferris";
static NAME: &'static str = "Ferris";

Rust 1.17 позволит вам больше не писать 'static, так как это единственное время жизни, которое имеет смысл:

const NAME: &str = "Ferris";
static NAME: &str = "Ferris";

В некоторых ситуациях это позволит избавиться от лишних повторений:

// было
const NAMES: &'static [&'static str; 2] = &["Ferris", "Bors"];

// стало
const NAMES: &[&str; 2] = &["Ferris", "Bors"];

Другим подобным косметическим улучшением является «короткая инициализация полей». Подобно ECMAScript 6, который называет это «Сокращение Значения Свойства Объектного Литерала» («Object Literal Property Value Shorthand»), дублирование может быть удалено при объявлении структур, к примеру:

// определение
struct Point {
    x: i32,
    y: i32,
}

let x = 5;
let y = 6;

// было
let p = Point {
    x: x,
    y: y,
};

// стало
let p = Point {
    x,
    y,
};

То есть форма записи x, y будет предполагать, что значения x и y соответствуют переменным с аналогичными именами, находящимися в данной области видимости.

Другое маленькое, но полезное улучшение касается в основном новичков в Rust, которые пытаются использовать +, чтобы соединить две &str вместе. Но это не работает, соединить вы можете лишь String + &str. Поэтому, было добавлено новое сообщение об ошибке, чтобы помочь пользователям, которые совершают подобную ошибку:

// код
"foo" + "bar"

// было
error[E0369]: binary operation `+` cannot be applied to type `&'static str`
 --> <anon>:2:5
  |
2 |     "foo" + "bar"
  |     ^^^^^
  |
note: an implementation of `std::ops::Add` might be missing for `&'static str`
 --> <anon>:2:5
  |
2 |     "foo" + "bar"
  |     ^^^^^

// стало
error[E0369]: binary operation `+` cannot be applied to type `&'static str`
 --> <anon>:2:5
  |
2 |     "foo" + "bar"
  |     ^^^^^
  |
  = note: `+` can't be used to concatenate two `&str` strings
help: to_owned() can be used to create an owned `String` from a string
reference. String concatenation appends the string on the right to the string on
the left and may require reallocation. This requires ownership of the string on
the left.
  |     "foo".to_owned() + "bar"

При использовании сценариев сборки Cargo вы должны указать расположение скрипта в вашем Cargo.toml. Однако, подавляющее большинство людей писали build = «build.rs», тем самым используя файл build.rs, расположенный в корне проекта. Теперь это соглашение поддерживается самим Cargo, и будет использовано по умолчанию, если существует файл build.rs. Мы предупреждали об этом изменении в течение нескольких последних выпусков. Вы также можете использовать build = false для отказа от этого соглашения.

В этом выпуске удалена старая система сборки на основе Makefile. Новая система, анонсированная в Rust 1.15, написана на Rust и в основном использует Cargo для управления сборкой. На данный момент она уже достаточно зрелая, чтобы быть единственной системой сборки.

В рамках этого изменения, пакеты из crates.io теперь можно использовать в системе сборки Rust. Первым был добавлен mdBook, и он теперь используется при сборки нашей разнообразной книжной документации:

Обратите внимание на ссылки на соответствующие репозитории; документы были перемещены из основного дерева. Кроме того, мы добавили четвертую книгу, которая все еще расположена в основном дереве: Книга «Нестабильные возможности Rust». Она описывает нестабильные возможности, содержит ссылки на задачи, связанные с их стабилизацией, и может содержать исходную документацию. Если есть возможность, которую вы хотите увидеть стабилизированной, то пожалуйста, примите участие в ее обсуждении!

Несколько выпусков назад rustup перестал по умолчанию устанавливать документацию. Мы внесли это изменение, чтобы немного разгрузить канал, а также потому, что не все пользователи в действительности хотят хранить локальную копию документации. Однако это создало ловушку: некоторые пользователи не были в курсе, что произошло изменение, и заметили бы это, только если бы у них пропало подключение к Интернету. Кроме того, некоторые пользователи хотели иметь локальную копию документации, независимо от их подключения. Таким образом, мы откатили данное изменение, и документация снова устанавливается по умолчанию.

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

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

Был стабилизирован 21 новый интерфейс:

  • Arc::into_raw и Rc::into_raw позволят вам забрать Arc или Rc и получить сырой указатель.
  • Arc::from_raw и Rc::from_raw позволят вам забрать сырой указатель и получить Arc или Rc.
  • Arc::ptr_eq и Rc::ptr_eq возвращает true если оба Arc или оба Rc указывают на одно и то же значение (не обязательно значения, которые сравниваются, равны).
  • Ordering::then позволит вам сцепить два Ordering вместе, и Ordering::then_with позволит сделать это с помощью функции.
  • BTreeMap::range позволит вам итерировать лишь по части BTreeMap, и BTreeMap::range_mut позволит вам сделать это с возможностью изменения. collections::Bound может дать вам еще больше контроля.
  • process::abort будет полностью завершать процесс анормальным образом.
  • ptr::read_unaligned и ptr::write_unaligned аналогичны ptr::read и ptr::write, но без требований к выравниванию.
  • Result::expect_err зеркально подобен Result::expect, то есть работает с вариантом Err, а не с вариантом Ok.
  • Cell::swap аналогичен std::mem::swap, но позволяет вам делать это с &Cell вместо &mut T.
  • Cell::replace аналогичен std::mem::replace, но позволяет вам делать это с &Cell вместо &mut T.
  • Cell::into_inner позволит вам взять Cell, и извлечь его значение.
  • Cell::take позволит вам забрать значение Cell наружу, заменив его на Default::default.

Что касается других изменений, для многих методов Cell<T> требовалось ограничение T: Copy, но теперь это требование значительно ослаблено.

Box<T> теперь реализует более дюжины новых преобразований с помощью From.

SocketAddr и IpAddr также теперь имеют несколько новых преобразований. Раньше вы должны были писать код вроде этого:

"127.0.0.1:3000".parse().unwrap()

Сейчас же вы можете писать
SocketAddr::from(([127, 0, 0, 1], 3000))
// или
([127, 0, 0, 1], 3000).into())

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

Обратная трассировка теперь имеет более приятное форматирование, опуская некоторые незначительные детали по умолчанию.

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

Помимо ранее упомянутых изменений, касающихся build.rs, у Cargo есть еще несколько новых улучшений. cargo check --all и cargo run --package — два отсутствовавших до этого момента флага, которые теперь поддерживаются.

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

Новое поле в Cargo.toml, required-features, позволяет указать конкретные возможности, которые должны быть установлены для цели, которую нужно собрать. Вот пример: предположим, что мы пишем контейнер, который взаимодействует с базами данных, и хотим, чтобы он поддерживал несколько баз данных. Мы могли бы это сделать в нашем Cargo.toml:

[features]
# ...
postgres = []
sqlite = []
tools = []

Возможность tools позволяет нам включить дополнительные инструменты, а возможности postgres и sqlite указывают, какие базы данных мы хотим поддерживать.

Раньше cargo build пыталась собрать все цели, которые вам нужны. Но что, если у нас есть файл src/bin/postgres-tool.rs, который является нужным только при условии, что возможности postgres и tools были включены? Раньше нам приходилось писать что-то вроде этого:

#[cfg(not(all(feature = "postgres", feature = "tools")))]
fn main() {
    println!("This tool requires the `postgres` and `tools` features to be enabled.");
}

#[cfg(all(feature = "postgres", feature = "tools"))]
fn main() {
    // код
}

Слишком много шаблонного кода для работы с cargo build. Еще печальнее дело обстояло с examples/, которые должны демонстрировать, как использовать вашу библиотеку. Но такие махинации возможны только при работе внутри самого пакета, поэтому вы потерпите неудачу, если попытаетесь использовать пример вне этого пакета.

С помощью нового ключа required-features мы можем добавить следующее:

[[bin]]
# ...
required-features = ["postgres", "tools"]

Теперь cargo build будет собирать наш postgres-tool, только если у нас включены две эти возможности, и поэтому мы можем написать нормальный fn main без всяких нагромождений вроде cfg.

Разработчики версии 1.17.0

Много людей внесли свой вклад в создание Rust 1.17. Мы не смогли бы сделать это без всех вас. Спасибо!

Авторы перевода и публикации @kgv, @vitvakatu, @ozkriff.

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

★★★★★

Проверено: Shaman007 ()
Последнее исправление: sudopacman (всего исправлений: 3)

Ответ на: комментарий от drfaust

И для каждой OS компилер С сделает оптимальный вариант.

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

На Rust можно так же.

::x86::io::inw
red75prim ★★★
()
Ответ на: комментарий от mersinvald

dpkg без апта ничего не подтянет сам. После установки пакета надо делать apt install -f чтобы доустановить зависимости и пакет

А дальше 50/50 либо пакет улетит, либо пол системы.

NextGenenration ★★
()
Ответ на: комментарий от eao197

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

А память под строку выделяется на стеке?

NextGenenration ★★
()
Ответ на: комментарий от anonymous

Реализуй браузерный движок на том же самом си за год. Смелее, это же столь хороший инструмент.

NextGenenration ★★
()
Ответ на: комментарий от RazrFalcon

Почему все сишники так боятся шаблонов? Они же никак не влияют на рантайм. Это просто генераторы кода.

Не боимся. Просто знаем, что если ими злоупотреблять, то код быстро станет «упитанным».

drfaust ★★★★★
()
Ответ на: комментарий от pftBest

Вот и вопрос - нафига делать двойную вставку(асм в С, С в раст), если можно сразу в раст асм вставку вкорячить - или с cpuid нельзя(тогда почему нельзя)?

drfaust ★★★★★
()
Ответ на: комментарий от drfaust

или с cpuid нельзя(тогда почему нельзя)?

Конкретно в этом случае так сделали чтобы эта библиотека могла собираться стабильным релизом компилятора. Потому что ее могут захотеть использовать другие люди а не только ядро redox.

До вот этого коммита все работало без сишки https://github.com/gz/rust-cpuid/commit/81fc82eb6ecd4c47a79c158f7a60856453f14029

pftBest ★★★★
()
Последнее исправление: pftBest (всего исправлений: 1)
Ответ на: комментарий от pftBest

До вот этого коммита все работало без сишки

unsafe {
    let ebx: u32;
    let edx: u32;
    let ecx: u32;
     unsafe {
        asm!("cpuid" : "+{eax}"(eax) "={ebx}"(ebx)
                       "={ecx}"(ecx) "={edx}"(edx));
     }
 }

Не слишком ли громоздко?

drfaust ★★★★★
()
Последнее исправление: drfaust (всего исправлений: 1)
Ответ на: комментарий от anonymous

Ты так наезжаешь на llvm, будто у gcc нет бекенда. Или ты так и не понял, что такое llvm

А по коммитам ты так и не понял, что привязка к llvm твоего языка ограничивает тебя архитектурами самого llvm. Сколько уже можно приводить процессора, которые до сих пор рулят и педалят в продакшене.

Вот свежие аппаратики, прошивы которых нарисованы в основном на С и 51й архитектуре (Элвес-МФ 78e516, АМС-100Ф этот вообще на 80c31)

drfaust ★★★★★
()
Ответ на: комментарий от NextGenenration

Сравни.

asm volatile ("cpuid" : "+a"(*a), "=b"(*b), "+c"(*c), "=d"(*d));
Причём можно было бы избежать передачи параметров, если бы не требования биндить эту функцию снаружи.

drfaust ★★★★★
()
Последнее исправление: drfaust (всего исправлений: 1)
Ответ на: комментарий от drfaust

Это не полный пример. Где например обхявления a,b,c,d? То что ты привёл экивалентно двум отформатированным строкам из кода на rust

NextGenenration ★★
()
Ответ на: комментарий от pftBest

И ассемблерный код в итоге будет одинаковый. А внешний вид это субьективная характеристика.

результ. код надо сравнивать не на однострочниках.

drfaust ★★★★★
()
Ответ на: комментарий от drfaust

привязка к llvm твоего языка ограничивает тебя архитектурами самого llvm

То есть llvm использовать плохо, потому что он не все архитектуры поддерживает?

Какие ваши предложения? Наверно, написать нужные бэкенды самому?

anonymous
()
Ответ на: комментарий от mersinvald

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

upcFrost ★★★★★
()
Ответ на: комментарий от mersinvald

Told ya. :)

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

в целом можно наверно будет потом даже вместо вебхука сразу на obs настроить тревис, чтоб пакеты шли после билда (кто-то же должен заливать вендоринг, почему не скинуть это на CI)

upcFrost ★★★★★
()
Ответ на: комментарий от upcFrost

А вообще зачем ты ставишь stage0? Есть же бинарные билды компилятора и cargo, которые ставятся rustupом.

mersinvald ★★★★★
() автор топика
Ответ на: комментарий от mersinvald

которые ставятся rustupом

потому что в obs в виртуалке интернета нету. нет интернета - нет растапа. «интернет вещей» короче - нет интернета, нет вещей

upcFrost ★★★★★
()
Ответ на: комментарий от upcFrost

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

pftBest ★★★★
()
Ответ на: комментарий от mersinvald

С гитхаба автоматом сливается сорц через т.н. service. Дальше билд на изолированной вм. Мне просто честно даже в голову не приходило что они для сборки компилятора инет требуют. Сейчас нашел статику, буду ее заливать. Но блин, расстреливать надо за такое

upcFrost ★★★★★
()
Ответ на: комментарий от upcFrost

Когда ты сливаешь исходники с гитхаба то git pull не качает исходники сабмодулей. Что еще делать билд скрипту когда он видит что исходников не хватает?

pftBest ★★★★
()
Ответ на: комментарий от pftBest

Изначально на асме. И пока наличие компилятора С не стало стандартом - так и было. Раст пока мягко говоря мелковат для такого.

upcFrost ★★★★★
()
Ответ на: комментарий от upcFrost

Разве нельзя использовать компилятор из дистра? Или он там старой версии? В PPA можно было ставить нужны для сборки пакеты.

RazrFalcon ★★★★★
()
Ответ на: комментарий от pftBest

Я не про stage0, я про исходники llvm которые качаются после того как скачался stage0

с llvm все пучком, он качается через service. эта шляпа лезет на свой crates-io обновлять реп. и вылетает.

upcFrost ★★★★★
()
Ответ на: комментарий от RazrFalcon

Разве нельзя использовать компилятор из дистра? Или он там старой версии?

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

upcFrost ★★★★★
()
Ответ на: комментарий от pftBest

да я про то и говорю. с llvm все пучком, против гита ничего не имею (в разумных пределах, не как у Go). они даже сами говорят мол «ой, инета нет, ниче, у нас вендоринг». вот только через секунду прилетает «ой, дык он же пустой, сорян». то есть они сами его заявляют, и сами же не наполняют. очень смешно блин.

upcFrost ★★★★★
()
Ответ на: комментарий от NextGenenration

А память под строку выделяется на стеке?

Во-первых, это зависит от a) реализации std::string (см. small string optimization) и b) размера результирующей строки.

Во-вторых, это вообще не важно, т.к. нельзя оставлять ссылки на объекты, для которых уже был вызван деструктор.

eao197 ★★★★★
()
Ответ на: комментарий от drfaust

Не слишком ли громоздко?

C:

void c_cpuid(uint32_t* a, uint32_t* b, uint32_t* c, uint32_t* d) {
   asm volatile ("cpuid"
      : "+a"(*a), "=b"(*b), "+c"(*c), "=d"(*d)
   );
}

Rust:

unsafe fn cpuid(a: &mut u32, b: &mut u32, c: &mut u32, d: &mut u32) {
    asm!("cpuid"
        : "+{eax}"(*a), "={ebx}"(*b), "+{ecx}"(*c), "={edx}"(*d)
    );
}

https://is.gd/QuWfpI

Разница в слове unsafe и в том, что Rust требует полные имена регистров. Если нужен volatile, его тоже легко добавить.

Если хочется к этому красивый и удобный API, то there is a crate for that! https://docs.rs/cpuid/

anonymous
()
Ответ на: комментарий от anonymous

Мань, ты про Contiki слышал когда-нибудь?

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.