syntax: add `ast::ItemKind::MacroDef`, simplify hygiene info
This PR
- adds a new variant `MacroDef` to `ast::ItemKind` for `macro_rules!` and eventually `macro` items,
- [breaking-change] forbids macro defs without a name (`macro_rules! { () => {} }` compiles today),
- removes `ast::MacroDef`, and
- no longer uses `Mark` and `Invocation` to identify and characterize macro definitions.
- We used to apply (at least) two `Mark`s to an expanded identifier's `SyntaxContext` -- the definition mark(s) and the expansion mark(s). We now only apply the latter.
r? @nrc
rustc: Exit quickly on only `--emit dep-info`
This commit alters the compiler to exit quickly if the only output being emitted
is `dep-info`, which doesn't need a lot of other information to generate.
Closes#40328
Remove ability for plugins to register a MIR pass
In recent months there have been a few different people investigating how to make a plugin that
registers a MIR-pass – one that isn’t intended to be eventually merged into rustc proper.
The interface to register MIR passes was added primarily for miri (& later was
found to make prototyping of rustc-proper MIR passes a tiny bit faster). Since miri does not use
this interface anymore it seems like a good time to remove this "feature".
For prototyping purposes a similar interface can be added by developers themselves in their custom
rustc build.
cc @nikomatsakis
Fix suggestion span error with a line containing multibyte characters
This PR fixes broken suggestions caused by multibyte characters.
e.g. for this code, rustc provides a broken suggestion ([playground](https://is.gd/DWGLu7)):
```rust
fn main() {
let tup = (1,);
println!("☃{}", tup[0]);
}
```
```
error: cannot index a value of type `({integer},)`
--> <anon>:3:21
|
3 | println!("☃{}", tup[0]);
| ^^^^^^
|
help: to access tuple elements, use tuple indexing syntax as shown
| println!("☃{}"tup.00]);
error: aborting due to previous error
```
`CodeSuggestion::splice_lines` is misusing `Loc.col` (`CharPos`) as a byte offset when slicing source.
This commit alters the compiler to exit quickly if the only output being emitted
is `dep-info`, which doesn't need a lot of other information to generate.
Closes#40328
In recent months there have been a few different people investigating how to make a plugin that
registers a MIR-pass – one that isn’t intended to be eventually merged into rustc proper.
The interface to register MIR passes was added primarily for miri (& later was
found to make prototyping of rustc-proper MIR passes a tiny bit faster). Since miri does not use
this interface anymore it seems like a good time to remove this "feature".
For prototyping purposes a similar interface can be added by developers themselves in their custom
rustc build.
When declaring nested unsafe blocks (`unsafe {unsafe {}}`) that trigger
the "unnecessary `unsafe` block" error, point out the enclosing `unsafe
block` or `unsafe fn` that makes it unnecessary.
Add compile-fail tests for remaining items in whitelist and remove it
Add compile-fail tests for `cfg_target_thread_local` and `unwind_attributes`, and remove the whitelist.
Let me know if I should clean up the tests (or if I've done anything else wrong, this is my first contribution to rust).
cc/ @est31
Group "missing variable bind" spans in `or` matches and clarify wording
for the two possible cases: when a variable from the first pattern is
not in any of the subsequent patterns, and when a variable in any of the
other patterns is not in the first one.
Before:
```
error[E0408]: variable `a` from pattern #1 is not bound in pattern #2
--> file.rs:10:23
|
10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| ^^^^^^^^^^^ pattern doesn't bind `a`
error[E0408]: variable `b` from pattern #2 is not bound in pattern #1
--> file.rs:10:32
|
10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| ^ pattern doesn't bind `b`
error[E0408]: variable `a` from pattern #1 is not bound in pattern #3
--> file.rs:10:37
|
10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| ^^^^^^^^ pattern doesn't bind `a`
error[E0408]: variable `d` from pattern #1 is not bound in pattern #3
--> file.rs:10:37
|
10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| ^^^^^^^^ pattern doesn't bind `d`
error[E0408]: variable `c` from pattern #3 is not bound in pattern #1
--> file.rs:10:43
|
10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| ^ pattern doesn't bind `c`
error[E0408]: variable `d` from pattern #1 is not bound in pattern #4
--> file.rs:10:48
|
10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| ^^^^^^^^ pattern doesn't bind `d`
error: aborting due to 6 previous errors
```
After:
```
error[E0408]: variable `a` is not bound in all patterns
--> file.rs:20:37
|
20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => {
intln!("{:?}", a); }
| - ^^^^^^^^^^^ ^^^^^^^^ - variable
t in all patterns
| | | |
| | | pattern doesn't bind `a`
| | pattern doesn't bind `a`
| variable not in all patterns
error[E0408]: variable `d` is not bound in all patterns
--> file.rs:20:37
|
20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => {
intln!("{:?}", a); }
| - - ^^^^^^^^ ^^^^^^^^ pattern
esn't bind `d`
| | | |
| | | pattern doesn't bind `d`
| | variable not in all patterns
| variable not in all patterns
error[E0408]: variable `b` is not bound in all patterns
--> file.rs:20:37
|
20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => {
intln!("{:?}", a); }
| ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern
esn't bind `b`
| | | |
| | | pattern doesn't bind `b`
| | variable not in all patterns
| pattern doesn't bind `b`
error[E0408]: variable `c` is not bound in all patterns
--> file.rs:20:48
|
20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => {
intln!("{:?}", a); }
| ^^^^^^^^^^^ ^^^^^^^^^^^ - ^^^^^^^^ pattern
esn't bind `c`
| | | |
| | | variable not in all
tterns
| | pattern doesn't bind `c`
| pattern doesn't bind `c`
error: aborting due to 4 previous errors
```
* Have only one presentation for binding consistency errors
* Point to same binding in multiple patterns when possible
* Check inconsistent bindings in all arms
* Simplify wording of diagnostic message
* Sort emition and spans of binding errors for deterministic output
In MIR construction, operands need to live exactly until they are used,
which is during the (sub)expression that made the call to `as_operand`.
Before this PR, operands lived until the end of the temporary scope,
which was sometimes unnecessarily longer and sometimes too short.
Fixes#38669.
convert AdtDef::destructor to on-demand
This removes the `Cell` from `AdtDef`. Also, moving destructor validity
checking to on-demand (forced during item-type checking) ensures that
invalid destructors can't cause ICEs.
Fixes#38868.
Fixes#40132.
r? @eddyb
transition borrowck to visit all **bodies** and not item-likes
This is a better structure for incremental compilation and also more compatible with the eventual borrowck mir. It also fixes#38520 as a drive-by fix.
r? @eddyb
This reduces the number of dynamic drops in libstd from 1141 to 899.
However, without this change, the next patch would have created much
more dynamic drops.
A basic merge unswitching hack reduced the number of dynamic drops to
644, with no effect on stack usage. I should be writing a more dedicated
drop unswitching pass.
No performance measurements.
Implement function-like procedural macros ( `#[proc_macro]`)
Adds the `#[proc_macro]` attribute, which expects bare functions of the kind `fn(TokenStream) -> TokenStream`, which can be invoked like `my_macro!()`.
cc rust-lang/rfcs#1913, #38356
r? @jseyfried
cc @nrc
Tracking issue: https://github.com/rust-lang/rust/issues/40180
This calling convention can be used for definining interrupt handlers on
32-bit and 64-bit x86 targets. The compiler then uses `iret` instead of
`ret` for returning and ensures that all registers are restored to their
original values.
Usage:
```
extern "x86-interrupt" fn handler(stack_frame: &ExceptionStackFrame) {…}
```
for interrupts and exceptions without error code and
```
extern "x86-interrupt" fn page_fault_handler(stack_frame: &ExceptionStackFrame,
error_code: u64) {…}
```
for exceptions that push an error code (e.g., page faults or general
protection faults). The programmer must ensure that the correct version
is used for each interrupt.
For more details see the [LLVM PR][1] and the corresponding [proposal][2].
[1]: https://reviews.llvm.org/D15567
[2]: http://lists.llvm.org/pipermail/cfe-dev/2015-September/045171.html