📜 ⬆️ ⬇️

Release Rust 1.13

The Rust team is pleased to present the release of Rust 1.13.0. Rust is a system programming language aimed at security, speed, and parallel code execution.


As usual, you can install Rust 1.13.0 from the corresponding page of the official site, as well as see the detailed list of changes in 1.13.0 on GitHub. This release includes 1448 patches.


It was a really hot time in Rust. We participated in three conferences in a row - RustConf , RustFest and Rust Belt Rust . It was great to see so many Rust lovers; We met with many for the first time! We thought a lot about the future, developed a plan for 2017 and created the tools our users needed .


And despite all this, we have collected a new release with a bunch of new cool chips.


What is included in the stable version 1.13


Does release 1.13 include the long-awaited operator ? , speeding up compilation, adding
Some features in Cargo and the standard library. This release also brings many small improvements to documentation and bug reports. This is the result of the work of many people, and they are not mentioned individually in the release notes.


This release contains important fixes for Cargo vulnerabilities. It depends on curl and openssl,
and they both recently published security updates. For details, see the corresponding announcements of curl 7.51.0 and OpenSSL 1.0.2j .


Operator ?


Rust purchased a new operator ? . It makes the work with errors much more pleasant,
removing the visual noise. For example, we have the following code to read data from a file:


 fn read_username_from_file() -> Result<String, io::Error> { let f = File::open("username.txt"); let mut f = match f { Ok(file) => file, Err(e) => return Err(e), }; let mut s = String::new(); match f.read_to_string(&mut s) { Ok(_) => Ok(s), Err(e) => Err(e), } } 

The code contains two paths that can fail with an error: opening a file and reading data from it. If one of them fails, we need to return the error from the read_username_from_file function. To do this, we have to match result of I / O operations. However, here we are simply forwarding an error to the call stack, and using match is a constantly recurring template code. Its hard to read.


C ? The above code will look like this:


 fn read_username_from_file() -> Result<String, io::Error> { let mut f = File::open("username.txt")?; let mut s = String::new(); f.read_to_string(&mut s)?; Ok(s) } 

? It is an abbreviation for the whole match expression, which we wrote above. In other words ? takes Result and, if it is Ok , expands it and gives the nested value. If the Result value is Err ? returns control from current function. It is much easier to read: instead of the whole expression, we use the character "?". So we show that we handle the error in the standard way, passing it up through the stack.


Experienced Rust programmers can point out that this is the same as the try! macro try! ,
available from Rust 1.0 . Indeed it is the same. Up to 1.13 read_username_from_file could be implemented like this:


 fn read_username_from_file() -> Result<String, io::Error> { let mut f = try!(File::open("username.txt")); let mut s = String::new(); try!(f.read_to_string(&mut s)); Ok(s) } 

So why make extensions to the language if we already have a macro? For different reasons.
First, try! confirmed its exceptional utility and is often used in the idiomatic Rust. It is used so often that it deserves a sweet syntax. This kind of evolution is one of the great advantages of a powerful macro system: the supposed extensions of the syntax of a language can be prototyped and tested without changing the language itself. In turn, a macro that has become extremely useful may indicate a lack of language capabilities. Such an evolution from try! in ? - a great example of this.


One of the reasons why try! needs to be sugar-coated - this is what it is rather ugly in the case of multiple calls in a chain. Compare:


 try!(try!(try!(foo()).bar()).baz()) 

a counterweight:


 foo()?.bar()?.baz()? 

The first fragment is quite difficult to read, and each error handling layer attributes
to the beginning of the expression call try! . This requires excessive attention concentration for trivial error forwarding, and overshadows the main working code — calls to foo , bar and baz . This type of call hooking with error handling is typical for situations like the builder design pattern.


Finally, specialized syntax makes it easier to get errors — can we consider using ? . And for code from macros it’s hard to make good mistakes. However, in this release, use error messages ? not fully implemented yet.


