| Age | Commit message (Collapse) | Author | Lines |
|
|
|
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
|
|
|
|
|
|
|
|
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
Co-authored-by: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
|
|
|
|
By replacing them with `{Open,Close}{Param,Brace,Bracket,Invisible}`.
PR #137902 made `ast::TokenKind` more like `lexer::TokenKind` by
replacing the compound `BinOp{,Eq}(BinOpToken)` variants with fieldless
variants `Plus`, `Minus`, `Star`, etc. This commit does a similar thing
with delimiters. It also makes `ast::TokenKind` more similar to
`parser::TokenType`.
This requires a few new methods:
- `TokenKind::is_{,open_,close_}delim()` replace various kinds of
pattern matches.
- `Delimiter::as_{open,close}_token_kind` are used to convert
`Delimiter` values to `TokenKind`.
Despite these additions, it's a net reduction in lines of code. This is
because e.g. `token::OpenParen` is so much shorter than
`token::OpenDelim(Delimiter::Parenthesis)` that many multi-line forms
reduce to single line forms. And many places where the number of lines
doesn't change are still easier to read, just because the names are
shorter, e.g.:
```
- } else if self.token != token::CloseDelim(Delimiter::Brace) {
+ } else if self.token != token::CloseBrace {
```
|
|
Type ascription syntax was removed in 2023.
|
|
|
|
`BinOpToken` is badly named, because it only covers the assignable
binary ops and excludes comparisons and `&&`/`||`. Its use in
`ast::TokenKind` does allow a small amount of code sharing, but it's a
clumsy factoring.
This commit removes `ast::TokenKind::BinOp{,Eq}`, replacing each one
with 10 individual variants. This makes `ast::TokenKind` more similar to
`rustc_lexer::TokenKind`, which has individual variants for all
operators.
Although the number of lines of code increases, the number of chars
decreases due to the frequent use of shorter names like `token::Plus`
instead of `token::BinOp(BinOpToken::Plus)`.
|
|
Tweak invalid RTN errors
Make suggestions verbose.
When encountering `method(type)` bound, suggest `method(..)` instead of `method()`.
```
error: argument types not allowed with return type notation
--> $DIR/bad-inputs-and-output.rs:9:23
|
LL | fn foo<T: Trait<method(i32): Send>>() {}
| ^^^^^
|
help: remove the input types
|
LL - fn foo<T: Trait<method(i32): Send>>() {}
LL + fn foo<T: Trait<method(..): Send>>() {}
|
```
When encountering both return type and arg list that isn't `..`, suggest replacing both.
```
error: return type not allowed with return type notation
--> $DIR/bad-inputs-and-output.rs:12:25
|
LL | fn bar<T: Trait<method() -> (): Send>>() {}
| ^^^^^^
|
help: use the right argument notation and remove the return type
|
LL - fn bar<T: Trait<method() -> (): Send>>() {}
LL + fn bar<T: Trait<method(..): Send>>() {}
|
```
When encountering a return type, suggest removing it including the leading whitespace.
```
error: return type not allowed with return type notation
--> $DIR/bad-inputs-and-output.rs:24:45
|
LL | fn bay_path<T: Trait>() where T::method(..) -> (): Send {}
| ^^^^^
|
help: remove the return type
|
LL - fn bay_path<T: Trait>() where T::method(..) -> (): Send {}
LL + fn bay_path<T: Trait>() where T::method(..): Send {}
|
```
r? ``@compiler-errors``
|
|
Make suggestions verbose.
When encountering `method(type)` bound, suggest `method(..)` instead of `method()`.
```
error: argument types not allowed with return type notation
--> $DIR/bad-inputs-and-output.rs:9:23
|
LL | fn foo<T: Trait<method(i32): Send>>() {}
| ^^^^^
|
help: remove the input types
|
LL - fn foo<T: Trait<method(i32): Send>>() {}
LL + fn foo<T: Trait<method(..): Send>>() {}
|
```
When encountering both return type and arg list that isn't `..`, suggest replacing both.
```
error: return type not allowed with return type notation
--> $DIR/bad-inputs-and-output.rs:12:25
|
LL | fn bar<T: Trait<method() -> (): Send>>() {}
| ^^^^^^
|
help: use the right argument notation and remove the return type
|
LL - fn bar<T: Trait<method() -> (): Send>>() {}
LL + fn bar<T: Trait<method(..): Send>>() {}
|
```
When encountering a return type, suggest removing it including the leading whitespace.
```
error: return type not allowed with return type notation
--> $DIR/bad-inputs-and-output.rs:24:45
|
LL | fn bay_path<T: Trait>() where T::method(..) -> (): Send {}
| ^^^^^
|
help: remove the return type
|
LL - fn bay_path<T: Trait>() where T::method(..) -> (): Send {}
LL + fn bay_path<T: Trait>() where T::method(..): Send {}
|
```
|
|
|
|
|
|
Notes about tests:
- tests/ui/parser/macro/trait-object-macro-matcher.rs: the syntax error
is duplicated, because it occurs now when parsing the decl macro
input, and also when parsing the expanded decl macro. But this won't
show up for normal users due to error de-duplication.
- tests/ui/associated-consts/issue-93835.rs: similar, plus there are
some additional errors about this very broken code.
- The changes to metavariable descriptions in #132629 are now visible in
error message for several tests.
|
|
|
|
|
|
Instead use dcx.abort_if_error() or guar.raise_fatal() instead. These
guarantee that an error actually happened previously and thus we don't
silently abort.
|
|
The parser pushes a `TokenType` to `Parser::expected_token_types` on
every call to the various `check`/`eat` methods, and clears it on every
call to `bump`. Some of those `TokenType` values are full tokens that
require cloning and dropping. This is a *lot* of work for something
that is only used in error messages and it accounts for a significant
fraction of parsing execution time.
This commit overhauls `TokenType` so that `Parser::expected_token_types`
can be implemented as a bitset. This requires changing `TokenType` to a
C-style parameterless enum, and adding `TokenTypeSet` which uses a
`u128` for the bits. (The new `TokenType` has 105 variants.)
The new types `ExpTokenPair` and `ExpKeywordPair` are now arguments to
the `check`/`eat` methods. This is for maximum speed. The elements in
the pairs are always statically known; e.g. a
`token::BinOp(token::Star)` is always paired with a `TokenType::Star`.
So we now compute `TokenType`s in advance and pass them in to
`check`/`eat` rather than the current approach of constructing them on
insertion into `expected_token_types`.
Values of these pair types can be produced by the new `exp!` macro,
which is used at every `check`/`eat` call site. The macro is for
convenience, allowing any pair to be generated from a single identifier.
The ident/keyword filtering in `expected_one_of_not_found` is no longer
necessary. It was there to account for some sloppiness in
`TokenKind`/`TokenType` comparisons.
The existing `TokenType` is moved to a new file `token_type.rs`, and all
its new infrastructure is added to that file. There is more boilerplate
code than I would like, but I can't see how to make it shorter.
|
|
Because the `Token` type is similar to but different to the `TokenType`
type, and the difference is important, so we want to avoid confusion.
|
|
`rustc_span::symbol` defines some things that are re-exported from
`rustc_span`, such as `Symbol` and `sym`. But it doesn't re-export some
closely related things such as `Ident` and `kw`. So you can do `use
rustc_span::{Symbol, sym}` but you have to do `use
rustc_span::symbol::{Ident, kw}`, which is inconsistent for no good
reason.
This commit re-exports `Ident`, `kw`, and `MacroRulesNormalizedIdent`,
and changes many `rustc_span::symbol::` qualifiers in `compiler/` to
`rustc_span::`. This is a 200+ net line of code reduction, mostly
because many files with two `use rustc_span` items can be reduced to
one.
|
|
Co-authored-by: Max Niederman <max@maxniederman.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This commit does the following.
- Renames `collect_tokens_trailing_token` as `collect_tokens`, because
(a) it's annoying long, and (b) the `_trailing_token` bit is less
accurate now that its types have changed.
- In `collect_tokens`, adds a `Option<CollectPos>` argument and a
`UsePreAttrPos` in the return type of `f`. These are used in
`parse_expr_force_collect` (for vanilla expressions) and in
`parse_stmt_without_recovery` (for two different cases of expression
statements). Together these ensure are enough to fix all the problems
with token collection and assoc expressions. The changes to the
`stringify.rs` test demonstrate some of these.
- Adds a new test. The code in this test was causing an assertion
failure prior to this commit, due to an invalid `NodeRange`.
The extra complexity is annoying, but necessary to fix the existing
problems.
|
|
This lets us compare a `Token` with a `TokenKind`. It's used a lot, but
can be used even more, avoiding the need for some `.kind` uses.
|
|
|
|
|
|
The previous commit updated `rustfmt.toml` appropriately. This commit is
the outcome of running `x fmt --all` with the new formatting options.
|
|
|
|
|
|
This removes the final `Option<AttrWrapper>` argument.
|
|
|
|
|
|
```rust
reuse prefix::{a, b, c}
```
|
|
This span records the declaration of the metavariable in the LHS of the macro.
It's used in a couple of error messages. Unfortunately, it gets in the way of
the long-term goal of removing `TokenKind::Interpolated`. So this commit
removes it, which degrades a couple of (obscure) error messages but makes
things simpler and enables the next commit.
|
|
|
|
|
|
|
|
|
|
Do not use `?`-induced skewing of type inference in the compiler
This prevents breakage from #122412 and is generally a good idea.
r? `@estebank`
|
|
Stabilize associated type bounds (RFC 2289)
This PR stabilizes associated type bounds, which were laid out in [RFC 2289]. This gives us a shorthand to express nested type bounds that would otherwise need to be expressed with nested `impl Trait` or broken into several `where` clauses.
### What are we stabilizing?
We're stabilizing the associated item bounds syntax, which allows us to put bounds in associated type position within other bounds, i.e. `T: Trait<Assoc: Bounds...>`. See [RFC 2289] for motivation.
In all position, the associated type bound syntax expands into a set of two (or more) bounds, and never anything else (see "How does this differ[...]" section for more info).
Associated type bounds are stabilized in four positions:
* **`where` clauses (and APIT)** - This is equivalent to breaking up the bound into two (or more) `where` clauses. For example, `where T: Trait<Assoc: Bound>` is equivalent to `where T: Trait, <T as Trait>::Assoc: Bound`.
* **Supertraits** - Similar to above, `trait CopyIterator: Iterator<Item: Copy> {}`. This is almost equivalent to breaking up the bound into two (or more) `where` clauses; however, the bound on the associated item is implied whenever the trait is used. See #112573/#112629.
* **Associated type item bounds** - This allows constraining the *nested* rigid projections that are associated with a trait's associated types. e.g. `trait Trait { type Assoc: Trait2<Assoc2: Copy>; }`.
* **opaque item bounds (RPIT, TAIT)** - This allows constraining associated types that are associated with the opaque without having to *name* the opaque. For example, `impl Iterator<Item: Copy>` defines an iterator whose item is `Copy` without having to actually name that item bound.
The latter three are not expressible in surface Rust (though for associated type item bounds, this will change in #120752, which I don't believe should block this PR), so this does represent a slight expansion of what can be expressed in trait bounds.
### How does this differ from the RFC?
Compared to the RFC, the current implementation *always* desugars associated type bounds to sets of `ty::Clause`s internally. Specifically, it does *not* introduce a position-dependent desugaring as laid out in [RFC 2289], and in particular:
* It does *not* desugar to anonymous associated items in associated type item bounds.
* It does *not* desugar to nested RPITs in RPIT bounds, nor nested TAITs in TAIT bounds.
This position-dependent desugaring laid out in the RFC existed simply to side-step limitations of the trait solver, which have mostly been fixed in #120584. The desugaring laid out in the RFC also added unnecessary complication to the design of the feature, and introduces its own limitations to, for example:
* Conditionally lowering to nested `impl Trait` in certain positions such as RPIT and TAIT means that we inherit the limitations of RPIT/TAIT, namely lack of support for higher-ranked opaque inference. See this code example: https://github.com/rust-lang/rust/pull/120752#issuecomment-1979412531.
* Introducing anonymous associated types makes traits no longer object safe, since anonymous associated types are not nameable, and all associated types must be named in `dyn` types.
This last point motivates why this PR is *not* stabilizing support for associated type bounds in `dyn` types, e.g, `dyn Assoc<Item: Bound>`. Why? Because `dyn` types need to have *concrete* types for all associated items, this would necessitate a distinct lowering for associated type bounds, which seems both complicated and unnecessary compared to just requiring the user to write `impl Trait` themselves. See #120719.
### Implementation history:
Limited to the significant behavioral changes and fixes and relevant PRs, ping me if I left something out--
* #57428
* #108063
* #110512
* #112629
* #120719
* #120584
Closes #52662
[RFC 2289]: https://rust-lang.github.io/rfcs/2289-associated-type-bounds.html
|
|
This prevents breakage when `?` no longer skews inference.
|
|
|