Hacker News new | past | comments | ask | show | jobs | submit login
Announcing Rust 1.12 (rust-lang.org)
396 points by steveklabnik on Sept 29, 2016 | hide | past | favorite | 76 comments



MIR is here! End-users probably aren't going to be too excited about this just yet, since MIR's focus in 1.12 is in ensuring there are no correctness regressions (always a risk when you rewrite an enormous portion of your middle-end) or noticeable runtime perf or compile-time perf regressions. I do recall pcwalton remarking that MIR improved Servo's compile times by about 20%, though this is probably not what one would expect across the board. In any case, the upcoming 1.13 release is where the rubber is really going to start meeting the road: middle-end optimizations that operate on the MIR (i.e. https://github.com/rust-lang/rust/pull/36388 ); outright removing old trans (which remains in 1.12 via a compiler flag) which allows us to actually start taking advantage of non-zeroing drop (a long-held dream!); an initial spike for incremental recompilation; plus big miscellaneous performance improvements such as https://github.com/rust-lang/rust/pull/36524 . As ever, no matter how exciting Rust's present is, it somehow seems that its future is even more so. :P

(Which isn't to overshadow Jonathan Turner's heroic compiler error message overhaul that has been long in the works, or the dozens and dozens of new volunteers who answered the call to help us transition: https://github.com/rust-lang/rust/issues/35233 . But I've had the new error messages enabled for months now, and it's easy to forget that not everyone has been enjoying them this whole time!)


For those like me that don't know, MIR is midlevel intermediate representation

https://blog.rust-lang.org/2016/04/19/MIR.html


Which will enable in the future:

> Faster compilation time [...] Faster execution time [...] More precise type checking


I'm also excited about the possibilities MIR opens up. As I recall, non-lexical lifetimes depended on MIR. Does anybody know what the current ETA is for that feature?


It's still in the pre-RFC phase, so there's no solid ETA. This was in fact one of the largest blockers, though, so we'll see how it goes. To make the status of MIR more clear:

  * 1.11: "old trans" by default, MIR with a flag
  * 1.12: MIR by default, "old trans" with a flag
  * 1.13: MIR only, "old trans" is gone
Given that we've had 6 weeks so far with MIR-by-default, everything is looking good, but in theory, making it more widely available might turn up issues. If something catastrophic happens, in theory, old trans could be brought back. So we'll see how the next few weeks goes.

That doesn't mean _no_ work has been done on non-lexical lifetimes, see http://smallcultfollowing.com/babysteps/blog/2016/05/09/non-... (that's a link to the last of three posts). But there's still work to write an actual RFC, discuss it, and then land it.


The information about lifetimes will be available to IDEs? So may be possible to identify lifetimes by the color from each variable https://medium.com/@evnbr/coding-in-color-3a6db2743a1e#.lu50...


Now that MIR has landed, lifetime improvements are now blocked on porting the borrow checker to use the MIR directly, which also involves shuffling it after the MIR phase of the compiler. It's definitely a priority for the near future, but in the immediate term I think most of the focus of the devs is going to be on getting incremental recompilation to a usable state.


There is a postponed issue regarding them here: https://github.com/rust-lang/rfcs/issues/811

(Edited after @steveklabnik corrected me)


Nit: that's not an RFC, it's just an issue in the RFC repo.

PRs in that repo are a much bigger deal than issues: issues are a place to talk in a general sense and see if others are interested in the feature, but converting that into an actual, actionable RFC is a lot of work. I'm not aware of any actual RFC for non-lexical lifetimes, because everyone who would do such a thing knew we had to wait for MIR to shake out before they were realistically possible, and so writing an RFC before then would mostly be a waste of time.


Ah, you're right, sorry. Corrected.


It's all good! I only even make the nitpick because this is an _incredibly_ anticipated feature, and I don't want people to have unrealistic expectations about how far along it is. I considered not even saying anything.


Maybe off topic, but what's the state of constant-time programming in Rust? Last I checked it wasn't possible and people who need that still have to stick with C or other languages.


each percent of compilation time is an improvement. 20% is huge success.


It's been really cool watching the design and development of the new error messages from the outside. There was significant inspiration drawn from the Elm language's fantastic error messages [1] and even a project that provided something similar (but not built into rustc) [2].

I've always thought that Rust's command line tooling is really top notch. The language may be complex, but the authors of rustc make it a point of pride to make it as easy as possible for users anyway. The new errors will make it that much easier to learn and be productive in Rust.

Also, the community involvement in this release is really spectacular. There were 83 participants working together on the new error messages [3] and 176 total involved directly with the rust compiler just for 1.12! (ok, well, including a few bots)

[1] https://internals.rust-lang.org/t/compiler-errors-for-humans... [2] https://www.reddit.com/r/rust/comments/3totkg/dybuk_the_elml... [3] https://github.com/rust-lang/rust/issues/35233


