Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Announcing Rust 1.16 (rust-lang.org)
377 points by steveklabnik on March 16, 2017 | hide | past | favorite | 92 comments


Probably the most significant addition in this release is the cargo check subcommand, which does all the type/safety checking part of rustc, but skips the LLVM part of generating the actual binary.

If you just want to make sure you code compiles, this is the command for you.

There's also a bunch of API stablilizations around Strings, Vectors etc, complete changelog: https://github.com/rust-lang/rust/blob/master/RELEASES.md#ve...

Congratulations to everyone involved on the release!


Yes, this is huge. It dramatically reduces the code/does-it-compile cycle, which is far more important than the code/run cycle, for rust development.


-Z time-passes

Well played, Rust devs, well played. https://imgur.com/a/lK1BQ


Ha! I am pretty sure this is serendipity; -Z is our catch-all "unstable/internal flags" marker.


I might be a minority here, but can someone please update me on there state of Rust on iOS? I develop C++ cross platform iOS/Android apps and would love to use Rust if possible.

The last time I checked Rust didn't support .frameworks creation, didn't support Bitcode and calling the main thread from Rust wasn't easy.

I would love to hear if these issues have been resolved.


> The last time I checked Rust didn't support .frameworks creation

From a purely "how do I get something I can link to" perspective, you can still build a cdylib and a header for it, Xcode will let you include the header in your Objective-C code or in the Swift bridging header, and then you can link to the cdylib and copy it into the "Frameworks" subdirectory in the bundle at build time. I've been doing that in an OS X app for several months and it works out very well.

> calling the main thread from Rust wasn't easy.

If you want to schedule code to run in the main queue/thread/runloop, that's an Apple-specific thing Rust wouldn't be aware of by default, but I did find a wrapper for libdispatch/GCD, and it seems to support calling things on the main queue which should do what you want.

https://crates.io/crates/dispatch

You can also have your app provide a C callback to the Rust code (even a Swift closure with captured variables, with some clever workarounds since you can't do that by default), and then in the callback you can schedule code to run on the main queue/thread if you want.


You can't use dynamic libraries on iOS because they fail iTunes Connect validation. The only dylibs it allows are the Swift standard library. You can, however, use clang to take a static library and throw it into anything you want (framework, dylib, executable).


It looks like you're right, Apple says you can't bundle dylibs outside of a Framework on iOS :\

What would be the difference though, why make the distinction?

> Dynamic libraries outside of a framework bundle, which typically have the file extension .dylib, are not supported on iOS, watchOS, or tvOS, except for the system Swift libraries provided by Xcode.

https://developer.apple.com/library/content/technotes/tn2435...


From my understanding, the limitation is purely because of how Apple designed iTunes Connect validation, and not for technical reasons.


That's not true at all. You can use dynamic libraries; Swift modules produce .framework packages, which are dynamically linked.


I meant dylib files. You can't ship those, but you can ship dynamically linked frameworks.


AFAIK the only difference between a dylib and a framework is the folder structure (and I guess the install path of the library). So in theory you could produce a cdylib, create a framework folder structure for it, and then use install_name_tool to update the install name appropriately.


That's what I thought, too, but I was reminded of the filetype field in the mach_header which has distinct MH_DYLIB and MH_BUNDLE values. fwiw, I don't think that difference means much for the loading process, but they are different.


Hmm. I just ran `otool -hv /System/Library/Frameworks/Foundation.framework/Foundation` and it says the "filetype" header has the value "DYLIB". It looks like MH_BUNDLE is actually for plugin bundles, not for frameworks.


Oh, I see! That makes sense. Preference bundles are type "BUNDLE" but frameworks are not. TIL.


Ah, I see. Thanks for the clarification.


If you can avoid using a dylib on iOS, I would do it. It effects startup performance time. Just make a static version and compile it into the binary?


I'm aware of long polling of file/socket and libdispatch.dispatch_source to update main threads from BG on iOS/Android. I'll have to try that out and find if it works.

>You can also have your app provide a C callback to the Rust code

That's exactly what I'm doing, however callbacks become cumbersome after a while, and I don't like that pattern. I need to do MVVM where the View is a thin iOS/Android layer, and the VM is in Rust. Right now there are significant hurdles to keep references from Swift to Rust and vice versa.


I use Swift, Rust, tokio and lwIP in an iOS app to proxy traffic through Tor and they work very nicely together: https://github.com/icepa/icepa


This looks great, I'll check it out.

Thanks.


I hadn't heard of the .frameworks or "calling the main thread" problems; do you know if there are issues open?

Bitcode is tough, see https://github.com/rust-lang/rust/issues/35968

In general, we'd love to get this into better shape, but need some help from people with the time and expertise to hack on it.


Hey no worries, you guys are doing great!

To be fair to Rust, it does perfectly what it's supposed to do as a language on iOS/Android. I have a fully multithreaded toy Rust+Swift app that works fine, and the performance is pretty good. Most of the problems I described are due to the differences in the paradigms between Swift/Java and Rust. (OOP vs Functional), and I'm sure things will be fine with time.


Sorry for stealing the thread, on my case is Android/UWP.

Do you have any better approach to JNI calls other than Djinni, SafeJNI, SWIG, RPC-like with bulk of work on Java side?


> Do you have any better approach to JNI calls other than Djinni, SafeJNI, SWIG, RPC-like with bulk of work on Java side?

I use this homegrown solution on an Android app of mine which integrates with the CPython interpreter: https://github.com/joaoventura/pybridge/

It is RPC-like, but the code is quite simple: https://github.com/joaoventura/pybridge/#how-it-works. In the java-side, you just create a JSON object, send it to Python-land and get the result. Here's the java example in the code (https://goo.gl/sw4JLt) and here's the python function that it calls (https://goo.gl/hgbqVR).

Don't know if it's what you're looking for, or how it compares to the solutions you mentioned above, but I had someone from dropbox contributing a fix, and mentioning that going forward with a solution like this he would need something similar to djinni regarding error handling: https://github.com/joaoventura/pybridge/pull/3#issuecomment-...


Obrigado! :)

