impl Trait Lifetime Handling
This PR implements the updated strategy for handling `impl Trait` lifetimes, as described in [RFC 1951](https://github.com/rust-lang/rfcs/blob/master/text/1951-expand-impl-trait.md) (cc #42183).
With this PR, the `impl Trait` desugaring works as follows:
```rust
fn foo<T, 'a, 'b, 'c>(...) -> impl Foo<'a, 'b> { ... }
// desugars to
exists type MyFoo<ParentT, 'parent_a, 'parent_b, 'parent_c, 'a, 'b>: Foo<'a, 'b>;
fn foo<T, 'a, 'b, 'c>(...) -> MyFoo<T, 'static, 'static, 'static, 'a, 'b> { ... }
```
All of the in-scope (parent) generics are listed as parent generics of the anonymous type, with parent regions being replaced by `'static`. Parent regions referenced in the `impl Trait` return type are duplicated into the anonymous type's generics and mapped appropriately.
One case came up that wasn't specified in the RFC: it's possible to write a return type that contains multiple regions, neither of which outlives the other. In that case, it's not clear what the required lifetime of the output type should be, so we generate an error.
There's one remaining FIXME in one of the tests: `-> impl Foo<'a, 'b> + 'c` should be able to outlive both `'a` and `'b`, but not `'c`. Currently, it can't outlive any of them. @nikomatsakis and I have discussed this, and there are some complex interactions here if we ever allow `impl<'a, 'b> SomeTrait for AnonType<'a, 'b> { ... }`, so the plan is to hold off on this until we've got a better idea of what the interactions are here.
cc #34511.
Fixes#44727.
show macro backtrace with -Z flag
Fixes#39413 by adding a facility to restore the "old school" macro expansion backtraces (previously removed in 61865384b8).
The restored functionality is accessed through the flag `-Z external-macro-backtrace`. Errors showing the truncated backtraces will suggest this flag.
### Example
Code: <details>
`a/src/lib.rs`
```rust
#[macro_export]
macro_rules! a {
() => { a!(@) };
(@) => { a!(@@) };
(@@) => {
syntax error;
}
}
```
`b/src/main.rs`
```rust
#[macro_use] extern crate a;
macro_rules! b {
() => { b!(@) };
(@) => { b!(@@) };
(@@) => {
syntax error;
}
}
fn main() {
a!();
b!();
}
```
</details>
<br/><br/>
Running without env var (note: first error is from remote macro, second from local macro):
<details>
```
$ cargo +custom run
Compiling b v0.1.0
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
--> src/main.rs:12:5
|
12 | a!();
| ^^^^^
| |
| expected one of 8 possible tokens here
| unexpected token
|
= note: this error originates in a macro outside of the current crate (run with RUST_MACRO_BACKTRACE=1 for more info)
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
--> src/main.rs:7:16
|
7 | syntax error;
| -^^^^^ unexpected token
| |
| expected one of 8 possible tokens here
...
13 | b!();
| ----- in this macro invocation
error: aborting due to 2 previous errors
error: Could not compile `b`.
To learn more, run the command again with --verbose.
```
</details>
The output is the same as today, except for an addition to the note which aids discoverability of the new environment variable.
<br/><br/>
Running _with_ env var:
<details>
```
$ RUST_MACRO_BACKTRACE=1 cargo +custom run
Compiling b v0.1.0
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
--> <a macros>:1:72
|
1 | ( ) => { a ! ( @ ) } ; ( @ ) => { a ! ( @ @ ) } ; ( @ @ ) => { syntax error ;
| -^^^^^ unexpected token
| |
| expected one of 8 possible tokens here
src/main.rs:12:5: 12:10 note: in this expansion of a! (defined in <a macros>)
<a macros>:1:11: 1:20 note: in this expansion of a! (defined in <a macros>)
<a macros>:1:36: 1:47 note: in this expansion of a! (defined in <a macros>)
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
--> src/main.rs:7:16
|
7 | syntax error;
| -^^^^^ unexpected token
| |
| expected one of 8 possible tokens here
src/main.rs:12:5: 12:10 note: in this expansion of a! (defined in <a macros>)
<a macros>:1:11: 1:20 note: in this expansion of a! (defined in <a macros>)
<a macros>:1:36: 1:47 note: in this expansion of a! (defined in <a macros>)
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
--> src/main.rs:7:16
|
7 | syntax error;
| -^^^^^ unexpected token
| |
| expected one of 8 possible tokens here
src/main.rs:13:5: 13:10 note: in this expansion of b! (defined in src/main.rs)
src/main.rs:4:13: 4:18 note: in this expansion of b! (defined in src/main.rs)
src/main.rs:5:14: 5:20 note: in this expansion of b! (defined in src/main.rs)
error: aborting due to 2 previous errors
error: Could not compile `b`.
To learn more, run the command again with --verbose.
```
</details>
The output is hard to read, but better than nothing (and it's exactly what we used to have before the infamous `fix_multispans_in_std_macros`).
<br/><br/>
Wishlist:
- Save the actual source of macros in crate metadata, not just AST, so the output can be improved
- Hopefully this would allow line numbers in the trace as well
- Show the actual macro invocations in the traces
r? @nrc
show in docs whether the return type of a function impls Iterator/Read/Write
Closes#25928
This PR makes it so that when rustdoc documents a function, it checks the return type to see whether it implements a handful of specific traits. If so, it will print the impl and any associated types. Rather than doing this via a whitelist within rustdoc, i chose to do this by a new `#[doc]` attribute parameter, so things like `Future` could tap into this if desired.
### Known shortcomings
~~The printing of impls currently uses the `where` class over the whole thing to shrink the font size relative to the function definition itself. Naturally, when the impl has a where clause of its own, it gets shrunken even further:~~ (This is no longer a problem because the design changed and rendered this concern moot.)
The lookup currently just looks at the top-level type, not looking inside things like Result or Option, which renders the spotlights on Read/Write a little less useful:
<details><summary>`File::{open, create}` don't have spotlight info (pic of old design)</summary>
![image](https://user-images.githubusercontent.com/5217170/31209495-e59d027e-a950-11e7-9998-ceefceb71c07.png)
</details>
All three of the initially spotlighted traits are generically implemented on `&mut` references. Rustdoc currently treats a `&mut T` reference-to-a-generic as an impl on the reference primitive itself. `&mut Self` counts as a generic in the eyes of rustdoc. All this combines to create this lovely scene on `Iterator::by_ref`:
<details><summary>`Iterator::by_ref` spotlights Iterator, Read, and Write (pic of old design)</summary>
![image](https://user-images.githubusercontent.com/5217170/31209554-50b271ca-a951-11e7-928b-4f83416c8681.png)
</details>
[rustllvm] Use report_fatal_error over llvm_unreachable
This makes it more robust when assertions are disabled, crashing instead of causing UB.
Also introduces a tidy check to enforce this rule, which in turn necessitated making tidy run on `src/rustllvm`.
Fixes#44020
Fix typo in MIR "cannot move out of borrowed content"
I believe this all we need to change (#46018). Anyway, do let me know if there is anything else that needs to changed as well!
add doc for doing `Read` from `&str`
This information can be found on [stackoverflow](https://stackoverflow.com/questions/32674905/pass-string-to-function-taking-read-trait) but I think it would be beneficial if it was documented in the `Read` trait itself.
I had an *extremely* hard time finding this information, and "mocking" a reader with a string is an EXTREMELY common thing (I believe).
impl From for Mutex and RwLock
I felt that these implementations were missing, because doing `x.into()` works for other smart containers (such as `RefCell`), and in general I would say that the conversion makes sense.
This makes it more robust when assertions are disabled,
crashing instead of causing UB.
Also introduces a tidy check to enforce this rule,
which in turn necessitated making tidy run on src/rustllvm.
Fixes#44020
The GNU C library (glibc) is documented to always allocate with an alignment
of at least 8 or 16 bytes, on 32-bit or 64-bit platforms:
https://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html
This matches our use of `MIN_ALIGN` before this commit.
However, even when libc is glibc, the program might be linked
with another allocator that redefines the `malloc` symbol and friends.
(The `alloc_jemalloc` crate does, in some cases.)
So `alloc_system` doesn’t know which allocator it calls,
and needs to be conservative in assumptions it makes.
The C standard says:
https://port70.net/%7Ensz/c/c11/n1570.html#7.22.3
> The pointer returned if the allocation succeeds is suitably aligned
> so that it may be assigned to a pointer to any type of object
> with a fundamental alignment requirement
https://port70.net/~nsz/c/c11/n1570.html#6.2.8p2
> A fundamental alignment is represented by an alignment less than
> or equal to the greatest alignment supported by the implementation
> in all contexts, which is equal to `_Alignof (max_align_t)`.
`_Alignof (max_align_t)` depends on the ABI and doesn’t seem to have
a clear definition, but it seems to match our `MIN_ALIGN` in practice.
However, the size of objects is rounded up to the next multiple
of their alignment (since that size is also the stride used in arrays).
Conversely, the alignment of a non-zero-size object is at most its size.
So for example it seems ot be legal for `malloc(8)` to return a pointer
that’s only 8-bytes-aligned, even if `_Alignof (max_align_t)` is 16.
Fix broken CSS for book redirect pages
rust.css has to be next to the font files so we shouldn't copy it for
only the book redirect pages, instead just use the version that is
already there.
This also removes the duplicate code creating version_info.html.
Fixes: #45974
* The overflow-checking shift items need to take a full 128-bit type, since they need to be able to detect idiocy like `1i128 << (1u128 << 127)`
* The unchecked ones just take u32, like the `*_sh?` methods in core
* Because shift-by-anything is allowed, cast into a new local for every shift