LINUX.ORG.RU

Rust 1.10

 ,


0

4

Анонсирована очередная версия языка программирования Rust 1.10, разрабатываемого Mozilla совместно с сообществом.

Улучшения компилятора:

  • Добавлен новый тип крейта cdylib, предназначенный для экспорта C API. Основные отличия от dylib:
    • отсутствие метаданных;
    • разрешено LTO;
    • все библиотеки должны быть статически слинкованы;
    • экспортируются лишь те символы, которые помечены как extern. Например:
      pub fn foo() {} // не экспортируется
      #[no_mangle] pub extern fn bar() {} // экспортируется
    Для сравнения: «hello world» cdylib занимает 7.2КБ, а dylib - 2.4МБ.
  • Добавлена поддержка платформ i586-unknown-linux-gnu, i686-unknown-linux-musl, и armv7-linux-androideabi;
  • Снижено потребление памяти на ~100МБ при проверке типов;
  • Ускорена проверка T: Sized на 15%;
  • Улучшена кодогенерация при #[derive(Copy, Clone)].

Изменения в стандартной библиотеке:

Breaking changes!

  • AtomicBool теперь преобразуется в bool, а не isize. Демонстрация:
    use std::sync::atomic::AtomicBool;
    use std::mem::transmute;
    
    fn main() {
        let foo: bool = unsafe { transmute(AtomicBool::new(true)) };
    }
    
    На старых версиях компилятора будет ошибка;
  • time::Duration::new теперь будет паниковать при переполнении;
  • String::truncate теперь будет паниковать чуть меньше;
  • Небольшое изменение поведения макросов на этапе их парсинга: из :ty и :path следует :block;
  • Исправлен баг, связанный с гигиеной макросов. Следующий код будет валидным в устаревших версиях компилятора:
    fn main() {
        let x = true;
        macro_rules! foo { () => {
            let x = 0;
            macro_rules! bar { () => {x} }
            let _: bool = bar!();
            //^ `bar!()` использует первый `x` (который bool),
            //| а должен использовать второй `x` (который i32).
        }}
        foo! {};
    }
  • Переименование платформ:
    • arm-unknown-linux-gnueabi => arm-unknown-linux-gnu;
    • arm-unknown-linux-gnueabihf => arm-unknown-linux-gnu;
    • armv7-unknown-linux-gnueabihf => armv7-unknown-linux-gnu.
    Другими словами, изменены target_env, применяемые в conditional compilation.

Изменения в менеджере зависимостей Cargo:

  • Добавлен флаг --force, -f для подкоманды cargo install, предназначенной для загрузки исходных текстов из crates.io, их компиляции и установки в каталог ~/.cargo/bin. Это нововведение теперь позволит писать:
    cargo install FOO -f
    вместо:
    cargo uninstall FOO
    cargo install FOO
    Однако всё еще невозможно узнать, а требуется ли обновление вообще?
  • Диагностические сообщения теперь отправляются в stderr, а не в stdout;
  • С помощью флагов cargo doc --bin и cargo doc --lib можно выбрать: генерировать html документацию для проекта-приложения src/main.rs или проекта-библиотеки src/lib.rs;
  • В конфигурационном файле Cargo.toml, который можно встретить в корневом каталоге каждого проекта, теперь можно указать, каким образом макрос panic!() будет завершать приложение: unwind (по умолчанию) или abort;
  • Добавлен флаг cargo --explain FOO, поведение которого идентично rustc --explain FOO: показывает документацию по номеру ошибки;
  • В черный список имен крейтов добавлены ключевые слова раста, такие как fn, unsafe, let и прочее.

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



Проверено: tailgunner ()
Последнее исправление: cetjs2 (всего исправлений: 6)

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

Если бы мне это было надо - да, я бы рассчитал. Просто опытным путем. Какие проблемы.

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

У тебя в тестовой программе нет ARC.

Тем более. Значит сломана даже более низкоуровневая концепция.

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

Бытует мнение, что Rust безопаснее C. Для последнего есть стандарт MISRA, который эту негодную рекурсию запрещает. А в безопасном Rust она используется на уровне стандартной библиотеки, если не самого языка. Выходит, если мы хотим писать код, который не падает в зависимости от фазы луны, версии рантайма и параметров компиляции, нам нельзя пользоваться стандартной библиотекой, и для передачи чего-либо куда-либо остаётся только unsafe?

Продай мне этот язык при подобных условиях.