On my specific case it is more weekend programming, mainly focused on graphics and multimedia, so I can bare the ocasional pain for reading image files, being called as a service or interacting with the network related hardware.

Just wanted to have some heads up on other possibilities that I could be missing, from people that do it professionally.


Have you tried Loopers for Android to update main thread from NDK BG thread? I've seen people have success with that, but I personally didn't try it. AFAIK if you want to use MVVM pattern, there's no option than to use JNI.

We use Djinni extensively and it does what it advertises. We've to be careful with retain cycles and Djinni proxies create strong retain cycles if didn't configure correctly.

I'm actively looking into libdispatch for threading. I've heard of people having success with long polling of file/socket and dispatch_source to update main threads from BG on iOS/Android. I'll probably write a blog post if I succeed (and that's a big IF).


> Have you tried Loopers for Android to update main thread from NDK BG thread?

Not really, but I am aware of that pattern as it is the approach taken by SDL.

Thanks.


I haven't seen much on it. Doesn't mean solutions don't exist, but I regularly read updates on reddit and what people are working on, and I haven't seen much there. I feel like Swift is more likely to fill that role by coming to android.


I imagine just like with Objective-C, it will only happen with forks of the NDK, as Google has always removed it from clang builds.


for me it works great, a few quirks to configure xcode at first (like with most things in xcode when you need more than a 100% cocoa app), then now the workflow is unobtrusive. debugging also works from xcode, minus coloring of rust code.

my only concern is bitcode support, not feasible now due to a version mismatch between apple's llvm and rust's llvm (you can emit bitcode with rustc). which means currently you can ship apps for iOS, but not watchOS or tvOS.

(my use case of rust is DSP / audio synthesis)


I am glad that FreeBSD is on the "Tier 2" list of supported platforms [1] but am wondering, is there any way to convince you guys to make it "Tier 1"? If so, how?

I am willing to dedicate some amount of my own time to make it happen but am not convinced that my skills [2] and the amount of time I have available to spend is sufficient to make a difference.

[1]: https://forge.rust-lang.org/platform-support.html

[2]: https://www.github.com/eriknstr


I think it is unlikely we will make FreeBSD tier 1 any time soon. The project is stretched beyond its limits with its platform support commitments, and FreeBSD is historically difficult for us to support.

The next tier 1 is going to be ARM, probably for both Android and Linux, and then I personally don't see any others on the horizon. I actually see our tiers being redefined soon to be more graduated, and not have so many tier 2 commitments (we're happy to build artifacts for obscure platforms, less happy to be on the hook for guaranteeing obscure platforms continue to build - not saying FreeBSD specifically is 'obscure').

