trace_macro: Show both the macro call and its expansion. #42072.
See #42072 for the initial motivation behind this.
The change is not the minimal fix, but I want this behavior almost every time I use `trace_macros`.
Fix 'associate type' typo
I came across an error message mentioning an 'associate type'.
Since this is the only instance of this term in rustc (it's 'associated type' everywhere else), I think this might be a typo.
Make assignments to `Copy` union fields safe
This is an accompanying PR to PR https://github.com/rust-lang/rust/pull/42068 stabilizing FFI unions.
This was first proposed in https://github.com/rust-lang/rust/issues/32836#issuecomment-281296416, see subsequent comments as well.
Assignments to `Copy` union fields do not read any data from the union and are [equivalent](https://github.com/rust-lang/rust/issues/32836#issuecomment-281660298) to whole union assignments, which are safe, so they should be safe as well. This removes a significant number of "false positive" unsafe blocks, in code dealing with FFI unions in particular.
It desirable to make this change now, together with stabilization of FFI unions, because now it affecfts only unstable code, but later it will cause warnings/errors caused by `unused_unsafe` lint in stable code.
cc #32836
r? @nikomatsakis
add thiscall calling convention support
This support is needed for bindgen to work well on 32-bit Windows, and also enables people to begin experimenting with C++ FFI support on that platform.
Fixes#42044.
Initial implementation of declarative macros 2.0
Implement declarative macros 2.0 (rust-lang/rfcs#1584) behind `#![feature(decl_macro)]`.
Differences from `macro_rules!` include:
- new syntax: `macro m(..) { .. }` instead of `macro_rules! m { (..) => { .. } }`
- declarative macros are items:
```rust
// crate A:
pub mod foo {
m!(); // use before definition; declaration order is irrelevant
pub macro m() {} // `pub`, `pub(super)`, etc. work
}
fn main() {
foo::m!(); // named like other items
{ use foo::m as n; n!(); } // imported like other items
}
pub use foo::m; // re-exported like other items
// crate B:
extern crate A; // no need for `#[macro_use]`
A::foo::m!(); A::m!();
```
- Racket-like hygiene for items, imports, methods, fields, type parameters, privacy, etc.
- Intuitively, names in a macro definition are resolved in the macro definition's scope, not the scope in which the macro is used.
- This [explaination](http://beautifulracket.com/explainer/hygiene.html) of hygiene for Racket applies here (except for the "Breaking Hygiene" section). I wrote a similar [explanation](https://github.com/jseyfried/rfcs/blob/hygiene/text/0000-hygiene.md) for Rust.
- Generally speaking, if `fn f() { <body> }` resolves, `pub macro m() { <body> } ... m!()` also resolves, even if `m!()` is in a separate crate.
- `::foo::bar` in a `macro` behaves like `$crate::foo::bar` in a `macro_rules!`, except it can access everything visible from the `macro` (thus more permissive).
- See [`src/test/{run-pass, compile-fail}/hygiene`](https://github.com/rust-lang/rust/pull/40847/commits/afe7d89858fd72b983e24727d6f4058293153c19) for examples. Small example:
```rust
mod foo {
fn f() { println!("hello world"); }
pub macro m() { f(); }
}
fn main() { foo::m!(); }
```
Limitations:
- This does not address planned changes to matchers (`expr`,`ty`, etc.), c.f. #26361.
- Lints (including stability and deprecation) and `unsafe` are not hygienic.
- adding hygiene here will be mostly or entirely backwards compatible
- Nested macro definitions (a `macro` inside another `macro`) don't always work correctly when invoked from external crates.
- pending improvements in how we encode macro definitions in crate metadata
- There is no way to "escape" hygiene without using a procedural macro.
r? @nrc
Refactor: Move the mutable parts out of LintStore. Fix#42007.
* #42007 happens because the `Session` `LintStore` is emptied when linting.
* The `Session` `LintStore` is emptied because the checker (`Early`/`LateContext`) wants ownership.
* The checker wants ownership because it wants to mutate the pass objects and lint levels.
The ownership of the whole store is not essential, only the lint levels and pass objects need to be owned. Therefore, these parts are extracted out of the `LintStore` into a separate structure `LintSession`. The "check crates" methods can operate on `&mut LintSession` instead of `&mut LintStore`.
This is a minor *breaking change* for lint writers since the `LintContext` trait is changed: the `mut_lints` and `level_stack` methods are removed. But no one outside of `librustc/lint/context.rs` is using these functions, so it should be safe.
Remove some needless // gate-test- comments
Also, add detection to treat such comments as tidy errors.
We also remove the found_lib_feature code because it
was just repeating the found_feature code. Originally it
was intended to allow for gate-test lines for
lib features, but apparently nobody missed it.
Make RangeInclusive just a two-field struct
Not being an enum improves ergonomics and consistency, especially since NonEmpty variant wasn't prevented from being empty. It can still be iterable without an extra "done" bit by making the range have !(start <= end), which is even possible without changing the Step trait.
Implements merged https://github.com/rust-lang/rfcs/pull/1980; tracking issue https://github.com/rust-lang/rust/issues/28237.
This is definitely a breaking change to anything consuming `RangeInclusive` directly (not as an Iterator) or constructing it without using the sugar. Is there some change that would make sense before this so compilation failures could be compatibly fixed ahead of time?
r? @aturon (as FCP proposer on the RFC)
This support is needed for bindgen to work well on 32-bit Windows, and
also enables people to begin experimenting with C++ FFI support on that
platform.
Fixes#42044.
Also, add detection to treat such comments as tidy errors.
We also remove the found_lib_feature code because it
was just repeating the found_feature code. Originally it
was intended to allow for gate-test lines for
lib features, but apparently nobody missed it.
introduce local-scope to prevent `StorageLive`/`StorageDead` in statics
In investigating #36799, I found that we were creating storage-live/storage-dead instructions in statics/constants, where they are not needed. This arose due to the fix for local scopes. This PR tries to fix that (and adds a test -- I'm curious if there is a way to make that test more targeted, though).
r? @arielb1
remove interior mutability of type-flags
We were previously using the flags on `Ty<'tcx>` instances to do some ad-hoc caching schemes around things like `is_sized()`, `is_freeze()`, and `moves_by_default()`. This PR replaces those schemes with a proper query; the query key is based on the pair of a `(ParameterEnvironment<'tcx>, Ty<'tcx>)` pair. This is also intended to be a preliminary template for what trait-selection and projection will eventually look like.
I did some performance measurements. In the past, I observed a noticeable speedup (6%) for building rustc, but since I've rebased, the numbers appear to be more of a wash:
| Crate | Before | After | Percentage |
| --- | --- | --- | -- |
| syntax | 167s | 166s | 0.6% faster |
| rustc | 376s | 382s | 1.5% slower |
Some advantages of this new scheme:
- `is_sized` etc are proper queries
- we get caching across generic fns, so long as trait environment is identical
- dependency tracking is correct
Add better error message when == operator is badly used
Part of #40660.
With the following code:
```rust
fn foo<T: PartialEq>(a: &T, b: T) {
a == b;
}
fn main() {
foo(&1, 1);
}
```
It prints:
```
error[E0277]: the trait bound `&T: std::cmp::PartialEq<T>` is not satisfied
--> test.rs:2:5
|
2 | a == b;
| ^^^^^^ can't compare `&T` with `T`
|
= help: the trait `std::cmp::PartialEq<T>` is not implemented for `&T`
= help: consider adding a `where &T: std::cmp::PartialEq<T>` bound
error: aborting due to previous error
```