Although this is a slight improvement in our experience ? - a worthwhile improvement in ergonomics try! . This is a good example of the consistent improvement in the quality of life that Rust will continue to receive.


More about ? see RFC 243 .


Performance improvement


We seriously focused on compiler performance. We already have some good news, but it will be even better in future releases.


Mark Simulacrum and Nick Cameron honed perf.rust-lang.org , our compiler performance tracking tool. He regularly runs rustc-benchmarks on dedicated hardware and tracks changes over time. This tool records the results of each compilation step and is used by developers to narrow the search range for commits that lead to performance degradation. This is an important part of our toolkit!


We can use it to take a look at the performance schedule for the 1.13 development period - from August 16 to September 29 (the graph is shown below). The schedule starts on August 25 and is filtered by several criteria - to exclude unreliable, incomplete or contradictory results. You can notice large reductions that are quantitatively reflected on the corresponding statistics page.



Performance graph



On September 1, there was a significant improvement - Niko turned on the normalized projections of the cache during the broadcast . This means that during the generation of LLVM IR, the compiler no longer recalculates specific instances of associated types at each location. Now it reuses previously calculated values. This optimization does not affect any code, but when certain type fragments are encountered, you will notice a difference. For example, for futures-rs , the build time for the debug version has been improved by 40% .


Another similar optimization is implemented by Michael Woerister. It speeds up the compilation of containers that export many embedded functions. If the function is marked as #[inline] , the compiler stores its representation in MIR in rlib - in addition to the usual translation for use in the current container. Then it translates it in each container that calls the function. In retrospect, Michael made an obvious optimization: in some cases, the inline functions are intended only for other containers, so the compiler does not have to translate them in the container where they are declared. Of course, except when they are called there. This saves time on converting the function to LLVM IR and its processing by LLVM: optimization and code generation.


In some cases, this gives impressive results. The build time of ndarray is improved by 50% , and for (unpublished) winapi 0.3 , rustc now does not produce any machine code at all.


But wait, that's not all! Nick Nethercote also turned his attention to compiler performance , concentrating on profiling and micro-optimizations. This release already includes some of the fruits of his work , others are scheduled for 1.14.


See the release notes for details.


Other notable changes


This release contains important fixes for Cargo vulnerabilities. It depends on curl and OpenSSL, and they both recently published security updates. For details, see the corresponding announcements of curl 7.51.0 and OpenSSL 1.0.2j .


Now you can use in-place type macros ( RFC 873 ) and apply attributes to operators ( RFC 16 ):


 //  ,    macro_rules! Tuple { { $A:ty,$B:ty } => { ($A, $B) } } let x: Tuple!(i32, i32) = (1, 2); 

 //        #[allow(uppercase_variable)] let BAD_STYLE = List::new(); 

Built-in reset flags (inline drop flags) are removed. In the past, the compiler kept the "reset flag" in structures to understand whether to execute the destructor when structures moved in some execution paths. This increased the size of the structures, which prevented the transfer of types with destructors across the FFI boundary. For code that does not move structures only in part of the execution paths, this memory was wasted. At 1.12, MIR became the default translator - this was the foundation of many improvements, including the removal of these built-in reset flags . Now the reset flags are in the stack of those functions that need them.


In 1.13 there is a serious bug in code generation for ARM with a hardware implementation of floating point numbers. These are most of the ARM based platforms. Currently ARM is a platform of support level 2, so this bug does not block the release. Since 1.13 contains a security fix, we recommend ARM users to use beta versions 1.14. This thread will receive a fix for this problem soon.


Stabilization of language capabilities



Library stabilization



Cargo features



See the release notes for details.


Developers version 1.13.0


155 people contributed 1.13.0. Thank you very much!