> The language may be complex

Compared to what?

Edit: This was not meant as a slight, I quite like Rust's comapritive simplicity when held up to other non-GC 'systems' languages.


Modula-3 with a concurrent, low-latency GC + static analysis on anything declared unsafe. That's first example that comes to mind. It nicely balanced safety, compilation speed, productivity, and runtime performance. SPIN OS was written in it that leveraged type-safe linking + its safety to pull user add-ons straight into the kernel without crashes. CVSup for FreeBSD was originally done in it as well with development experience so good vs C++ that author didn't want to give it up.

https://en.wikipedia.org/wiki/Modula-3

So, that's my baseline if we're excluding functional programming elements. Maybe that with Design-by-Contract and SCOOP from Eiffel. I'd add borrow checker from Rust for unsafe sections as an option. Past that, you've already knocked out vast majority of issues while retaining rapid development.

If functional programming, I'd start with a PreScheme (C replacement), bring it closer to Racket on static or dynamic side for power, build in safety analysis, and sugar coat it with nice syntax + standard library. Julia language did something similar to that approach with femtolisp at the core. Also easy to read and learn for a language so powerful.

I currently recommend Rust over most C alternatives due to the attributes in its motto plus strong community (most important) around it. The simpler alternatives in this niche got little traction for various reasons that are more social or economic than technical. So, if you're jumping on a wave, might as well pick the one that's safe and fast by default.


To answer you seriously—I think a great contrast would be the simplicity of Go. The GC and type system are both the opposite of providing complexity to the user; they provide the only way to get anything done, and it's easy to keep in your head.

For the record, I prefer rust.


I would like to switch from go to rust. But rust's standard library isn't as mature as that of go. Do you think there are compatible crates to packages from go's standard library.

I need

* json/gzip/etc. * string manipulation * good unicode support (normalization, etc.)

not much actually.

And one important question: which one do you think is best for large projects? Both were built to deal with difficulties rising from large projects but took two opposite directions...


Rust has a nice standard library, but much nice functionality comes from external crates. If you haven't yet, you should check out the Cargo tutorial[1], which is an intro to the package management and build system. I have used a JSON library, which worked well out of the box. I'm sure there are others up there for your other bullets.

I will say that all strings in Rust are Unicode, so the support is there.

Edit to your question about large projects: I think Rust's type system will prove to be a long-term benefit for large projects. The type system / borrow checker combination is the secret sauce of Rust.

[1] http://doc.crates.io/index.html


If by JSON you need serialization, then I'd recommend Serde: https://crates.io/crates/serde (which works on stable Rust but has a nicer interface on nightly; this nicer interface should be available on stable by early next year at the latest)

For Unicode support, here are crates for normalization https://crates.io/crates/unicode-normalization and segmentation (working with grapheme clusters and so on) https://crates.io/crates/unicode-segmentation