Ах да, GC сложнее, но, поскольку он, как правило, часть рантайма, то и тестируется он всем миром, в отличии от наших поделок с unsafe.

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

Для последнего есть стандарт MISRA, который эту негодную рекурсию запрещает

Да, это решает все проблемы.

А в безопасном Rust она используется на уровне стандартной библиотеки, если не самого языка

Пока я вижу, что ты сделал типичную ошибку начинающего, о которой предупреждают в туториалах: http://cglab.ca/~abeinges/blah/too-many-lists/book/first-drop.html, а потом начал делать из этой ошибки выводы космического масштаба.

Продай мне этот язык при подобных условиях.

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

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

о которой предупреждают в туториалах: http://cglab.ca/~abeinges/blah/too-many-lists/book/first-drop.html

Спасибо, я в курсе, как бороться с этой проблемой. Теперь посмотри на этот же код, и скажи, что он тебе напоминает.

чтобы купить Rust, нужно кое-что потратить - как минимум время на изучение

Чтобы утверждать, что лизать железную ручку в мороз не нужно, не нужно этого делать.

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

Спасибо, я в курсе, как бороться с этой проблемой

Может, ты еще в курсе, где именно в стандартной библиотеке есть эта проблема? После

good_riddance> в безопасном Rust она используется на уровне стандартной библиотеки

ты просто обязан это знать.

лизать железную ручку

Не принимай строго на свой счет, но напомнило:

«Для таких как ты на ручных гранатах делают надпись: „В рот не класть“»

Sun-ch

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

Жду ответа на вопрос «что же этот workaround напоминает». Подсказка в треде.

Может, ты еще в курсе, где именно в стандартной библиотеке есть эта проблема?

Нет, не в курсе. Возможно, в реализации Box или где-то ниже. См. мой предыдущий пост, где говорилось то же самое. Не считаю нужным копировать все детали из поста в пост.

«Для таких как ты на ручных гранатах делают надпись: „В рот не класть“»

#rust #programming #rustprogramming #learning #mozilla #install #run #zerocostabstractions #memorysafety

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

Жду ответа на вопрос «что же этот workaround напоминает»

Мне он напоминает итеративный проход по списку, что он напоминает тебе - понятия не имею.

Может, ты еще в курсе, где именно в стандартной библиотеке есть эта проблема?

Нет, не в курсе

Я так и думал.

#rust #programming #rustprogramming #learning #mozilla #install #run #zerocostabstractions #memorysafety

А, тут поколение твиттера. Тогда на понятном тебе языке: #nodejs #smoothie

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

А, тут поколение твиттера.

Да, оно-то и форсит Rust.

Мне он напоминает итеративный проход по списку

Совершенно верно. Полная аналогия с устаревшим и небезопасным C. Только в C мы гарантированно получаем и замечаем утечку, а здесь забытая деинициализация может, к примеру, отработать в тестах, но вызвать в продакшне nasty креш, поскольку этот механизм полностью непредсказуем.

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

тут поколение твиттера.

Да, оно-то и форсит Rust.

Недавно ты сам просил продать тебе Rust, а сейчас жалуешься, что его форсят.

Мне он напоминает итеративный проход по списку

Совершенно верно. Полная аналогия с устаревшим и небезопасным C

Полная

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

Только в C мы гарантированно получаем и замечаем утечку

Гарантированно получаете? Гарантированно замечаете? Что ты несешь.

этот механизм полностью непредсказуем

Не пиши списков, пока не поймешь языка. И помни о надписи на гранате.

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

Недавно ты сам просил продать тебе Rust, а сейчас жалуешься, что его форсят.

Это так называемая «фигура речи». Прости что ввёл в заблуждение, запас плакатов с надписью «сарказм» иссяк.

В отличие от Си, этот проход безопасен.

...

Гарантированно получаете

Да, гарантированно. malloc без free течёт как часы, практически в любое время года и суток.

Не пиши списков, пока не поймешь языка.

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

И помни о надписи на гранате.

Но на гранате написано #zerocostabstractions #memorysafety. Я что-то не вижу надписи, что она взрывается в кармане, если нагреть её до температуры 38 C (или 36.8, если рядом находится сильный магнит).

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

Да, гарантированно. malloc без free течёт как часы, практически в любое время года и суток.

Я рад за malloc. А твоя претензия к Rust в чем?

Ты, как знаток языка

Как вы достали. Я не знаток языка, не евангелист, не продаван. Я просто слежу за ним.

утверждаешь, что эта проблема проявляется только в списках?

