Allow legacy custom derive authors to disable warnings in downstream crates
This PR allows legacy custom derive authors to use a pre-deprecated method `registry.register_custom_derive()` instead of `registry.register_syntax_extension()` to avoid downstream deprecation warnings.
r? @nrc
On fmt string with unescaped `{` note how to escape
On cases of malformed format strings where a `{` hasn't been properly escaped, like `println!("{");`, present a NOTE explaining how to escape the `{` char.
Fix#34300.
Add foreign formatting directive detection.
This teaches `format_args!` how to interpret format printf- and
shell-style format directives. This is used in cases where there are
unused formatting arguments, and the reason for that *might* be because
the programmer is trying to use the wrong kind of formatting string.
This was prompted by an issue encountered by simulacrum on the #rust IRC
channel. In short: although `println!` told them that they weren't using
all of the conversion arguments, the problem was in using printf-syle
directives rather than ones `println!` would undertand.
Where possible, `format_args!` will tell the programmer what they should
use instead. For example, it will suggest replacing `%05d` with `{:0>5}`,
or `%2$.*3$s` with `{1:.3$}`. Even if it cannot suggest a replacement,
it will explicitly note that Rust does not support that style of directive,
and direct the user to the `std::fmt` documentation.
-----
**Example**: given:
```rust
fn main() {
println!("%.*3$s %s!\n", "Hello,", "World", 4);
println!("%1$*2$.*3$f", 123.456);
}
```
The compiler outputs the following:
```text
error: multiple unused formatting arguments
--> local/fmt.rs:2:5
|
2 | println!("%.*3$s %s!\n", "Hello,", "World", 4);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: argument never used
--> local/fmt.rs:2:30
|
2 | println!("%.*3$s %s!\n", "Hello,", "World", 4);
| ^^^^^^^^
note: argument never used
--> local/fmt.rs:2:40
|
2 | println!("%.*3$s %s!\n", "Hello,", "World", 4);
| ^^^^^^^
note: argument never used
--> local/fmt.rs:2:49
|
2 | println!("%.*3$s %s!\n", "Hello,", "World", 4);
| ^
= help: `%.*3$s` should be written as `{:.2$}`
= help: `%s` should be written as `{}`
= note: printf formatting not supported; see the documentation for `std::fmt`
= note: this error originates in a macro outside of the current crate
error: argument never used
--> local/fmt.rs:6:29
|
6 | println!("%1$*2$.*3$f", 123.456);
| ^^^^^^^
|
= help: `%1$*2$.*3$f` should be written as `{0:1$.2$}`
= note: printf formatting not supported; see the documentation for `std::fmt`
```
On cases of malformed format strings where a `{` hasn't been properly
escaped, like `println!("{");`, present a note explaining how to escape
the `{` char.
This teaches `format_args!` how to interpret format printf- and
shell-style format directives. This is used in cases where there are
unused formatting arguments, and the reason for that *might* be because
the programmer is trying to use the wrong kind of formatting string.
This was prompted by an issue encountered by simulacrum on the #rust IRC
channel. In short: although `println!` told them that they weren't using
all of the conversion arguments, the problem was in using printf-syle
directives rather than ones `println!` would undertand.
Where possible, `format_args!` will tell the programmer what they should
use instead. For example, it will suggest replacing `%05d` with `{:0>5}`,
or `%2$.*3$s` with `{1:.3$}`. Even if it cannot suggest a replacement,
it will explicitly note that Rust does not support that style of directive,
and direct the user to the `std::fmt` documentation.
Fix regression involving custom derives on items with `$crate`
The regression was introduced in #37213.
I believe we cannot make the improvements from #37213 work with the current custom derive setup (c.f. https://github.com/rust-lang/rust/issues/37637#issuecomment-258959145) -- we'll have to wait for `TokenStream`'s API to improve.
Fixes#37637.
r? @nrc
macros 1.1: Allow proc_macro functions to declare attributes to be mark as used
This PR allows proc macro functions to declare attribute names that should be marked as used when attached to the deriving item. There are a few questions for this PR.
- Currently this uses a separate attribute named `#[proc_macro_attributes(..)]`, is this the best choice?
- In order to make this work, the `check_attribute` function had to be modified to not error on attributes marked as used. This is a pretty large change in semantics, is there a better way to do this?
- I've got a few clones where I don't know if I need them (like turning `item` into a `TokenStream`), can these be avoided?
- Is switching to `MultiItemDecorator` the right thing here?
Also fixes https://github.com/rust-lang/rust/issues/37563.
By using a second attribute `attributes(Bar)` on
proc_macro_derive, whitelist any attributes with
the name `Bar` in the deriving item. This allows
a proc_macro function to use custom attribtues
without a custom attribute error or unused attribute
lint.
Stabilize `..` in tuple (struct) patterns
I'd like to nominate `..` in tuple and tuple struct patterns for stabilization.
This feature is a relatively small extension to existing stable functionality and doesn't have known blockers.
The feature first appeared in Rust 1.10 6 months ago.
An example of use: https://github.com/rust-lang/rust/pull/36203
Closes https://github.com/rust-lang/rust/issues/33627
r? @nikomatsakis
Most of the Rust community agrees that the vec! macro is clearer when
called using square brackets [] instead of regular brackets (). Most of
these ocurrences are from before macros allowed using different types of
brackets.
There is one left unchanged in a pretty-print test, as the pretty
printer still wants it to have regular brackets.
macros 1.1: future proofing and cleanup
This PR
- uses the macro namespace for custom derives (instead of a dedicated custom derive namespace),
- relaxes the shadowing rules for `#[macro_use]`-imported custom derives to match the shadowing rules for ordinary `#[macro_use]`-imported macros, and
- treats custom derive `extern crate`s like empty modules so that we can eventually allow, for example, `extern crate serde_derive; use serde_derive::Serialize;` backwards compatibly.
r? @alexcrichton
Avoid many CrateConfig clones.
This commit changes `ExtCtx::cfg()` so it returns a `CrateConfig`
reference instead of a clone. As a result, it also changes all of the
`cfg()` callsites to explicitly clone... except one, because the commit
also changes `macro_parser::parse()` to take `&CrateConfig`. This is
good, because that function can be hot, and `CrateConfig` is expensive
to clone.
This change almost halves the number of heap allocations done by rustc
for `html5ever` in rustc-benchmarks suite, which makes compilation 1.20x
faster.
r? @nrc
Clarify the positions of the lexer and parser
The lexer and parser use unclear names to indicate their positions in the
source code. I propose the following renamings.
Lexer:
```
pos -> next_pos # it's actually the next pos!
last_pos -> pos # it's actually the current pos!
curr -> ch # the current char
curr_is -> ch_is # tests the current char
col (unchanged) # the current column
```
parser
```
- last_span -> prev_span # the previous token's span
- last_token_kind -> prev_token_kind # the previous token's kind
- LastTokenKind -> PrevTokenKind # ditto (but the type)
- token (unchanged) # the current token
- span (unchanged) # the current span
```
Things to note:
- This proposal removes all uses of "last", which is an unclear word because it
could mean (a) previous, (b) final, or (c) most recent, i.e. current.
- The "current" things (ch, col, token, span) consistently lack a prefix. The
"previous" and "next" things consistently have a prefix.
This commit changes `ExtCtx::cfg()` so it returns a `CrateConfig`
reference instead of a clone. As a result, it also changes all of the
`cfg()` callsites to explicitly clone... except one, because the commit
also changes `macro_parser::parse()` to take `&CrateConfig`. This is
good, because that function can be hot, and `CrateConfig` is expensive
to clone.
This change almost halves the number of heap allocations done by rustc
for `html5ever` in rustc-benchmarks suite, which makes compilation 1.20x
faster.
macros: clean up scopes of expanded `#[macro_use]` imports
This PR changes the scope of macro-expanded `#[macro_use]` imports to match that of unexpanded `#[macro_use]` imports. For example, this would be allowed:
```rust
example!();
macro_rules! m { () => { #[macro_use(example)] extern crate example_crate; } }
m!();
```
This PR also enforces the full shadowing restrictions from RFC 1560 on `#[macro_use]` imports (currently, we only enforce the weakened restrictions from #36767).
This is a [breaking-change], but I believe it is highly unlikely to cause breakage in practice.
r? @nrc