macros: improve 1.0/2.0 interaction
This PR supports using unhygienic macros from hygienic macros without breaking the latter's hygiene.
```rust
// crate A:
#[macro_export]
macro_rules! m1 { () => {
f(); // unhygienic: this macro needs `f` in its environment
fn g() {} // (1) unhygienic: `g` is usable outside the macro definition
} }
// crate B:
#![feature(decl_macro)]
extern crate A;
use A::m1;
macro m2() {
fn f() {} // (2)
m1!(); // After this PR, `f()` in the expansion resolves to (2), not (3)
g(); // After this PR, this resolves to `fn g() {}` from the above expansion.
// Today, it is a resolution error.
}
fn test() {
fn f() {} // (3)
m2!(); // Today, `m2!()` can see (3) even though it should be hygienic.
fn g() {} // Today, this conflicts with `fn g() {}` from the expansion, even though it should be hygienic.
}
```
Once this PR lands, you can make an existing unhygienic macro hygienic by wrapping it in a hygienic macro. There is an [example](b766fa887d) of this in the tests.
r? @nrc
Add iterator method specialisations to Range*
Add specialised implementations of `max` for `Range`, and `last`, `min` and `max` for `RangeInclusive`, all of which lead to significant advantages in the generated assembly on x86.
Note that adding specialisations of `min` and `last` for `Range` led to no benefit, and adding `sum` for `Range` and `RangeInclusive` led to type inference issues (though this is possibly still worthwhile considering the performance gain).
This addresses some of the concerns in #39975.
Replace uses of DepGraph.in_ignore with DepGraph.with_ignore
I currently plan to track tasks in thread local storage. Ignoring things in a closure ensures that the ignore tasks do not overlap the beginning or end of any other task. The TLS API will also use a closure to change a TLS value, so having the ignore task be a closure also helps there.
It also adds `assert_ignored` which is used before a `TyCtxt` is created. Instead of adding a new ignore task this simply ensures that we are in a context where reads are ignored.
r? @michaelwoerister
[incremental] Specialize encoding and decoding of Fingerprints
This saves the storage space used by about 32 bits per `Fingerprint`.
On average, this reduces the size of the `/target/{mode}/incremental`
folder by roughly 5% [Full details here](https://gist.github.com/wesleywiser/264076314794fbd6a4c110d7c1adc43e).
Fixes#45875
r? @michaelwoerister
Fix built-in indexing not being used where index type wasn't "obviously" usize
Fixes#33903Fixes#46095
This PR was made possible thanks to the generous help of @eddyb
Following the example of binary operators, builtin checking for indexing has been moved from the typecheck stage to a writeback stage, after type constraints have been resolved.
Deprecate [T]::rotate in favor of [T]::rotate_{left,right}.
Background
==========
Slices currently have an **unstable** [`rotate`] method which rotates
elements in the slice to the _left_ N positions. [Here][tracking] is the
tracking issue for this unstable feature.
```rust
let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate(2);
assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
```
Proposal
========
Deprecate the [`rotate`] method and introduce `rotate_left` and
`rotate_right` methods.
```rust
let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate_left(2);
assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
```
```rust
let mut a = ['a', 'b' ,'c', 'd', 'e', 'f'];
a.rotate_right(2);
assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
```
Justification
=============
I used this method today for my first time and (probably because I’m a
naive westerner who reads LTR) was surprised when the docs mentioned that
elements get rotated in a left-ward direction. I was in a situation
where I needed to shift elements in a right-ward direction and had to
context switch from the main problem I was working on and think how much
to rotate left in order to accomplish the right-ward rotation I needed.
Ruby’s `Array.rotate` shifts left-ward, Python’s `deque.rotate` shifts
right-ward. Both of their implementations allow passing negative numbers
to shift in the opposite direction respectively. The current `rotate`
implementation takes an unsigned integer argument which doesn't allow
the negative number behavior.
Introducing `rotate_left` and `rotate_right` would:
- remove ambiguity about direction (alleviating need to read docs 😉)
- make it easier for people who need to rotate right
[`rotate`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rotate
[tracking]: https://github.com/rust-lang/rust/issues/41891
This saves the storage space used by about 32 bits per `Fingerprint`.
On average, this reduces the size of the `/target/{mode}/incremental`
folder by roughly 5%.
Fixes#45875
Shorten names of some compiler generated artifacts.
This PR makes the compiler mangle codegen unit names by default. The name of every codegen unit name will now be a random string of 16 characters. It also makes the file extensions of some intermediate compiler products shorter. Hopefully, these changes will reduce the pressure on tools with path length restrictions like buildbot. The change should also solve problems with case-insensitive file system.
cc #47186 and #47222
r? @alexcrichton
Replace empty array hack with repr(align)
As a side effect, this fixes the warning about repr(C, simd) that has been reported during x86_64 windows builds since #47111 (see also: #47103)
r? @alexcrichton
fix the doc-comment-decoration-trimming edge-case rustdoc ICE
This `horizontal_trim` function strips the leading whitespace from
doc-comments that have a left-asterisk-margin:
```
/**
* You know what I mean—
*
* comments like this!
*/
```
The index of the column of asterisks is `i`, and if trimming is deemed
possible, we slice each line from `i+1` to the end of the line. But if, in
particular, `i` was 0 _and_ there was an empty line (as in the example
given in the reporting issue), we ended up panicking trying to slice an
empty string from 0+1 (== 1).
Let's tighten our check to say that we can't trim when `i` is even the same
as the length of the line, not just when it's greater. (Any such cases
would panic trying to slice `line` from `line.len()+1`.)
Resolves#47197.
Add help message for incorrect pattern syntax
When I was getting started with rust I often made the mistake of using `||` instead of `|` to match multiple patterns and spent a long time staring at my code wondering what was wrong.
for example:
```
fn main() {
let x = 1;
match x {
1 || 2 => println!("1 or 2"),
_ => println!("Something else"),
}
}
```
If you compile this with current rustc you will see
```
error: expected one of `...`, `..=`, `..`, `=>`, `if`, or `|`, found `||`
--> test.rs:5:11
|
5 | 1 || 2 => println!("1 or 2"),
| -^^ unexpected token
| |
| expected one of `...`, `..=`, `..`, `=>`, `if`, or `|` here
error: aborting due to previous error
```
With my proposed change it will show:
```
error: unexpected token `||` after pattern
--> test.rs:5:11
|
5 | 1 || 2 => println!("1 or 2"),
| ^^
|
= help: did you mean to use `|` to specify multiple patterns instead?
error: aborting due to previous error
```
Make normalize_and_test_predicates into a query
From #44891.
I'm not real solid on how `dep_graph` stuff works, but if a node is going to have a key (again, not sure how important that is), then the key needs to be `Copy`. So since `normalize_and_test_predicates` only had one out-of-module use, I changed that call site to use a new function, `substitute_normalize_and_test_predicates` which is the query and enables having the arguments be `Copy`. Hopefully this makes sense.
r? @nikomatsakis
and/or @michaelwoerister
Provide suggestion when trying to use method on numeric literal
New output:
```
error[E0688]: can't call method `powi` on ambiguous numeric type `{float}`
--> $DIR/method-on-ambiguous-numeric-type.rs:12:17
|
12 | let x = 2.0.powi(2);
| ^^^^
help: you must specify a concrete type for this numeric value, like `f32`
|
12 | let x = 2.0_f32.powi(2);
| ^^^^^^^
```
Previous output:
```
error[E0599]: no method named `powi` found for type `{float}` in the current scope
--> src/main.rs:12:17
|
12 | let x = 2.0.powi(2);
| ^^^^
|
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
|
11 | use core::num::Float;
|
```
Fix#40985.