Canonicalize inputs to const eval where needed
Canonicalize inputs to const eval, so that they can contain inference variables. Which enables invoking const eval queries even if the current param env has inference variable within it, which can occur during trait selection.
This is a reattempt of #67717, in a far less invasive way.
Fixes#68477
r? @nikomatsakis
cc @eddyb
Rollup of 9 pull requests
Successful merges:
- #69379 (Fail on multiple declarations of `main`.)
- #69430 (librustc_typeck: remove loop that never actually loops)
- #69449 (Do not ping PR reviewers in toolstate breakage)
- #69491 (rustc_span: Add `Symbol::to_ident_string` for use in diagnostic messages)
- #69495 (don't take redundant references to operands)
- #69496 (use find(x) instead of filter(x).next())
- #69501 (note that find(f) is equivalent to filter(f).next() in the docs.)
- #69527 (Ignore untracked paths when running `rustfmt` on repository.)
- #69529 (don't use .into() to convert types into identical types.)
Failed merges:
r? @ghost
Ignore untracked paths when running `rustfmt` on repository.
This is a step towards resolving #69291
(It might be the only step necessary at the moment; I'm not yet sure.)
Fail on multiple declarations of `main`.
Closes#67946.
Previously, when inserting the entry function, we only checked for
duplicate _definitions_ of `main`. However, it's possible to cause
problems even only having a duplicate _declaration_. For example,
shadowing `main` using an extern block isn't caught by the current
check, and causes an assertion failure down the line in in LLVM code.
r? @pnkfelix
Revert "Mark attributes consumed by `check_mod_attrs` as normal"
This reverts commit d78b22f35e.
Those changes were incompatible with incremental compilation since the
effect `check_mod_attrs` has with respect to marking the attributes as
used is neither persisted nor recomputed.
Mark other variants as uninitialized after switch on discriminant
During drop elaboration, which builds the drop ladder that handles destruction during stack unwinding, we attempt to remove MIR `Drop` terminators that will never be reached in practice. This reduces the number of basic blocks that are passed to LLVM, which should improve performance. In #66753, a user pointed out that unreachable `Drop` terminators are common in functions like `Option::unwrap`, which move out of an `enum`. While discussing possible remedies for that issue, @eddyb suggested moving const-checking after drop elaboration. This would allow the former, which looks for `Drop` terminators and replicates a small amount of drop elaboration to determine whether a dropped local has been moved out, leverage the work done by the latter.
However, it turns out that drop elaboration is not as precise as it could be when it comes to eliminating useless drop terminators. For example, let's look at the code for `unwrap_or`.
```rust
fn unwrap_or<T>(opt: Option<T>, default: T) -> T {
match opt {
Some(inner) => inner,
None => default,
}
}
```
`opt` never needs to be dropped, since it is either moved out of (if it is `Some`) or has no drop glue (if it is `None`), and `default` only needs to be dropped if `opt` is `Some`. This is not reflected in the MIR we currently pass to codegen.
![pasted_image](https://user-images.githubusercontent.com/29463364/73384403-109a0d80-4280-11ea-8500-0637b368f2dc.png)
@eddyb also suggested the solution to this problem. When we switch on an enum discriminant, we should be marking all fields in other variants as definitely uninitialized. I implemented this on top of alongside a small optimization (split out into #68943) that suppresses drop terminators for enum variants with no fields (e.g. `Option::None`). This is the resulting MIR for `unwrap_or`.
![after](https://user-images.githubusercontent.com/29463364/73384823-e432c100-4280-11ea-84bd-d0bcc3b777b4.png)
In concert with #68943, this change speeds up many [optimized and debug builds](https://perf.rust-lang.org/compare.html?start=d55f3e9f1da631c636b54a7c22c1caccbe4bf0db&end=0077a7aa11ebc2462851676f9f464d5221b17d6a). We need to carefully investigate whether I have introduced any miscompilations before merging this. Code that never drops anything would be very fast indeed until memory is exhausted.
Simplify the signature of par_for_each_in
Given `T: IntoIterator`/`IntoParallelIterator`, `T::Item` is
unambiguous, so we don't need the explicit trait casting.
resolve: `lifetimes.rs` -> `late/lifetimes.rs`
Lifetime resolution should ideally be merged into the late resolution pass, at least for named lifetimes.
Let's move it closer to it for a start.
Backport only: avoid ICE on bad placeholder type
#69148 has a proper fix, but it is too big to backport.
This change avoids the ICE by actually emitting an appropriate error. The
output will be duplicated in some cases, but that's better than the
avoidable ICE.
r? @Centril