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
The hash tests were written before the assert_ne macro was added to the standard library. The assert_ne macro provides better output in case of a failure.
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.
Generalized article_and_description
r? @matthewjasper
The logic of finding the right word and article to print seems to be repeated elsewhere... this is an experimental method to unify this logic...
Rollup of 5 pull requests
Successful merges:
- #68712 (Add methods to 'leak' RefCell borrows as references with the lifetime of the original reference)
- #69209 (Miscellaneous cleanup to formatting)
- #69381 (Allow getting `no_std` from the config file)
- #69434 (rustc_metadata: Use binary search from standard library)
- #69447 (Minor refactoring of statement parsing)
Failed merges:
r? @ghost