List of participants
  • Aaron gallagher
  • Abhishek Kumar
  • aclarry
  • Adam Medziński
  • Ahmed charles
  • Aleksey Kladov
  • Alexander von Gluck IV
  • Alexandre Oliveira
  • Alex Burka
  • Alex Crichton
  • Amanieu d'anthras
  • Amit levy
  • Andrea Corradi
  • Andre Bogus
  • Andrew cann
  • Andrew Cantino
  • Andrew Lygin
  • Andrew Paseltiner
  • Andy russell
  • Ariel Ben-Yehuda
  • arthurprs
  • Ashley williams
  • athulappadan
  • Austin hicks
  • bors
  • Brian anderson
  • c4rlo
  • Caleb jones
  • CensoredUsername
  • cgswords
  • changchun.fan
  • Chiu-Hsiang Hsu
  • Chris Stankus
  • Christopher Serr
  • Chris Wong
  • clementmiao
  • Cobrand
  • Corey farwell
  • Cristi cobzarenco
  • crypto-universe
  • dangcheng
  • Daniele Baracchi
  • DarkEld3r
  • David Tolnay
  • Dustin bensing
  • Eduard burtescu
  • Eduard-Mihai Burtescu
  • Eitan adler
  • Erik uggeldahl
  • Esteban Küber
  • Eugene bulkin
  • Eugene R Gonzalez
  • Fabian zaiser
  • Federico Ravasio
  • Felix S. Klock II
  • Florian gilcher
  • Gavin baker
  • Georg Brandl
  • ggomez
  • Gianni ciccarelli
  • Guillaume gomez
  • Jacob
  • jacobpadkins
  • Jake goldsborough
  • Jake goulding
  • Jakob demler
  • James duley
  • James miller
  • Jared roesch
  • Jared wyles
  • Jeffrey seyfried
  • Jessrudder
  • Joe neeman
  • Johannes löthberg
  • John firebaugh
  • johnthagen
  • Jonas schievink
  • Jonathan turner
  • Jorge aparicio
  • Joseph dunne
  • Josh Triplett
  • Justin lefebre
  • Keegan mcallister
  • Keith yeung
  • Keunhong lee
  • king6cong
  • Knight
  • knight42
  • Kylo Ginsberg
  • Liigo
  • Manish goregaokar
  • Mark-simulacrum
  • Matthew piziak
  • Matt ickstadt
  • mcarton
  • Michael Layne
  • Michael Woerister
  • Mikhail Modin
  • Mohit agarwal
  • Nazım Can Altınova
  • Neil Williams
  • Nicholas nethercote
  • Nick cameron
  • Nick platt
  • Niels Sascha Reedijk
  • Nikita Baksalyar
  • Niko Matsakis
  • Oliver middleton
  • Oliver schneider
  • orbea
  • Panashe M. Fundira
  • Patrick walton
  • Paul Fanelli
  • philipp
  • Phil ruffwind
  • Piotr jawniak
  • pliniker
  • QuietMisdreavus
  • Rahul sharma
  • Richard Janis Goldschmidt
  • Scott a carr
  • Scott olson
  • Sean McArthur
  • Sebastian ullrich
  • Sebastien marie
  • Seo sanghyeon
  • Sergio benitez
  • Shyam sundar b
  • silenuss
  • Simonas kazlauskas
  • Simon sapin
  • Srinivas reddy thatiparthy
  • Stefan schindler
  • Stephan hugel
  • Steve klabnik
  • Steven allen
  • Steven fackler
  • Terry sun
  • Thomas garcia
  • Tim neumann
  • Tobias bucher
  • Tomasz Miąsko
  • trixnz
  • Tshepang Lekhonkhobe
  • Ulrich weigand
  • Ulrik sverdrup
  • Vadim chugunov
  • Vadim Petrochenkov
  • Vanja cosic
  • Vincent Esche
  • Wesley wiser
  • William Lee
  • Ximin luo
  • Yossi Konstantinovsky
  • zjhmale

')

Source: https://habr.com/ru/post/315192/


All Articles