Make FileMap::{lines, multibyte_chars, non_narrow_chars} non-mutable.
This PR removes most of the interior mutability from `FileMap`, which should be beneficial, especially in a multithreaded setting. This is achieved by initializing the state in question when the filemap is constructed instead of during lexing. Hopefully this doesn't degrade performance.
cc @wesleywiser
The method relied on the FileMap still being under construction in
order for it to do what the name promises. It's now independent of
the current state.
Namely: labels, type parameters, bindings in patterns, parameter names in functions without body.
All of these do not need hygiene after lowering to HIR, only span locations.
Our implementation ends up changing the `PatKind::Range` variant in the
AST to take a `Spanned<RangeEnd>` instead of just a `RangeEnd`, because
the alternative would be to try to infer the span of the range operator
from the spans of the start and end subexpressions, which is both
hideous and nontrivial to get right (whereas getting the change to the
AST right was a simple game of type tennis).
This is concerning #51043.
Now that `..=` inclusive ranges are stabilized, people probably
shouldn't be using `...` even in patterns, even if it's still legal
there (see #51043). To avoid drawing attention to `...` being a real
thing, let's reword this message to just say "unexpected token" rather
"cannot be used in expressions".
async/await
This PR implements `async`/`await` syntax for `async fn` in Rust 2015 and `async` closures and `async` blocks in Rust 2018 (tracking issue: https://github.com/rust-lang/rust/issues/50547). Limitations: non-`move` async closures with arguments are currently not supported, nor are `async fn` with multiple different input lifetimes. These limitations are not fundamental and will be removed in the future, however I'd like to go ahead and get this PR merged so we can start experimenting with this in combination with futures 0.3.
Based on https://github.com/rust-lang/rust/pull/51414.
cc @petrochenkov for parsing changes.
r? @eddyb
Rollup of 6 pull requests
Successful merges:
- #51158 (Mention spec and indented blocks in doctest docs)
- #51629 (Do not consume semicolon twice while parsing local statement)
- #51637 (Update zx_cprng_draw_new on Fuchsia)
- #51664 (make more libsyntax methods public)
- #51666 (Disable probestack when GCOV profiling is being used)
- #51703 (Recognize the extra "LLVM tools versions" argument to build-manifest.)
Failed merges:
r? @ghost
make more libsyntax methods public
Followup for #51502, which was sufficient only for the latest stable release of Rocket. The `master` branch uses a few more. I plan to reimplement the deleted method `parse_seq` in Rocket (see SergioBenitez/Rocket#666), rather than resurrecting it in libsyntax.
r? @Mark-Simulacrum
Do not consume semicolon twice while parsing local statement
The span for a `let` statement includes multiple semicolons. For example,
```rust
let x = 2;;;
// ^^^^^^^^^^^ The span for the above statement.
```
This PR fixes it.
cc https://github.com/rust-lang-nursery/rustfmt/issues/2791.
This is gated on edition 2018 & the `async_await` feature gate.
The parser will accept `async fn` and `async unsafe fn` as fn
items. Along the same lines as `const fn`, only `async unsafe fn`
is permitted, not `unsafe async fn`.The parser will not accept
`async` functions as trait methods.
To do a little code clean up, four fields of the function type
struct have been merged into the new `FnHeader` struct: constness,
asyncness, unsafety, and ABI.
Also, a small bug in HIR printing is fixed: it previously printed
`const unsafe fn` as `unsafe const fn`, which is grammatically
incorrect.
Various changes to existing diagnostics
* [Add code to `invalid ABI` error, add span label, move list to help to make message shorter](23ae5af274):
```
error[E0697]: invalid ABI: found `路濫狼á́́`
--> $DIR/unicode.rs:11:8
|
LL | extern "路濫狼á́́" fn foo() {} //~ ERROR invalid ABI
| ^^^^^^^^^ invalid ABI
|
= help: valid ABIs: cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
```
* [Add code to incorrect `pub` restriction error](e96fdea8a3)
* [Add message to `rustc_on_unimplemented` attributes in core to have them set a custom message _and_ label](2cc7e5ed30):
```
error[E0277]: `W` does not have a constant size known at compile-time
--> $DIR/unsized-enum2.rs:33:8
|
LL | VA(W),
| ^ `W` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `W`
= help: consider adding a `where W: std::marker::Sized` bound
= note: no field of an enum variant may have a dynamically sized type
```
```
error[E0277]: `Foo` cannot be sent between threads safely
--> $DIR/E0277-2.rs:26:5
|
LL | is_send::<Foo>();
| ^^^^^^^^^^^^^^ `Foo` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `Foo`
```
```
error[E0277]: can't compare `{integer}` with `std::string::String`
--> $DIR/binops.rs:16:7
|
LL | 5 < String::new();
| ^ no implementation for `{integer} < std::string::String` and `{integer} > std::string::String`
|
= help: the trait `std::cmp::PartialOrd<std::string::String>` is not implemented for `{integer}`
```
```
error[E0277]: can't compare `{integer}` with `std::result::Result<{integer}, _>`
--> $DIR/binops.rs:17:7
|
LL | 6 == Ok(1);
| ^^ no implementation for `{integer} == std::result::Result<{integer}, _>`
|
= help: the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}`
```
```
error[E0277]: a collection of type `i32` cannot be built from an iterator over elements of type `i32`
--> $DIR/type-check-defaults.rs:16:19
|
LL | struct WellFormed<Z = Foo<i32, i32>>(Z);
| ^ a collection of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
|
= help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
note: required by `Foo`
--> $DIR/type-check-defaults.rs:15:1
|
LL | struct Foo<T, U: FromIterator<T>>(T, U);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
* [Add link to book for `Sized` errors](1244dc7c28):
```
error[E0277]: `std::fmt::Debug + std::marker::Sync + 'static` does not have a constant size known at compile-time
--> $DIR/const-unsized.rs:13:29
|
LL | const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
| ^^^^^^^^^^^^^^^^^^^^^^ `std::fmt::Debug + std::marker::Sync + 'static` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Sync + 'static`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: constant expressions must have a statically known size
```
* [Point to previous line for single expected token not found](48165168fb) (if the current token is in a different line)