That said, the differences between tier 1 and tier 2 are not so great. If a platform has testing on CI then it is pretty close to tier 1, even if it's technically tier 2. The problem here is that testing the FreeBSD targets requires running FreeBSD in some way and that has been hard for our CI to do. Anything that can be crossed from Linux is easy, everything else is a painful special case. So with FreeBSD we do the the cross-building, but not the cross-testing. So the most effective thing to do to take Rust FreeBSD support to the next level is to figure out a way to get the CI to run tests.

There may be opportunities in the future for paid Rust platform support, where if a motivated party donates the right amount of money, we'll make it happen. I think that will have to happen to get some of the remaining platforms up to production quality.


>So the most effective thing to do to take Rust FreeBSD support to the next level is to figure out a way to get the CI to run tests.

If I were to set up my own FreeBSD buildbot for commits to the Rust repos, would result reports from my buildbot be welcome? Would automatic reports be useful to you, or should I manually inspect failures and write up a bug report / pull request with fixes for issues that arise? If automatic, how could I best integrate reports of failure with your development process for Rust?

>There may be opportunities in the future for paid Rust platform support, where if a motivated party donates the right amount of money, we'll make it happen. I think that will have to happen to get some of the remaining platforms up to production quality.

I like this idea though I don't have a lot of money to spend myself currently.


We no longer use buildbot for our CI.

We have a "meta CI" system called bors/homu that integrates with other CI, currently Travis and AppVeyor. bors works with any service that can post a result to a GitHub PR.

So the plan for supporting further architectures is to create a small custom runner that builds, tests and posts to the PR. That code does not exist yet, but if it appeared there are likely several upcoming architectures that could make use of it.

With that tool, we could allow contributors to set up their own integration bots and hook into our CI.


I've got scripts that I use for my own kernel development that spin up a VM (using kvm), run a test inside the VM and give you pass/fail and test output on stdout.

If anyone is interested, it'd probably be quite easy to adapt for running rust tests inside a FreeBSD vm:

https://evilpiepirate.org/git/ktest.git

If anyone is interested I'd be happy to walk someone through what it does and what parts you'd want.


Semi-official answer since this isn't an area I work on directly:

In general, the differences between Tier 2 and Tier 1 are:

1. Get tests running on every commit.

2. Gate building on those tests passing.

The first is a technical/money issue, the latter is a social issue. That is, getting all tests working is technical, being able to afford running them on every commit is monetary, but gating builds on failures on a platform is an issue of "who is responsible for making sure things stay passing."

Given that we run these tests on every commit, in some sense, it would be the PR author's job, but if they get stuck, we need someone who's able to help them fix that. That is the hardest part of moving from tier 2 to tier 1 in my personal opinion. Who is that person? What happens if they drop off the project?


>Given that we run these tests on every commit, in some sense, it would be the PR author's job, but if they get stuck, we need someone who's able to help them fix that. That is the hardest part of moving from tier 2 to tier 1 in my personal opinion. Who is that person? What happens if they drop off the project?

I would have liked to volunteer as the kind of person that would investigate issues for the FreeBSD platform but as I said, both my skills and my time are limited to the extent that they might not be sufficient.

As for what happens if the person responsible for this drops off the project, I think the solution to that is not so complicated; demote the platform back to tier 2 until someone else (if anyone ever) steps up to take over the responsibility.


Yeah, I think that policy is sound, it's just something we haven't actually done yet, so there are inevitable kinks to work out :)

I expect that your situation isn't uncommon, maybe the solution is two or three people rather than one. Raises that bar though...


One of the kinks is the longevity guarantee -- we kinda-sorta guarantee that Tier 1 platforms will "never" go away, but we can't as easily do that for a community thing. AIUI Tier 1 is something permanent that you can rely on always existing in the future.


>maybe the solution is two or three people rather than one

Sounds like a good idea to me. Personally I would be willing to work with a couple of other volunteers as long as we were able to get along.


I like rust a lot, but even hello world web apps compile (and recompile) so slowly. I barely get a single step down my to do list before recompiles take more than a second, and it makes it functionally unusable compared to other tools. I know this sounds silly, but it's true. I don't want the check, I want to see the webpage changed after my code changes. I keep hearing about incremental compiles but when I used nightly and tried turning it on, I guess it didn't work because compile times barely changed.


