borrowck::mir::dataflow: ignore unwind edges of empty drops
This avoids creating drop flags in many unnecessary situations.
Fixes#41110.
r? @nagisa
beta-nominating because regression. However, that is merely a small perf regression and codegen changes are always risky, so we might let this slide for 1.17.
Fixed ICEs with pattern matching in const expression
Fixed 2 ICEs with when pattern matching inside a constant expression.
Both of these ICEs now resolve to an appropriate compiler error.
1. ICE was caused by a compiler bug to implement discriminant const qualify.
I removed this intentionally thrown bug and changed it to a FIXME as the unimplemented expression type is handled as a compiler error elsewhere.
2. ICE was caused during a drop check when checking if a variable lifetime outlives the current scope if there was no parent scope .
I've changed it to stop checking if there is no parent scope for the current scope. It is valid syntax for a const variable to be assigned a match expression with no enclosing scope.
The ICE seemed to mainly be used as a defensive check for bugs elsewhere.
Fixes#38199.
Fixes#31577.
Fixes#29093.
Fixes#40012.
Introduce `TyErr` independent from `TyInfer`
Add a `TyErr` type to represent unknown types in places where
parse errors have happened, while still able to build the AST.
Initially only used to represent incorrectly written fn arguments and
avoid "expected X parameters, found Y" errors when called with the
appropriate amount of parameters. We cannot use `TyInfer` for this as
`_` is not allowed as a valid argument type.
Example output:
```rust
error: expected one of `:` or `@`, found `,`
--> file.rs:12:9
|
12 | fn bar(x, y: usize) {}
| ^
error[E0061]: this function takes 2 parameters but 3 parameters were supplied
--> file.rs:19:9
|
12 | fn bar(x, y) {}
| --------------- defined here
...
19 | bar(1, 2, 3);
| ^^^^^^^ expected 2 parameters
```
Fix#34264.
Suggest using enum when a variant is used as a type
Given a file:
```rust
enum Fruit {
Apple(i64),
Orange(i64),
}
fn should_return_fruit() -> Apple {
Apple(5)
}
```
Provide the following output:
```rust
error[E0412]: cannot find type `Apple` in this scope
--> file.rs:16:29
|
16 | fn should_return_fruit() -> Apple {
| ^^^^^ not found in this scope
|
help: there is an enum variant `Fruit::Apple`, did you mean to use `Fruit`?
--> file.rs:12:5
|
12 | Apple(i64),
| ^^^^^^^^^^
error[E0425]: cannot find function `Apple` in this scope
--> file.rs:17:5
|
17 | Apple(5)
| ^^^^^ not found in this scope
|
= help: possible candidate is found in another module, you can import it into scope:
`use Fruit::Apple;`
```
Fix#35675.
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
rustdoc: collapse docblock before showing label
The animation for collapsing descriptions is currently pretty jarring, as the label starts fading in as the description is collapsing. This causes the description to jump down a line (and sometimes change indentation) while animating.
This PR modifies this behavior to collapse the block entirely before starting to fade in the collapse button label.
While this PR works well for descriptions of structs, traits, etc., it still does not look ideal for attributes. I'd appreciate any suggestions for improving that animation. Perhaps we want to optimize for the single-attribute case, and try not to collapse the attribute list entirely before fading in the label?
travis: Use upstream LLVM repositories for Fuchsia
The Fuchsia copies of LLVM repositories contain additional patches
for work-in-progress features and there is some amount of churn that
may break Rust. Use upstream LLVM repositories instead for building
the toolchain used by the Fuchsia builder.
dist-powerpc-linux: use a pure 32-bit CPU profile
With `-mcpu=power4`, code might use instructions like `fcfid`, excluding
older CPUs like the PowerPC G4, which apparently some users would like
to use. The generic `-mcpu=powerpc` should stick to pure 32-bit PowerPC
instructions.
Fixesrust-lang/cargo#3852.
Re-enable appveyor cache
After breaking the queue last time, I'm cautiously back with a PR to re-enable caching on appveyor.
If you look at https://ci.appveyor.com/project/rust-lang/rust/build/1.0.2623/job/46o90by4ari6gege (one of the multiple runs that started failed, there are actually two errors - one for restoring the cache, one right at the bottom for creating a directory. I only noticed the restore error at the time as I was a bit rushed to revert and didn't stop to wonder why it continued - turns out appveyor [does not abort on cache restore failure](https://github.com/appveyor/ci/issues/723).
Turns out the cause of the build failures was the cache directory existing and me being thinking that because mkdir on windows is [recursive by default](http://stackoverflow.com/a/905239/2352259), it ignores the error if the directory already exists. Apparently this is not true, so now it checks if the directory exists before attempting to create.
In addition, I've added some more paranoia to double check everything is sane.
cstore: return an immutable borrow from `visible_parent_map`
This prevents an ICE when `visible_parent_map` is called multiple times, for example when an item referenced in an impl signature is imported from an `extern crate` statement occurs within an impl.
Fixes#41053.
r? @eddyb
Handle DefPath hashing centrally as part of DefPathTable (+ save work during SVH calculation)
In almost all cases where we construct a `DefPath`, we just hash it and throw it away again immediately.
With this PR, the compiler will immediately compute and store the hash for each `DefPath` as it is allocated. This way we
+ can get rid of any subsequent `DefPath` hash caching (e.g. the `DefPathHashes`),
+ don't need to allocate a transient `Vec` for holding the `DefPath` (although I'm always surprised how little these small, dynamic allocations seem to hurt performance), and
+ we don't hash `DefPath` prefixes over and over again.
That last part is because we construct the hash for `prefix::foo` by hashing `(hash(prefix), foo)` instead of hashing every component of prefix.
The last commit of this PR is pretty neat, I think:
```
The SVH (Strict Version Hash) of a crate is currently computed
by hashing the ICHes (Incremental Computation Hashes) of the
crate's HIR. This is fine, expect that for incr. comp. we compute
two ICH values for each HIR item, one for the complete item and
one that just includes the item's interface. The two hashes are
are needed for dependency tracking but if we are compiling
non-incrementally and just need the ICH values for the SVH,
one of them is enough, giving us the opportunity to save some
work in this case.
```
r? @nikomatsakis
This PR depends on https://github.com/rust-lang/rust/pull/40878 to be merged first (you can ignore the first commit for reviewing, that's just https://github.com/rust-lang/rust/pull/40878).
Only use cargo-vendor if building from git sources
The only time we need to vendor sources is when building from git. If one is
building from a rustc source tarball, everything should already be in place.
This also matters for distros which do offline builds, as they can't install
cargo-vendor this way.
This adds a common `Build::src_is_git` flag, and then uses it in the dist-src
target to decide whether to install or use `cargo-vendor` at all.
Fixes#41042.
The SVH (Strict Version Hash) of a crate is currently computed
by hashing the ICHes (Incremental Computation Hashes) of the
crate's HIR. This is fine, expect that for incr. comp. we compute
two ICH values for each HIR item, one for the complete item and
one that just includes the item's interface. The two hashes are
are needed for dependency tracking but if we are compiling
non-incrementally and just need the ICH values for the SVH,
one of them is enough, giving us the opportunity to save some
work in this case.
On demandify reachability
cc https://github.com/rust-lang/rust/issues/40746
I tried following this guidance from #40746:
> The following tasks currently execute before a tcx is built, but they could be easily converted into queries that are requested after tcx is built. The main reason they are the way they are was to avoid a gratuitious refcell (but using the refcell map seems fine)...
but the result of moving `region_maps` out of `TyCtxt` and into a query caused a lot of churn, and seems like it could potentially result in a rather large performance hit, since it means a dep-graph lookup on every use of `region_maps` (rather than just a field access). Possibly `TyCtxt` could store a `RefCell<Option<RegionMap>>` internally and use that to prevent repeat lookups, but that feels like it's duplicating the work of the dep-graph. @nikomatsakis What did you have in mind for this?
The Fuchsia copies of LLVM repositories contain additional patches
for work-in-progress features and there is some amount of churn that
may break Rust. Use upstream LLVM repositories instead for building
the toolchain used by the Fuchsia builder.
#[used] attribute
(For an explanation of what this feature does, read the commit message)
I'd like to propose landing this as an experimental feature (experimental as in:
no clear stabilization path -- like `asm!`, `#[linkage]`) as it's low
maintenance (I think) and relevant to the "Usage in resource-constrained
environments" exploration area.
The main use case I see is running code before `main`. This could be used, for
instance, to cheaply initialize an allocator before `main` where the alternative
is to use `lazy_static` to initialize the allocator on its first use which it's
more expensive (atomics) and doesn't work on ARM Cortex-M0 microcontrollers (no
`AtomicUsize` on that platform)
Here's a `std` example of that:
``` rust
unsafe extern "C" fn before_main_1() {
println!("Hello");
}
unsafe extern "C" fn before_main_2() {
println!("World");
}
#[link_section = ".init_arary"]
#[used]
static INIT_ARRAY: [unsafe extern "C" fn(); 2] = [before_main_1, before_main_2];
fn main() {
println!("Goodbye");
}
```
```
$ rustc -C lto -C opt-level=3 before_main.rs
$ ./before_main
Hello
World
Goodbye
```
In general, this pattern could be used to let *dependencies* run code before
`main` (which sounds like it could go very wrong in some cases). There are
probably other use cases; I hope that the people I have cc-ed can comment on
those.
Note that I'm personally unsure if the above pattern is something we want to
promote / allow and that's why I'm proposing this feature as experimental. If
this leads to more footguns than benefits then we can just axe the feature.
cc @nikomatsakis ^ I know you have some thoughts on having a process for
experimental features though I'm fine with writing an RFC before landing this.
- `dead_code` lint will have to be updated to special case `#[used]` symbols.
- Should we extend `#[used]` to work on non-generic functions?
cc rust-lang/rfcs#1002
cc rust-lang/rfcs#1459
cc @dpc @JinShil