Rollup of 10 pull requests
Successful merges:
- #57268 (Add a target option "merge-functions", and a corresponding -Z flag (works around #57356))
- #57476 (Move glob map use to query and get rid of CrateAnalysis)
- #57501 (High priority resolutions for associated variants)
- #57573 (Querify `entry_fn`)
- #57610 (Fix nested `?` matchers)
- #57634 (Remove an unused function argument)
- #57653 (Make the contribution doc reference the guide more)
- #57666 (Generalize `huge-enum.rs` test and expected stderr for more cross platform cases)
- #57698 (Fix typo bug in DepGraph::try_mark_green().)
- #57746 (Update README.md)
Failed merges:
r? @ghost
Generalize `huge-enum.rs` test and expected stderr for more cross platform cases
With this change, I am able to build and test cross-platform `rustc`
In particular, I can use the following in my `config.toml`:
```
[build]
host = ["i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu"]
target = ["i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu"]
```
Before this change, my attempt to run the test suite would fail
because the error output differs depending on what your host and
targets are.
----
To be concrete, here are the actual messages one can observe:
```
% ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc ../src/test/ui/huge-enum.rs -Aunused --target=x86_64-unknown-linux-gnu
error: the type `std::option::Option<[u32; 35184372088831]>` is too big for the current architecture
error: aborting due to previous error
% ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc ../src/test/ui/huge-enum.rs -Aunused --target=i686-unknown-linux-gnu
error: the type `std::option::Option<[u32; 536870911]>` is too big for the current architecture
error: aborting due to previous error
% ./build/i686-unknown-linux-gnu/stage1/bin/rustc ../src/test/ui/huge-enum.rs -Aunused --target=i686-unknown-linux-gnu
error: the type `std::option::Option<[u32; 536870911]>` is too big for the current architecture
error: aborting due to previous error
% ./build/i686-unknown-linux-gnu/stage1/bin/rustc ../src/test/ui/huge-enum.rs -Aunused --target=x86_64-unknown-linux-gnu
error: the type `[u32; 35184372088831]` is too big for the current architecture
error: aborting due to previous error
```
To address these variations, I changed the test to be more aggressive
in its normalization strategy. We cannot (and IMO should not)
guarantee that `Option` will appear in the error output here. So I
normalized both types `Option<[u32; N]>` and `[u32; N]` to just `TYPE`
Remove an unused function argument
The only use was a debug printing, which might help someone with debugging dataflow problems, but seems otherwise useless
High priority resolutions for associated variants
In https://github.com/rust-lang/rust/pull/56225 variants were assigned lowest priority during name resolution to avoid crater run and potential breakage.
This PR changes the rules to give variants highest priority instead.
Some motivation:
- If variants (and their constructors) are treated as associated items, then they are obviously *inherent* associated items since they don't come from traits.
- Inherent associated items have higher priority during resolution than associated items from traits.
- The reason is that there is a way to disambiguate in favor of trait items (`<Type as Trait>::Ambiguous`), but there's no way to disambiguate in favor of inherent items, so they became unusable in case of ambiguities if they have low priority.
- It's technically problematic to fallback from associated types to anything until lazy normalization (?) is implemented.
Crater found some regressions from this change, but they are all in type positions, e.g.
```rust
fn f() -> Self::Ambiguos { ... } // Variant `Ambiguous` or associated type `Ambiguous`?
```
, so variants are not usable there right now, but they may become usable in the future if https://github.com/rust-lang/rfcs/pull/2593 is accepted.
This PR keeps code like this successfully resolving, but introduces a future-compatibility lint `ambiguous_associated_items` that recommends rewriting it as `<Self as Trait>::Ambiguous`.
Move glob map use to query and get rid of CrateAnalysis
~Also includes commits from ~https://github.com/rust-lang/rust/pull/57392~ and ~https://github.com/rust-lang/rust/pull/57436~.~
With glob map calculated unconditionally in https://github.com/rust-lang/rust/pull/57392, this PR moves the calculated glob map to `GlobalCtxt` and exposes a relevant query (as we do with other queries which copy precomputed data over from the `Resolver`).
This allows us to get rid of the `CrateAnalysis` struct in an attempt to simplify the compiler interface.
cc @Zoxc
r? @nikomatsakis @Zoxc @petrochenkov
Add a target option "merge-functions", and a corresponding -Z flag (works around #57356)
This commit adds a target option "merge-functions", which takes values in ("disabled", "trampolines", or "aliases" (default is "aliases")), to allow targets to opt out of the MergeFunctions LLVM pass. Additionally, the latest commit also adds an optional -Z flag, "merge-functions", which takes the same values and has precedence over the target option when both are specified.
This works around https://github.com/rust-lang/rust/issues/57356.
cc @eddyb @japaric @oli-obk @nox @nagisa
Also thanks to @denzp and @gnzlbg for discussing this on rust-cuda!
### Motivation
Basically, the problem is that the MergeFunctions pass, which rustc currently enables by default at -O2 and -O3 [1], and `extern "ptx-kernel"` functions (specific to the NVPTX target) are currently not compatible with each other. If the MergeFunctions pass is allowed to run, rustc can generate invalid PTX assembly (i.e. a PTX file that is not accepted by the native PTX assembler `ptxas`). Therefore we would like a way to opt out of the MergeFunctions pass, which is what our target option does.
### Related work
The current behavior of rustc is to enable MergeFunctions at -O2 and -O3 [1], and also to enable the use of function aliases within MergeFunctions [2] [3]. MergeFunctions seems to have some benefits, such as reducing code size and fixing a crash [4], which is why it is enabled. However, MergeFunctions both with and without function aliases is incompatible with the NVPTX target; a more detailed example for both cases is given below.
clang's "solution" is to have a "-fmerge-functions" flag that opts in to the MergeFunctions pass, but it is not enabled by default.
### Examples/more details
Consider an example Rust lib using `extern "ptx-kernel"` functions: https://github.com/peterhj/nvptx-mergefunc-bug/blob/master/nocore.rs. If we try to compile this with nightly rustc, we get the following compiler error:
LLVM ERROR: Module has aliases, which NVPTX does not support.
This error happens because: (1) functions `foo` and `bar` have the same body, so are candidates to be merged by MergeFunctions; and (2) rustc configures MergeFunctions to generate function aliases using the "mergefunc-use-aliases" LLVM option [2] [3], but the NVPTX backend does not support those aliases.
Okay, so we can try omitting "mergefunc-use-aliases", and then rustc will happily emit PTX assembly: https://github.com/peterhj/nvptx-mergefunc-bug/blob/master/nocore-mergefunc-nousealiases-bad.ptx. However, this PTX is invalid! When we try to assemble it with `ptxas` (I'm on the CUDA 9.2 toolchain), we get an assembler error:
ptxas nocore-mergefunc-nousealiases-bad.ptx, line 38; error : Illegal call target, device function expected
ptxas fatal : Ptx assembly aborted due to errors
What's happening is that MergeFunctions rewrites the `bar` function to call `foo`. However, directly calling an `extern "ptx-kernel"` function from another `extern "ptx-kernel"` is wrong.
If we disable the MergeFunctions pass from running at all, rustc generates correct PTX assembly: https://github.com/peterhj/nvptx-mergefunc-bug/blob/master/nocore-nomergefunc-ok.ptx
[1] a36b960df6/src/librustc_codegen_ssa/back/write.rs (L155)
[2] a36b960df6/src/librustc_codegen_llvm/llvm_util.rs (L64)
[3] https://github.com/rust-lang/rust/pull/56358
[4] https://github.com/rust-lang/rust/pull/49479
Fix stack overflow when finding blanket impls
Currently, SelectionContext tries to prevent stack overflow by keeping
track of the current recursion depth. However, this depth tracking is
only used when performing normal section (which includes confirmation).
No such tracking is performed for evaluate_obligation_recursively, which
can allow a stack overflow to occur.
To fix this, this commit tracks the current predicate evaluation depth.
This is done separately from the existing obligation depth tracking:
an obligation overflow can occur across multiple calls to 'select' (e.g.
when fulfilling a trait), while a predicate evaluation overflow can only
happen as a result of a deep recursive call stack.
Fixes#56701
I've re-used `tcx.sess.recursion_limit` when checking for predication evaluation overflows. This is such a weird corner case that I don't believe it's necessary to have a separate setting controlling the maximum depth.
Rollup of 11 pull requests
Successful merges:
- #57107 (Add a regression test for mutating a non-mut #[thread_local])
- #57132 (Document that `-C opt-level=0` implies `-C debug-assertions`.)
- #57212 (docs(rustc): Link to the book's source in rustc)
- #57302 (Fix unused_assignments false positive)
- #57350 (Better error note on unimplemented Index trait for string)
- #57635 (use structured macro and path resolve suggestions)
- #57650 (librustc_metadata: Pass a default value when unwrapping a span)
- #57657 (Add regression test to close#53787)
- #57658 (Two HIR tweaks)
- #57720 (Fix suggestions given mulitple bad lifetimes)
- #57725 (Use structured suggestion to surround struct literal with parenthesis)
Failed merges:
r? @ghost
Fix suggestions given mulitple bad lifetimes
When given multiple lifetimes prior to type parameters in generic
parameters, do not ICE and print the correct suggestion.
r? @estebank
CC @pnkfelix
Fixes: #57521
librustc_metadata: Pass a default value when unwrapping a span
Fixes#57323.
When compiling with `static-nobundle` a-la
`rustc -l static-nobundle=nonexistent main.rs`
we now get a neat output in the form of:
```
error[E0658]: kind="static-nobundle" is feature gated (see issue #37403)
|
= help: add #![feature(static_nobundle)] to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.
```
The build and tests completed successfully on my machine. Should I be adding a new test?
Better error note on unimplemented Index trait for string
fixes#56740
I've tried to compile suggestion from comments in the issue #56740, but unsure of it. So I'm open to advice :)
Current output will be like this:
```rust
error[E0277]: the type `str` cannot be indexed by `{integer}`
--> $DIR/str-idx.rs:3:17
|
LL | let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}`
| ^^^^ `str` cannot be indexed by `{integer}`
|
= help: the trait `std::ops::Index<{integer}>` is not implemented for `str`
= note: you can use `.chars().nth()` or `.bytes().nth()`
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
```
`x.py test src/test/ui` succeeded and I've also tested output manually by compiling the following code:
```rust
fn _f() {
let s = std::string::String::from("hello");
let _c = s[0];
let s = std::string::String::from("hello");
let mut _c = s[0];
let s = "hello";
let _c = s[0];
let s = "hello";
let mut _c = &s[0];
}
```
Not sure if some docs should be changed too. I will also fix error message in the [Book :: Indexing into Strings](db53e2e3cd/src/ch08-02-strings.md (indexing-into-strings)) if that PR will get approved :)
Document that `-C opt-level=0` implies `-C debug-assertions`.
I couldn't find it stated anywhere else (https://doc.rust-lang.org/nightly/rustc/codegen-options/index.html#opt-level).
It was a problem before here: https://github.com/rust-lang/rust/issues/39449, it got lost in the migration to the new documentation I assume.
On a sidenote: I think that `-C opt-level=0` having a sideeffect on another flag should be changed. Having compiler flags affecting others doesn't make much sense to me, they are used to fine tune anyway.
In any case, this plays no role in this PR.
Enhance `Pin` impl applicability for `PartialEq` and `PartialOrd`.
This allows for comparing for equality or ordering a `Pin<P>` and a `Pin<Q>` as long as `P` and `Q` are correspondingly comparable themselves *even when `P` and `Q` are different types*.
An example might be comparing a `Pin<&mut OsString>` to a `Pin<&mut PathBuf>`, which might arise from pin projections from a pair of larger contexts that aren't `Unpin`.
Fix sources sidebar not showing up
Fixes#57601.
The order of imports made it so that the sidebar creation was called before the sidebar sources were created. Like this, when the sources are loaded, they create the sidebar as expected.
r? @QuietMisdreavus
Cleanup PartialEq docs.
- Cleanup the `impl PartialEq<BookFormat> for Book` implementation
- Implement `impl PartialEq<Book> for BookFormat` so it’s symmetric
- Fixes https://github.com/rust-lang/rust/issues/53844.
- Removes the last example since it appears to be redundant with the
previous two examples.
Remove confusing comment about ideally using `!` for `c_void`
Using `!` for `c_void` would have the problem that pointers and
potentially references to an uninhabited type would be created, and at
least for references this is UB.
In addition document that newtype wrappers around `c_void` can be used
safely in place of `extern type` until the latter is stabilized.
----
I'm not 100% sure about the usage for opaque types as the [nomicon](https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs) still recommends using `#[repr(C)] pub struct Foo { _private: [u8; 0] }` but it seems like these two should be equivalent in the end? Also the `#[repr(C)]` (in both cases) should be unneeded because such types never being passed by value, never being dereferenced but only passed around as pointer or reference, so the representation of (*values* of) the type itself should not matter at all?
Also in context of `c_void` and `!` the second unresolved question in the [`extern type`](https://github.com/rust-lang/rust/issues/43467) stabilization ticket seems relevant
> In [std's](164619a8cf/src/libstd/os/raw.rs (L59-L64)) source, it is mentioned that LLVM expects i8* for C's void*.
> We'd need to continue to hack this for the two c_voids in std and libc.
> But perhaps this should be done across-the-board for all extern types?
> Somebody should check what Clang does.
Please correct me if my understanding is wrong and everything's actually fine as is.
rustdoc: Add option to persist doc test executables
Fixes#37048.
This is the initial version of the code so the doctest executables can be used for stuff like code coverage (specifically https://github.com/xd009642/tarpaulin/issues/13) the folders it goes into were just a first idea, so any better ones are welcome.
Right now it creates a directory structure like:
```
given_path/
|_____ <filename>_rs_<linenum>/
|_____ ...
|_____ <filename>_rs_<linenum>/
|_____ rust_out
```
I couldn't figure out where it actually outputs the file w/ the name, I suspect its somewhere deeper in the compiler.
It also adds the unstable `--persist-doctests` flag to `rustdoc` that enables this behavior.
Move spin_loop_hint to core::hint module
As mentioned in #55002. The new name is kept unstable to decide whether the function should have `_hint` in its name.