Incremental compilation doesn't incrementally typecheck yet. A lot of time is spent in typechecking.

The feature is designed so that incremental typechecking can happen—it just doesn't yet.


Incremental recompilation is still underway; expect some news on it reasonably soon. Even then, it's just the start, and there's more that we can do.


When it's out, can we actually get the same responsiveness as, let's say Java? I assume it also depends on the IDE but I would really like to see instant hints during coding session, ex. when I make mistakes.


You can already get instant hints now with VS Code and the Rust Language Server (RLS). It's still in alpha and the initial setup is a bit involved, but it already works very well for me.

https://github.com/rust-lang-nursery/rls

https://github.com/jonathandturner/rls_vscode

For some reason, code completion via Racer doesn't work yet for me via RLS, so I use the "old" RustyCode extension for that (https://github.com/saviorisdead/RustyCode).


I am not talking about code completion. I am talking about mistakes. Currently I have to build a project. With new Rust 1.16 I can check, but that's still a separate task that has to be launched manually. Yet, IntelliJ with Java will show you problems instantly, as well as gives you most probable options to solve them.


I wasn't only talking about code completion either - when I make any syntax/type error I get a red squiggly after about a second and hovering shows the compiler error (which often has hints for solving it). Same goes for compiler warnings (e.g. green squigglies for dead code). Feels quite close to IntelliJ already (I use PyCharm...).


I'm not sure what the lower bound is, to be honest. It's not a thing I personally work on.


Thank you SO MUCH for 'cargo check'! 5-times faster for our biggest project.


Although you broke your promise about avoiding breaking changes. I know I know, it wasn't promise and wasn't about breaking changes, it was something else about something else.

"The attribute `export_macro` is currently unknown to the compiler" - what a surprise in beta 1.17.


It's macro_export, not export_macro https://github.com/rust-lang/rust/issues/40487

That said, regressions happen, which is why beta exists. If you find them, please file them!


It's not in my lib and issue is filled. That said, thanks :)


I'm eagerly awaiting a release of RLS that is installable via rustup.


We're literally hacking on this right now. It should be part of the early June stable release.


It will probably end up being installed by `cargo install` anyway.

What I can't wait for is Tokio for Diesel and Rocket.


The plan is for it to be a component in rustup, rather than through cargo install. It needs to be extremely tied to the exact rust version you're on.


Have you found any good tutorials for Rocket? The one on Rocket's website is detailed but doesn't go beyond an extremely basic website.


The examples in the repo[1] are fairly extensive, and you can always ask questions in the IRC channel[2]. I've found #rocket to be extremely gracious with their time.

[1] https://github.com/SergioBenitez/Rocket/tree/master/examples

[2] https://riot.im/app/#/room/#mozilla_#rocket:matrix.org


Me too exactly


I'm wondering if the following will be one day possible with Rust. I want to build a fast data-store with the basic data-structures offered by Rust (e.g., std::collections), which are stored in a memory-mapped file. The problem with mmapped files is that they don't always appear at the same address (this is not always possible, especially if you open multiple stores at once). So in order to use the standard data-structures, Rust must provide some mechanism to make this possible (I realize that this can be tricky). Alternatively, I could write my own data-structures, but of course, I'd prefer to use the standard ones.


>I want to build a fast data-store

Usually this means you want to build things build on arrays.

>The problem with mmapped files is that they don't always appear at the same address

i.e. you use arrays and then index into the array instead of using pointers.

> So in order to use the standard data-structures, Rust must provide some mechanism to make this possible

Well, arrays exist in Rust. Or you're going to have to be more specific about what you're trying to do.


> Or you're going to have to be more specific about what you're trying to do.

I want to allocate arrays, maps, etcetera inside the region of a memory mapped file. Then, later, when I mmap the same file to a different region in memory, I want the arrays and maps to still work. That's all.


There are several mmap crates, but they won't let you transparently use std::collections on top of them.

I imagine this will be possible once the custom allocators work sorts out.


Just having custom allocators won't automatically fix the pointer issue: remapping the file later will leave the previously "allocated" pointers pointing into old memory, which may not be where the file was remapped.

The allocators and data structures would need to support using non-raw-pointer pointers types, including not even platform-pointer sized types.


Right. Makes sense.


As others have explained, it's definitely possible to construct those data structures in Rust and use them from a crate. But you can't just flip a switch to get the standard library collections to work that way.