Я утверждаю, что надо читать маны и понимать, что делаешь. Написал класс с рекурсивным вызовом деструкторов - получил последствия.

Но на гранате написано #zerocostabstractions #memorysafety

А ты прочитай, что такое memorysafety. Внезапно выяснишь, что падение не явлется ее нарушением.

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

А ты прочитай, что такое memorysafety. Внезапно выяснишь, что падение не явлется ее нарушением.

Был топик, где я показал тебе, как успешно писать в область памяти за пределами стека. Ты тогда сказал, что и это не является нарушением memorysafety.

П.С. если что у меня нет никаких претензий к работе со стеком в Rust, все адекватно и безопасно.

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

Я не знаток языка, не евангелист, не продаван.

В профиле же написано: «Старый быдлокодер, тролль». Но каждый раз кто-то заново ловится на ваши провокации

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

Но каждый раз кто-то заново ловится на ваши провокации

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

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

Был топик, где я показал тебе, как успешно писать в область памяти за пределами стека. Ты тогда сказал, что и это не является нарушением memorysafety.

Потому что после твоей «записи» программа немедленно упала, да?

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

Потому что после твоей «записи» программа немедленно упала, да?

Это для тебя это «немедленно», а за это время испорченные данные могли, например, отправится на сервер.

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

Потому что после твоей «записи» программа немедленно упала, да?

Это для тебя это «немедленно»

Тогда давай линк на дискуссию.

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

А ты прочитай, что такое memorysafety

Я примерно представляю, что это. К Rust оно не относится.

Как вы достали. Я не знаток языка, не евангелист, не продаван. Я просто слежу за ним.

Изящный уход от основного вопроса.

Я утверждаю, что надо читать маны и понимать, что делаешь. Сделал X - получил последствия.

Какая прекрасная общая фраза. Допустим, я делаю ревью кода на Rust. Там всюду используются эти «смартпоинтеры». Какие маны мне нужно прочесть и как понять, когда нужно делать деаллокацию a la С, а когда надеяться на автоматическое разрешение? Когда уровень вложенности достигает 2? 10? Может быть произвольным?

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

Что именно «подробнее»? Нить будет портить свой стек и рано или поздно рухнет, но ничего послать не сможет и стеки других нитей не испортит.

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

Что именно «подробнее»? Нить будет портить свой стек и рано или поздно рухнет, но ничего послать не сможет и стеки других нитей не испортит.

Нет, стек как раз она портить не будет вообще. Запись будет вестись исключительно за его пределами.

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

Прекрасно, что люди понимают наличие нескольких трактовок одного слогана.

Кстати, такой ещё тезис есть. Часто во время повторения слогана «no GC» люди утверждают, что это якобы делает тайминги более предсказуемыми. Но malloc тоже может быть медленным и время его работы тоже непредсказуемо (зависит от фрагментации кучи). Плюс Rust использует и malloc и ARC, который тоже мало предсказуемый. Вопрос: есть ли исследования джиттера ARC и GC-based программ?

Скажем, разброс времени, проведённого внутри разных реализаций malloc и GC. Это было бы интересно независимо от темы треда.

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

Да, это известная проблема: https://github.com/rust-lang/rfcs/issues/686. Сейчас внимание разработчиков сфокусировано на MIR, так что вряд ли её исправят в ближайшее время.
Справедливости ради, никто не использует связные списки (особенно самодельные) в реальном коде.

ARC

Нет, раст его не использует. Все умные указатели — явные, а не автоматические.

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

Справедливости ради, никто не использует связные списки (особенно самодельные) в реальном коде.

Проблема не в списках. И спискам, кстати, тоже место можно найти в «реальном коде» (как динамический контейнер для хранения чего-то очень большого, или чего-то, что нельзя двигать).

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

У тебя какое-то свое понимание термина «стек».

Нет, это ты не хочешь или не можешь говорить по существу. Тебе полностью расписывают что и как, с примером листинга, а ты начинаешь вилять.

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

Проблема не в списках.

Это понятно, и, тем не менее, проблема весьма редка на практике.

И спискам, кстати, тоже место можно найти в «реальном коде»

В весьма редких случаях.

quantum-troll ★★★★★
()
Ответ на: комментарий от good_riddance

ARC
мало предсказуемый

Чем он мало предсказуемый?

malloc тоже может быть медленным и время его работы тоже непредсказуемо

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

У любимого вами GC есть задержки произвольной длины в произвольные моменты времени. Есть множество областей, где это совершенно недопустимо.

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