Re: "string manipulation" what do you need? Rust has a rich set of methods built in to its two native string types, (e.g. left-padding https://doc.rust-lang.org/std/fmt/struct.Formatter.html#meth... :P ), and we're open to adding more if there's demand for them.


  * https://crates.io/crates/serde_json [1]
  * https://crates.io/crates/flate2
  * https://crates.io/crates/unicode-normalization
"String manipulation" is a bit broad, but Rust's string types are already pretty rich.

[1]: small caveat here: this crate works on stable, but is more convenient on nightly. (Think "right now it's "go generate" but eventually it will be easier than that). We're close to stabilizing the stuff that it needs to be convenient on stable, but the earliest that could land in stable is Dec 22. (I just did this math yesterday.)


> But rust's standard library isn't as mature as that of go.

I'm not really sure that's true. Rust probably has a smaller standard library overall, but there are things that it has that Go doesn't: B-trees, native OS string encodings, functional tools, round(), etc.

The bigger point is that the crates.io ecosystem readily has support for everything you're asking for, and it's much easier to pull in third-party dependencies in Rust.


I am fairly certain I successfully got binary trees deleted from the standard library. If you monsters added it back, so help me god...

(BTrees, on the other hand, thrive)


Sorry about that. Corrected myself.


FWIW, in my opinion, the biggest thing that Rust has in `std` that Go doesn't is its iterator API. (I think you might have meant this by "functional tools," but just wanted to clarify.)


The Rust stdlib is indeed quite a bit slimmer, largely by design AFAICT. String manipulation and Unicode sopport are very much there.

Serde (https://serde.rs/) is probably what you're looking for for serialization tasks.


I think the rust compiler's enforcement of borrowing and explicit mutability make writing non-trivial Rust code as complicated as writing the same program with code that has equivalent safety (which isn't enforced) in C++.

The biggest issues I've seen lie at the safe/unsafe boundary. Things that are trivial to write without safety guarantees in C++ become more verbose (at least) in Rust.


But that is a common feature to Ada, Modula-3, Oberon derivatives, even Frama-C.

On one hand we need to still be able to do low-level stuff on "as needed" basis, but on the other hand it needs to be hard and explicit so that route is only taken as least resort and very easy to track down, even without help from tools.


It's...not an easy language. Not unapproachable by any stretch, but it's got surface area.

The thing that (currently) trips me up the most is figuring out when when I've to dereference something, and why, when I've to pass a reference to something and why, etc. Sometimes I do end up with a touch of operator soup.


> The thing that (currently) trips me up the most is figuring out when when I've to dereference something, and why, when I've to pass a reference to something and why, etc. Sometimes I do end up with a touch of operator soup.

This is a very common experience! One of the goals this year is to ease this painpoint.


Everything besides C and C++.


C is considerably less complex than either Rust or C++.


By those that use a single compiler, on a single OS and never had to deal with UB bugs.


I regularly have used more than one compiler (Borland, cc, early Microsoft, and one or two other proprietary ones for developing drivers for embedded optics controllers), programmed for more than one OS (Linux, a RTOS flavor of Linux, MS, Apple, AIX), and have seen my fair share of UB issues.

What you're referring to (programs and behaviors) is not what I was referring to (language details).


I don't understand how implementation-defined and undefined behavior are not a part of the language semantics. They're specified in the language standard, and they determine how the program code will be compiled. They're clearly part of the language.

The pretense that C is a simple language is equivocation, in my opinion.


Hmmm, that's a fair point, since "which C" applies, but I think that's a deficiency in the standard and larger in scope than the point I intended.


There's an assumption that having fewer forms of abstraction, or fewer syntactic constructs, makes a language 'simple.' Certainly having to understand and choose between different forms of abstraction can make it difficult to use a language correctly, but the absence of that kind of complexity doesn't mean the language is necessarily simple.


Thank you, Rust standard library maintainers, for making it very easy for me to contribute `BinaryHeap::peek_mut` to the stdlib, which landed in stable today!


Nice contribution!

I was just browsing the apidocs of peek_mut. Can you share a motivating use case? It wasn't immediately obvious to me.


This summer I was working on a userspace network I/O scheduler in Rust, and to avoid allocations, modifying the top element in the heap in-place was necessary. It dramatically improved performance of my scheduler.


I imagine if every item in the heap is a queue itself, you could use peek mut to get an item off the current max queue. After the modification, the former max element is sifted down to account for it's (probably) changed key.


The documentation really should mention the resifting, and why this is useful. It only mentions that the heap may be inconsistent if the `PeekMut` isn't properly dropped, without explaining why.

It's basically replacing the former (never stabilized) `push_pop` and `replace`, which Python folks can relate to similar methods in their `heapq`, for instance. With separate `push` and `pop` calls, the heap must be sifted twice, but with `peek_mut` you can update the head in-place and sift only once.


I agree-- you should send in a PR to the docs!


https://github.com/rust-lang/rfcs/issues/1626

Looks like it's to do something with the top data without the overhead of pop()+push()

Edit: ninja'd


Rust enthusiast here - thanks for contributing!


Optional JSON output for the compiler error messages is a really cool feature. This could improve web-technology-based Rust development (browsers, Electron apps), giving nice feedback to the editor, which could implement the error message highlighting right there in your code.


I'll just leave this here: https://github.com/nrc/rustw


It reminds me Play Framework!


https://github.com/rust-lang/sublime-rust has been making use of it already for its error parsing (image in link)


https://github.com/rust-lang/cargo/pull/2857

This will be nice. I couldn't possibly sell rust to my employers if we had to go to an outside source for packages like [EDIT: rust/crate currently does, with crates.io]. Being able to host our own mirrors (for CM purposes, if nothing else) is essential.


FWIW hosting your own mirror is possible today. It just requires a bit of work to match the crates.io format and specify it via .cargo/config (http://doc.crates.io/config.html). You can specify the index url as a "file://" and point it anywhere you like.

Definitely like this new approach though.


Thanks. My (limited) search for this a couple months back didn't turn anything up. This will be useful for my personal projects (I often work offline).


I like the look of this language, and loaded it up to play around with for the first time yesterday. This was the first thing that struck me when I compiled the obligatory hello world..

  09/29/2016  04:51 PM         1,746,638 main.exe
  09/29/2016  04:51 PM                43 main.rs
1.7Mb for the exe from 43 bytes of code on windows 10. :/

AllTheLibs? I'm hoping I can improve on that a bit.



Thanks for the link. It's a great read.


Note that Rust statically links in everything it needs by default, which is why hello world is so much larger in Rust than in C. :) If you want a hello world binary that's as small as C, there is a compiler flag for dynamically linking the generated binary.


A statically linked hello world in C using the MS toolchain gives me a 77Kb binary. The C++ version, using std::cout, is 176Kb.


5344 byte statically linked hello world in C:

    $ musl-gcc -static -Os -s -o hello hello.c
    $ ls -la hello
    -rwxrwxr-x. 1 sebastian sebastian 5344 Sep 30 06:22 hello
    $ ldd hello
	    not a dynamic executable
    $ ./hello 
    Hello, World
384 Byte hello world using NASM and ld on linux/amd64:

    BITS 64
    global _start
    
    %define SYS_write		1
    %define SYS_exit		60
    %define STDOUT_FILENO	1
    
    section .text
    _start:
    	call	after
    strHello:	db 'Hello, World!',10
    lenHello	equ $-strHello
    after:
    	pop		rsi
    	mov		rdx, lenHello
    	mov		rax, SYS_write
    	mov		rdi, STDOUT_FILENO
    	syscall
    
    	mov		rax, SYS_exit
    	xor		rdi, rdi
    	syscall
Most of the size overhead in the latter example comes from the ELF header, so by paying a bit more attention to the linker scripts, or just inlining a small ELF header with db in the asm file, it would be even smaller.

Just for size comparison. I am sure that it's quite possible to generate small Rust binaries as well.


  > I am sure that it's quite possible to generate small Rust 
  > binaries as well.
Indeed, here's a 151-byte hello world[0] in Rust: http://mainisusuallyafunction.blogspot.com/2015/01/151-byte-...


It's not clear (though it seems like no?) that the parent used options like LTO that would reduce the binary size.


I just literally installed the compiler toolset and did the first demo in the tutorial. I have never seen anything so large before, but I'm not a coder and not a windows coder.

The only windows code I have compiled has been FreePascal and that wasn't this crazy.

Similar to what sebcat showed above, I've done a bit of assembly on systems 8bit and up including nasm on linux, so not used to binaries with this sort of baggage. Wasn't trying to paint rust in a negative light, just came as a surprise when I ran that first compile.


It's all good! I'm not assuming any malice. First impressions are also very important.


Did you build in release mode?

    cargo build --release


No I wasn't aware of that, so thanks. I literally had just typed in the first example in the tute. :)

Working through more of it today.


Looks like you're using the GNU toolchain- for reference, the MSVC toolchain gives me a 107Kb exe from a 43-byte hello world.


1.7 megabytes is essential nothing in both modern disk/flash space and network costs. This isn't to say that efficient, small code isn't important, but it seems really common for a lot of programmers to freak out when there's some minimum executable size required for general "runtime" stuff, even when practically speaking it doesn't really matter in the real world outside of niche embedded system applications.

If each 43 bytes you compiled expanded to ANOTHER 1.7mb, then, yeah, that's not good, but that isn't the case here.


It might not matter to an individual user or developer, but if Rust is to be successful in the long run I think it's important for Rust-based desktop applications to be adopted.

If an application wants to be included in the standard install of, say, Ubuntu, one of the biggest costs from the Ubuntu maintainer's point of view is going to be "how much space will this take up on the iso, and what are we going to have to remove if we include this?" If the binaries are very small, it's a lot easier to make the case that they should be included.


It's easier for a distro to do dynamic linking for Rust binaries, since they can mandate a single compiler version across the ecosystem.


True. If dynamic linking is all that's needed to get tiny binaries, then that's probably sufficient from the distro's point of view.


I come from an assembly background (but spent the last 20 years doing scripting languages), so this came as a shock to me.


Now add up all the runtime stuff added by whatever scripting language you use and compare. Not many would come out ahead, Lua comes to mind.

The rust generated binary is statically linked and self-contained. It is pretty neat that it takes less than 2MB. In debug mode even, by the looks of it.


Congrats to the team and thank you!

As always, I've updated my Docker image for 1.12. Both the "1.12.0" and "latest" tags are now 1.12: https://hub.docker.com/r/jimmycuadra/rust/


Congratulations on all the good work to everyone!

Trying it out now.


The awesome thing about Rust is that the behemoths don't know about it.


I don't know. I wish that someone like MS would take this and really spend some big dollars on it. Mozilla is doing a great job but better collaboration between the vendors would be extremely beneficial and really increase its development. That's my hope anyway.


I mean, yeah, that would be amazing for the ecosystem. Still! I hope some small guy comes and makes something awesome with it, esp. w.r.t AI, which Rust seems sort of perfect for. As much potential as the Amazon-Microsoft-Google-Facebook-Acme Co. collab has, I'm not convinced that they aren't going to use it only to build dull chat bots and give us marginally more relevant ads.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: