Commit Graph

33 Commits

Author SHA1 Message Date
bors
44e3daf5ee Auto merge of #80459 - mark-i-m:or-pat-reg, r=petrochenkov
Implement edition-based macro :pat feature

This PR does two things:
1. Fixes the perf regression from https://github.com/rust-lang/rust/pull/80100#issuecomment-750893149
2. Implements `:pat2018` and `:pat2021` matchers, as described by `@joshtriplett`  in https://github.com/rust-lang/rust/issues/54883#issuecomment-745509090 behind the feature gate `edition_macro_pat`.

r? `@petrochenkov`

cc `@Mark-Simulacrum`
2020-12-31 14:52:26 +00:00
mark
40bf3c0f09 Implement edition-based macro pat feature 2020-12-30 09:57:49 -06:00
Yuki Okushi
4ae99cc843 Fix ICE when pointing at multi bytes character 2020-12-30 22:33:13 +09:00
mark
1a7d00a529 implement edition-specific :pat behavior for 2015/18 2020-12-19 07:13:36 -06:00
Aaron Hill
e6fa6334dd
Properly capture trailing 'unglued' token
If we try to capture the `Vec<u8>` in `Option<Vec<u8>>`, we'll
need to capture a `>` token which was 'unglued' from a `>>` token.
The processing of unglueing a token for parsing purposes bypasses the
usual capturing infrastructure, so we currently lose the trailing `>`.
As a result, we fall back to the reparsed `TokenStream`, causing us to
lose spans.

This commit makes token capturing keep track of a trailing 'unglued'
token. Note that we don't need to care about unglueing except at the end
of the captured tokens - if we capture both the first and second unglued
tokens, then we'll end up capturing the full 'glued' token, which
already works correctly.
2020-12-12 16:28:13 -05:00
Vadim Petrochenkov
31d72c2658 Accept arbitrary expressions in key-value attributes at parse time 2020-12-09 21:37:32 +03:00
Ryan Levick
823f64532c A slightly clearer diagnostic when misusing 2020-12-04 11:33:30 +01:00
Jonas Schievink
a732c3a369
Rollup merge of #78853 - calebcartwright:fix-const-block-expr-span, r=spastorino
rustc_parse: fix ConstBlock expr span

The span for a ConstBlock expression should presumably run through the end of the block it contains and not stop at the keyword, just like is done with similar block-containing expression kinds, such as a TryBlock
2020-11-28 15:58:15 +01:00
Aaron Hill
de88bf148b
Properly handle attributes on statements
We now collect tokens for the underlying node wrapped by `StmtKind`
instead of storing tokens directly in `Stmt`.

`LazyTokenStream` now supports capturing a trailing semicolon after it
is initially constructed. This allows us to avoid refactoring statement
parsing to wrap the parsing of the semicolon in `parse_tokens`.

Attributes on item statements
(e.g. `fn foo() { #[bar] struct MyStruct; }`) are now treated as
item attributes, not statement attributes, which is consistent with how
we handle attributes on other kinds of statements. The feature-gating
code is adjusted so that proc-macro attributes are still allowed on item
statements on stable.

Two built-in macros (`#[global_allocator]` and `#[test]`) needed to be
adjusted to support being passed `Annotatable::Stmt`.
2020-11-26 17:08:35 -05:00
Vadim Petrochenkov
2879ab793e rustc_parse: Remove optimization for 0-length streams in collect_tokens
The optimization conflates empty token streams with unknown token stream, which is at least suspicious, and doesn't affect performance because 0-length token streams are very rare.
2020-11-12 22:00:48 +03:00
Caleb Cartwright
e1d5c3c054 fix(rustc_parse): ConstBlock expr span 2020-11-07 14:33:34 -06:00
Vadim Petrochenkov
d0c63bccc5 parser: Cleanup LazyTokenStream and avoid some clones
by using a named struct instead of a closure.
2020-10-31 01:56:34 +03:00
bors
20b1e05a8d Auto merge of #77502 - varkor:const-generics-suggest-enclosing-braces, r=petrochenkov
Suggest that expressions that look like const generic arguments should be enclosed in brackets

I pulled out the changes for const expressions from https://github.com/rust-lang/rust/pull/71592 (without the trait object diagnostic changes) and made some small changes; the implementation is `@estebank's.`

We're also going to want to make some changes separately to account for trait objects (they result in poor diagnostics, as is evident from one of the test cases here), such as an adaption of https://github.com/rust-lang/rust/pull/72273.

Fixes https://github.com/rust-lang/rust/issues/70753.

r? `@petrochenkov`
2020-10-27 09:25:54 +00:00
varkor
ac1454001c Suggest expressions that look like const generic arguments should be enclosed in brackets
Co-Authored-By: Esteban Kuber <github@kuber.com.ar>
2020-10-26 21:54:45 +00:00
bors
ffa2e7ae8f Auto merge of #77255 - Aaron1011:feature/collect-attr-tokens, r=petrochenkov
Unconditionally capture tokens for attributes.

This allows us to avoid synthesizing tokens in `prepend_attr`, since we
have the original tokens available.

We still need to synthesize tokens when expanding `cfg_attr`,
but this is an unavoidable consequence of the syntax of `cfg_attr` -
the user does not supply the `#` and `[]` tokens that a `cfg_attr`
expands to.

This is based on PR https://github.com/rust-lang/rust/pull/77250 - this PR exposes a bug in the current `collect_tokens` implementation, which is fixed by the rewrite.
2020-10-24 19:23:32 +00:00
Santiago Pastorino
83abed9df6
Make inline const work for half open ranges 2020-10-22 13:22:12 -03:00
Santiago Pastorino
954b5a81b4
Rename parse_const_expr to parse_const_block 2020-10-22 13:21:18 -03:00
Aaron Hill
920bed1213
Don't create an empty LazyTokenStream 2020-10-22 10:09:08 -04:00
bors
22e6b9c689 Auto merge of #77250 - Aaron1011:feature/flat-token-collection, r=petrochenkov
Rewrite `collect_tokens` implementations to use a flattened buffer

Instead of trying to collect tokens at each depth, we 'flatten' the
stream as we go allong, pushing open/close delimiters to our buffer
just like regular tokens. One capturing is complete, we reconstruct a
nested `TokenTree::Delimited` structure, producing a normal
`TokenStream`.

The reconstructed `TokenStream` is not created immediately - instead, it is
produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This
closure stores a clone of the original `TokenCursor`, plus a record of the
number of calls to `next()/next_desugared()`. This is sufficient to reconstruct
the tokenstream seen by the callback without storing any additional state. If
the tokenstream is never used (e.g. when a captured `macro_rules!` argument is
never passed to a proc macro), we never actually create a `TokenStream`.

This implementation has a number of advantages over the previous one:

* It is significantly simpler, with no edge cases around capturing the
  start/end of a delimited group.

* It can be easily extended to allow replacing tokens an an arbitrary
  'depth' by just using `Vec::splice` at the proper position. This is
  important for PR #76130, which requires us to track information about
  attributes along with tokens.

* The lazy approach to `TokenStream` construction allows us to easily
  parse an AST struct, and then decide after the fact whether we need a
  `TokenStream`. This will be useful when we start collecting tokens for
  `Attribute` - we can discard the `LazyTokenStream` if the parsed
  attribute doesn't need tokens (e.g. is a builtin attribute).

The performance impact seems to be neglibile (see
https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a
small slowdown on a few benchmarks, but it only rises above 1% for incremental
builds, where it represents a larger fraction of the much smaller instruction
count. There a ~1% speedup on a few other incremental benchmarks - my guess is
that the speedups and slowdowns will usually cancel out in practice.
2020-10-21 15:03:14 +00:00
Yuki Okushi
de24210ebf
Rollup merge of #78118 - spastorino:inline-const-followups, r=petrochenkov
Inline const followups

r? @petrochenkov

Follow ups of #77124
2020-10-21 13:59:44 +09:00
Santiago Pastorino
d641cb82c1
Allow NtBlock to parse on check inline const next token 2020-10-19 18:50:58 -03:00
Aaron Hill
593fdd3d45
Rewrite collect_tokens implementations to use a flattened buffer
Instead of trying to collect tokens at each depth, we 'flatten' the
stream as we go allong, pushing open/close delimiters to our buffer
just like regular tokens. One capturing is complete, we reconstruct a
nested `TokenTree::Delimited` structure, producing a normal
`TokenStream`.

The reconstructed `TokenStream` is not created immediately - instead, it is
produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This
closure stores a clone of the original `TokenCursor`, plus a record of the
number of calls to `next()/next_desugared()`. This is sufficient to reconstruct
the tokenstream seen by the callback without storing any additional state. If
the tokenstream is never used (e.g. when a captured `macro_rules!` argument is
never passed to a proc macro), we never actually create a `TokenStream`.

This implementation has a number of advantages over the previous one:

* It is significantly simpler, with no edge cases around capturing the
  start/end of a delimited group.

* It can be easily extended to allow replacing tokens an an arbitrary
  'depth' by just using `Vec::splice` at the proper position. This is
  important for PR #76130, which requires us to track information about
  attributes along with tokens.

* The lazy approach to `TokenStream` construction allows us to easily
  parse an AST struct, and then decide after the fact whether we need a
  `TokenStream`. This will be useful when we start collecting tokens for
  `Attribute` - we can discard the `LazyTokenStream` if the parsed
  attribute doesn't need tokens (e.g. is a builtin attribute).

The performance impact seems to be neglibile (see
https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a
small slowdown on a few benchmarks, but it only rises above 1% for incremental
builds, where it represents a larger fraction of the much smaller instruction
count. There a ~1% speedup on a few other incremental benchmarks - my guess is
that the speedups and slowdowns will usually cancel out in practice.
2020-10-19 13:59:18 -04:00
Aaron Hill
f6aec82d4d
Avoid cloning the contents of a TokenStream in a few places 2020-10-19 12:30:41 -04:00
Santiago Pastorino
c3e8d7965c
Parse inline const expressions 2020-10-16 15:15:30 -03:00
Esteban Küber
e5f83bcd04 Detect blocks that could be struct expr bodies
This approach lives exclusively in the parser, so struct expr bodies
that are syntactically correct on their own but are otherwise incorrect
will still emit confusing errors, like in the following case:

```rust
fn foo() -> Foo {
    bar: Vec::new()
}
```

```
error[E0425]: cannot find value `bar` in this scope
 --> src/file.rs:5:5
  |
5 |     bar: Vec::new()
  |     ^^^ expecting a type here because of type ascription

error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
 --> src/file.rs:5:15
  |
5 |     bar: Vec::new()
  |               ^^^^^ only `Fn` traits may use parentheses

error[E0107]: wrong number of type arguments: expected 1, found 0
 --> src/file.rs:5:10
  |
5 |     bar: Vec::new()
  |          ^^^^^^^^^^ expected 1 type argument
  ```

If that field had a trailing comma, that would be a parse error and it
would trigger the new, more targetted, error:

```
error: struct literal body without path
 --> file.rs:4:17
  |
4 |   fn foo() -> Foo {
  |  _________________^
5 | |     bar: Vec::new(),
6 | | }
  | |_^
  |
help: you might have forgotten to add the struct literal inside the block
  |
4 | fn foo() -> Foo { Path {
5 |     bar: Vec::new(),
6 | } }
  |
```

Partially address last part of #34255.
2020-10-07 13:40:52 -07:00
Vadim Petrochenkov
219c66c55c rustc_parse: Make Parser::unexpected public and use it in built-in macros 2020-10-06 00:23:36 +03:00
Aurélien Deharbe
62068a59ee repairing broken error message and rustfix application for the new test
case
2020-09-11 17:31:52 +02:00
Aaron Hill
c1011165e6
Attach TokenStream to ast::Visibility
A `Visibility` does not have outer attributes, so we only capture tokens
when parsing a `macro_rules!` matcher
2020-09-10 17:33:06 -04:00
Aleksey Kladov
ccf41dd5eb Rename IsJoint -> Spacing
To match better naming from proc-macro
2020-09-03 17:32:45 +02:00
bors
80fc9b0ecb Auto merge of #76160 - scileo:format-recovery, r=petrochenkov
Improve recovery on malformed format call

The token following a format expression should be a comma. However, when it is replaced with a similar token (such as a dot), then the corresponding error is emitted, but the token is treated as a comma, and the parsing step continues.

r? @petrochenkov
2020-09-02 19:29:27 +00:00
Sasha
3524c3ef43 Improve recovery on malformed format call
If a comma in a format call is replaced with a similar token, then we
emit an error and continue parsing, instead of stopping at this point.
2020-09-02 13:18:19 +02:00
Caleb Cartwright
883b1e7592 parser: restore some fn visibility for rustfmt 2020-08-30 13:04:36 -05:00
mark
9e5f7d5631 mv compiler to compiler/ 2020-08-30 18:45:07 +03:00