Announcing Rust 1.30
blog.rust-lang.org
blog.rust-lang.org
Dhall [0] does that, additionally they allow using URL to import code.
[0]: https://github.com/dhall-lang/dhall-lang/blob/master/README....
Totally, fetching a single version through URLs works now, even on GitHub if you use tags. The tricky part is saying "I'm using 1.0, and 1.1 just came out, so I should upgrade to that." That requires ecosystem-wide agreement that everyone's going to use SemVer, and it assumes that everything's hosted in git or similar where there's a standard way to enumerate the available versions.
For example, tag v1.0: and a text at the bottom of the message "Next-Version: v1.1".
Or if one can enumerate versions/tags you could add back pointers to new versions/tags. Example, tag v1.1 with message including "Replaces-Version: v1.0".
One question I have about this update in particular: The raw identifiers syntax addition seems like syntax support for a convention. For example, I could use `r#for` or `_for` to solve the same problem, however, the first requires special syntax and the second doesn't. What does the syntax facilitate that a leading underscore doesn't?
For example, my 2015 crate might have a function `fn async(enabled: bool)` that I need to call from 2015. I could call it as `r#async(true)`.
This follows the existing syntax of `r"foo"` / `r###"foo"###` for raw strings as well as raw byte literals: `br##"HELO"##`;
Another use case will be for libraries like Diesel [0], a SQL query builder. People want to be able to search the documentation for SQL's `WHERE`, but `where` is keyword in Rust. They could choose to add a method called `r#where` to allow this kind of discoverability.
[0]: https://diesel.rs/
_async(true)2015 code:
fn async(enabled: bool) {}
fn _async(enabled: bool) {}
2018 code calling that: _async(true); // Which is this calling?This particular idea was not brought up during the RFC process, though several alternative syntaxes were. Leading underscore is already a thing in Rust, see shepmaster's posts on why this is not enough.
FWIW, we pretty much just followed existing languages here.
For example if you are using a crate with "dyn" as a method name then from 2015 you can call it via some_crate::dyn() but in 2018 you couldn't, since it's a keyword, but you could use some_crate::r#dyn(). That's the primary intent for this addition, though I believe some other use cases might be available as well.
After that, there's still some work that can be done towards NLL, specifically some details around how borrowing across functions works when the compiler "should" know that there actually isn't a borrow. This is part of some work codenamed "Polonius" [1], which should also improve the compiler time required to apply the borrow checker's rules.
Migration mode means that the MIR borrow check will run, and if it errors, then AST borrow check will run, and if that compiles successfully then the MIR borrow check errors will be downgraded to warnings. If MIR borrow check is successful then AST borrow check does not run and its errors will not impact the results.
Eventually we will enable MIR borrowck fully on all editions; I personally hope this happens sooner rather than later so we can delete the old code, but we have no concrete timeline just yet.
Besides the backward compatibility reason they might also be good for codegen tools. I encountered the situation multiple times that some identifier was used in an IDL (e.g. Thrift, Protobuf, etc) that then got exported into a keyword in a target language which prevented it from compiling. To word around that sometimes the IDL definition needed to be changed, which wasn't ideal. By generating only raw identifiers this can be avoided.
But yes, the `r#` isn't part of the name; if I define a Rust 2015 function as `fn async()`, in 2015 i can call it as just regular async() in 2015 code, and only need r#async() in Rust 2018 code.
And yeah, this is useful for codegen tools as well.