Значит сломана даже более низкоуровневая концепция.

Лол. Вы в курсе, что ругаете Rust за то, что можно легко повторить в C++? Но программистам на C++ это, последние лет 30, как-то не мешает.

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

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

Ну да, флагман. Точнее 1 из 2х больших проектов, написанных на rust. Вот вы готовы гарантировать, что взяв наугад какой-нибудь большой проект на С++ вы не найдёте там говнокода? Ну а теперь сделайте скидку, на то что существенная часть servo написана на альфа версии раста программистами, ещё не освоившими идиоматический растовый код.

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

tailgunner, как евангелист раста, объясни почему идиоматичный код без всяких unsafe вещей приводит к непредсказуемым крешам в зависимости от размера задачи?

А можно я объясню? Жил такой дядька по фамилии Тьюринг, который 80 лет назад доказал, что для любого тьюринг-полного языка не существует в общем случае возможности для некоего известного алгоритма и заданных для этого алгоритма входных данных определить, завершится ли когда-нибудь выполнение этого алгоритма на этих входных данных или он зависнет намертво. Из этой теоремы можно сделать вывод, что также невозможно определить, сколько алгоритму потребуется памяти, ведь в любой алгоритм можно добавить в тело цикла выделение памяти и тогда если алгоритм завершается, памяти потребуется некое ограниченное количество, а если не завершается то памяти тоже потребуется бесконечность. Из этого следует вывод, что обнаружить окончание памяти в тьюринг-полном языке статическим анализатором в принципе невозможно. Не имеет смысла даже пытаться.

Возвращаясь к конкретной проблеме, источник очевиден:

рантайм вызывает некий аналог delete для корневого узла, который вызывает delete для следующего и так продолжается пока не кончится список или не кончится стек. В принципе данный пример можно исправить, заменив рекурсию на цикл, но этот алгоритм будет не так красив и он не поможет, если вместо односвязного списка у нас будет дерево. Также возможны проблемы если ABI rust гарантирует порядок освобождения памяти, типа сначала внутренние члены, потом родитель (я не в курсе, возможно это так, а может и нет). В любом случае, разговоры о том, что данной проблемы нет в языках с GC от лукавого: да, этой проблемы нет, пока не требуется детерминированное освобождение. Как только мы реализуем для такого списка рекурсивные IDisposable, AutoCloseable или что-то типа того, вылезет та же проблема.

anonymous
()

Всё-таки печалит, что в ржавчине невозможно имплиментить трейты для классов из другого крейта.
Из-за этого появляются танцы с бубнами вокруг массивов, когда тебе нужен Clone и Copy трейт.

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

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

Боже упаси. Списки не нужны вообще никогда. Если у вас большие структуры и их нельзя двигать - используйте вектор из указателей.

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

Всё-таки печалит, что в ржавчине невозможно имплиментить трейты для классов из другого крейта.

Можно, но для этого необходимо создать трейт и реализовать его для необходимого типа:

use std::fmt::Display;

trait VecExt {
    fn print(&self);
}
impl<T: Display> VecExt for Vec<T> {
    fn print(&self) {
        for i in self {
            print!("{} ", i);
        }
    }
}

fn main() {
    let v = vec![1, 2, 3];
    v.print();
}
Пока VecExt находится в области видимости, ты можешь использовать метод .print.

Из-за этого появляются танцы с бубнами вокруг массивов, когда тебе нужен Clone и Copy трейт.

На данный момент трейты реализованы для массивов до N = 32. Хотя они вполне могли бы через макрос покрыть все размеры и использовать атрибут #[doc(hidden)], чтобы не засорять html документацию.

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

А это проблема самого руста, или реализации?

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

Можно, но для этого необходимо создать трейт и реализовать его для необходимого типа

Это не то.

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

Не было бы Linux, то взлетела бы FreeBSD. Не было бы FreeBSD, взлетела бы какая-нибудь другая ОС. Не было бы ничего - написали бы.

Ой, да ладно... Мы видим парочку графических тулкитов, пачку файловых систем, море браузеров и проч., и прочее...

Я к тому, что могло и ничего не взлететь, а было бы несколько «бисидишек» или еще чего, каждый бы пилил то, что ему больше по душе и т.д. Где-то сбоку полоскался бы какой-нибудь хурд. Для мелочи было-бы что-то одно, для серверов - другое, для настольных - третье, для рабочих станций - четвертое.

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