You could probably get pretty far by copy pasting the standard library containers you're interested in and replace Box with something like OffsetBox which uses indices into your memmap arena instead of pointers to any addressable memory. Of course, implementing OffsetBox is an exercise for the reader. :)

You would probably have to write some unsafe code to get it to work. But it's not a blocker for a project.


Perhaps a solution would be to introduce the concept of relative pointers. I.e., the pointer becomes a signed value that should be added to the address of the pointer to obtain the address of the location pointed to. Not sure what the implications would be. Of course the standard data-structures would need to support such pointers.

After some searching, I found that Microsoft Visual Studio supports something similar, and exactly for the application I had in mind: [1].

[1] https://msdn.microsoft.com/en-us/library/57a97k4e.aspx


Do you have examples of how this works in other languages? I would assume they have specialized data structures for this purpose.



This releases fixes the #derived mess, right? Meaning we don't need to mess with weird build scripts to get serialization and json support?

Edit: so it was 1.15! I've been running 1.14 on my laptop and didn't realize it!


That came out in the last release, 1.15: https://blog.rust-lang.org/2017/02/02/Rust-1.15.html


That was 1.15, I believe. :-)


Since Rust people read hn... the version 1.16 is at the bottom of https://thanks.rust-lang.org/, while it should appear before 1.15


There's a bug open about this, and I am literally deploying the fix right now. It'll probably be fixed by the time you read this comment :) (EDIT: deployed successfully, refresh the page)

Thank you!


Hi Steve, thank you. Can you link the bug so that I know where to look at the next time?



1.16 already! Do they sleep ?


We used a time-based release schedule; each minor version comes out every six weeks. We believe this approach is better for a number of reasons, including quality.


But this is a thing that amazes me: the rust community manage to be incredibly productive while maintaining a culture of rigorous quality. In a world of "move fast and break things" at best and just of "I don't know what I'm doing" at worst I find it fascinating to witness.


Honestly, it's extremely taxing to maintain this pace without everything falling apart. The size of the team employed by Mozilla is quite modest. Firefox, which has a similar release schedule, has an entire team dedicated to just getting the releases out (though Firefox is yet the significantly larger product). We have no entire people, but employ some very rigorous testing.


>We have no entire people

You mean people dedicated to releases, or just that everyone must cut off an appendage to join the team? :)


I suspect Niko is part alien


The theory is that the "not rocket science" rule is a major reason why this is possible: http://graydon2.dreamwidth.org/1597.html .


The speed up for diesel appears mistyped.


Gah, I can't do basic math it seems. I'll fix it tomorrow.


If you have a previous version of Rust installed, getting Rust 1.16 is as easy as:

    $ rustup update stable
Nah. The old "rustup.sh" script doesn't install "rustup", the application.

Rust isn't in the Ubuntu distribution, either.

Stop rolling your own installer and use the distro programs. You are not a special snowflake.


It's hard for a software project to make progress if the only way to reach users is non-rolling distros. To a large extent, the progress of software in non-rolling distros relies on enough other people using the intermediate versions from outside the distro repo, in rolling distros or on Mac/Windows.

That said, Ubuntu​ does carry (an obsolete version of) Rust: http://packages.ubuntu.com/search?keywords=rustc&searchon=na...


> Nah. The old "rustup.sh" script doesn't install "rustup", the application.

rustup.sh has been deprecated for months now.

> Rust isn't in the Ubuntu distribution, either.

It's in Debian now, so (as far as I know) that means it should end up in Ubuntu soonish.

> Stop rolling your own installer and use the distro programs.

Not everyone is on Linux.


FWIW, Debian unstable is stuck on rustc 1.14.0. You need experimental to, at the moment, get 1.15.1 (no 1.16 yet, but it's a tad early for that ; but in multiple occasions it took weeks to get new rustc releases into Debian).

Cargo in Debian, on the other hand, is stuck on 0.15.0... (current version for "stable rust" is 0.17.0) ; no newer version in experimental...


Yeah, Stretch just missed 1.15, it's a shame IMHO. They're fine with it though.

Now that we've gotten a lot of the kinks worked out, hopefully it won't be weeks in the future.


Personally I love this feature in a build tool. The Stack tool for Haskell does the same, which means I can use the newest version very easily, without depending on some volunteer's Ubuntu PPA (which may not exist).


No need to be hostile.




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

Search: