implement Ord for OutlivesPredicate and other types
It became necessary while implementing https://github.com/rust-lang/rust/pull/50070 to have `Ord` implemented for `OutlivesPredicate`.
This PR implements `Ord` for `OutlivesPredicate` as well as other types needed for the implementation.
Fix span for type-only arguments
Currently it points to the comma or parenthesis before the type, which is broken
cc @mark-i-m this is what broke #48309
r? @estebank
rustc: Correctly pretty-print macro delimiters
This commit updates the `Mac_` AST structure to keep track of the delimiters
that it originally had for its invocation. This allows us to faithfully
pretty-print macro invocations not using parentheses (e.g. `vec![...]`). This in
turn helps procedural macros due to #43081.
Closes#50840
This commit updates the `Mac_` AST structure to keep track of the delimiters
that it originally had for its invocation. This allows us to faithfully
pretty-print macro invocations not using parentheses (e.g. `vec![...]`). This in
turn helps procedural macros due to #43081.
Closes#50840
rustc: Fix procedural macros generating lifetime tokens
This commit fixes an accidental regression from #50473 where lifetime tokens
produced by procedural macros ended up getting lost in translation in the
compiler and not actually producing parseable code. The issue lies in the fact
that a lifetime's `Ident` is prefixed with `'`. The `glue` implementation for
gluing joint tokens together forgot to take this into account so the lifetime
inside of `Ident` was missing the leading tick!
The `glue` implementation here is updated to create a new `Symbol` in these
situations to manufacture a new `Ident` with a leading tick to ensure it parses
correctly.
Closes#50942
rustc: Fix joint-ness of stringified token-streams
This commit fixes `StringReader`'s parsing of tokens which have been stringified
through procedural macros. Whether or not a token tree is joint is defined by
span information, but when working with procedural macros these spans are often
dummy and/or overridden which means that they end up considering all operators
joint if they can!
The fix here is to track the raw source span as opposed to the overridden span.
With this information we can more accurately classify `Punct` structs as either
joint or not.
Closes#50700
This commit fixes an accidental regression from #50473 where lifetime tokens
produced by procedural macros ended up getting lost in translation in the
compiler and not actually producing parseable code. The issue lies in the fact
that a lifetime's `Ident` is prefixed with `'`. The `glue` implementation for
gluing joint tokens together forgot to take this into account so the lifetime
inside of `Ident` was missing the leading tick!
The `glue` implementation here is updated to create a new `Symbol` in these
situations to manufacture a new `Ident` with a leading tick to ensure it parses
correctly.
Closes#50942
lexer: Fix span override for the first token in a string
Previously due to peculiarities of `StringReader` construction something like `"a b c d".parse::<TokenStream>()` gave you one non-overridden span for `a` and then three correctly overridden spans for `b`, `c` and `d`.
Now all the spans are overridden.
rustc: introduce {ast,hir}::AnonConst to consolidate so-called "embedded constants".
Previously, constants in array lengths and enum variant discriminants were "merely an expression", and had no separate ID for, e.g. type-checking or const-eval, instead reusing the expression's.
That complicated code working with bodies, because such constants were the only special case where the "owner" of the body wasn't the HIR parent, but rather the same node as the body itself.
Also, if the body happened to be a closure, we had no way to allocate a `DefId` for both the constant *and* the closure, leading to *several* bugs (mostly ICEs where type errors were expected).
This PR rectifies the situation by adding another (`{ast,hir}::AnonConst`) node around every such constant. Also, const generics are expected to rely on the new `AnonConst` nodes, as well (cc @varkor).
* fixes#48838
* fixes#50600
* fixes#50688
* fixes#50689
* obsoletes #50623
r? @nikomatsakis
Speed up the macro parser
These three commits reduce the number of allocations done by the macro parser, in some cases dramatically. For example, for a clean check builds of html5ever, the number of allocations is reduced by 40%.
Here are the rustc-benchmarks that are sped up by at least 1%.
```
html5ever-check
avg: -6.6% min: -10.3% max: -4.1%
html5ever
avg: -5.2% min: -9.5% max: -2.8%
html5ever-opt
avg: -4.3% min: -9.3% max: -1.6%
crates.io-check
avg: -1.8% min: -2.9% max: -0.6%
crates.io-opt
avg: -1.0% min: -2.2% max: -0.1%
crates.io
avg: -1.1% min: -2.2% max: -0.2%
```
rustc: Disallow modules and macros in expansions
This commit feature gates generating modules and macro definitions in procedural
macro expansions. Custom derive is exempt from this check as it would be a large
retroactive breaking change (#50587). It's hoped that we can hopefully stem the
bleeding to figure out a better solution here before opening up the floodgates.
The restriction here is specifically targeted at surprising hygiene results [1]
that result in non-"copy/paste" behavior. Hygiene and procedural macros is
intended to be avoided as much as possible for Macros 1.2 by saying everything
is "as if you copy/pasted the code", but modules and macros are sort of weird
exceptions to this rule that aren't fully fleshed out.
[1]: https://github.com/rust-lang/rust/issues/50504#issuecomment-387734625
cc #50504
This commit feature gates generating modules and macro definitions in procedural
macro expansions. Custom derive is exempt from this check as it would be a large
retroactive breaking change (#50587). It's hoped that we can hopefully stem the
bleeding to figure out a better solution here before opening up the floodgates.
The restriction here is specifically targeted at surprising hygiene results [1]
that result in non-"copy/paste" behavior. Hygiene and procedural macros is
intended to be avoided as much as possible for Macros 1.2 by saying everything
is "as if you copy/pasted the code", but modules and macros are sort of weird
exceptions to this rule that aren't fully fleshed out.
[1]: https://github.com/rust-lang/rust/issues/50504#issuecomment-387734625
cc #50504
This commit fixes `StringReader`'s parsing of tokens which have been stringified
through procedural macros. Whether or not a token tree is joint is defined by
span information, but when working with procedural macros these spans are often
dummy and/or overridden which means that they end up considering all operators
joint if they can!
The fix here is to track the raw source span as opposed to the overridden span.
With this information we can more accurately classify `Punct` structs as either
joint or not.
Closes#50700
Implement edition hygiene for keywords
Determine "keywordness" of an identifier in its hygienic context.
cc https://github.com/rust-lang/rust/pull/49611
I've resurrected `proc` as an Edition-2015-only keyword for testing purposes, but it should probably be buried again. EDIT: `proc` is removed again.
Review proc macro API 1.2
cc https://github.com/rust-lang/rust/issues/38356
Summary of applied changes:
- Documentation for proc macro API 1.2 is expanded.
- Renamed APIs: `Term` -> `Ident`, `TokenTree::Term` -> `TokenTree::Ident`, `Op` -> `Punct`, `TokenTree::Op` -> `TokenTree::Punct`, `Op::op` -> `Punct::as_char`.
- Removed APIs: `Ident::as_str`, use `Display` impl for `Ident` instead.
- New APIs (not stabilized in 1.2): `Ident::new_raw` for creating a raw identifier (I'm not sure `new_x` it's a very idiomatic name though).
- Runtime changes:
- `Punct::new` now ensures that the input `char` is a valid punctuation character in Rust.
- `Ident::new` ensures that the input `str` is a valid identifier in Rust.
- Lifetimes in proc macros are now represented as two joint tokens - `Punct('\'', Spacing::Joint)` and `Ident("lifetime_name_without_quote")` similarly to multi-character operators.
- Stabilized APIs: None yet.
A bit of motivation for renaming (although it was already stated in the review comments):
- With my compiler frontend glasses on `Ident` is the single most appropriate name for this thing, *especially* if we are doing input validation on construction. `TokenTree::Ident` effectively wraps `token::Ident` or `ast::Ident + is_raw`, its meaning is "identifier" and it's already named `ident` in declarative macros.
- Regarding `Punct`, the motivation is that `Op` is actively misleading. The thing doesn't mean an operator, it's neither a subset of operators (there is non-operator punctuation in the language), nor superset (operators can be multicharacter while this thing is always a single character). So I named it `Punct` (first proposed in [the original RFC](https://github.com/rust-lang/rfcs/pull/1566), then [by @SimonSapin](https://github.com/rust-lang/rust/issues/38356#issuecomment-276676526)) , together with input validation it's now a subset of ASCII punctuation character category (`u8::is_ascii_punctuation`).