Update canonicalize docs
I was recently working with file-paths in Rust, and I felt let down by the `std::fs::canonicalize` docs, so I figured I should submit a PR with some suggestions.
I was looking for a method to turn a relative path into an absolute path. The `canonicalize` docs didn't mention the words "relative" or "absolute", but they did mention resolving symlinks (which is a kind of canonicalisation and does not imply converting to absolute), so I assumed that's all it did. To remedy this, I've added the word "absolute" to the description of both `std::fs::canonicalize` and `std::path::Path::canonicalize`.
After calling `canonicalize` on Windows, I ran into a bunch of other problems I would not have expected from the function's behaviour on Linux. Specifically, if you call `canonicalize` on a path:
- it's allowed to be much longer than it otherwise would
- `.join("a/slash/delimited/path")` gives you a broken path that Windows can't use, where the same operation would have worked perfectly without `canonicalize` (if the path were short enough)
- the resulting path may confuse other Windows programs if you pass it to them on the command-line, or write it to a config file that they read, etc.
...so I tried to summarize those behaviours too.
If I understand correctly, those behaviours are a side-effect of calling `GetFinalPathNameByHandle`, and the documentation says `canonicalize` might not call that function in future, so maybe those side-effects shouldn't be part of the function's documentation. However, I bet there's a lot of applications deliberately calling `canonicalize` just for the path-length-extension alone, so that particular side-effect is de-facto part of the `canonicalize` interface.
Remove all reference to DepGraph::work_products
This is an attempt at fixing #50500. It will remove the `work_products` key from `DepGraphData` completely, in favour of just passing the relevant data around. I went in a little blindly; everything appears to work just fine but I'd appreciate any additional advice people.
I didn't want to remove too much of what was already there, so I kept the structure pretty much the same (aside from some naming tweaks) - if anyone has suggestions on how to streamline it a little better, happy to follow up.
r? @michaelwoerister
Don't allocate when creating an empty BTree
Following the discussion in #50266, this adds a static instance of `LeafNode` that empty BTrees point to, and then replaces it on `insert`, `append`, and `entry`. This avoids allocating for empty maps.
Fixes#50266
r? @Gankro
don't make crazy suggestion for unreachable braced pub-use
The Higher Intermediate Representation doesn't have spans for visibility
keywords, so we were assuming that the first whitespace-delimited token
in the item span was the `pub` to be weakened. This doesn't work for
brace-grouped `use`s, which get lowered as if they were several
individual `use` statements, but with spans that only cover the braced
path-segments. Constructing a correct suggestion here presents some
challenges—until someone works those out, we can at least protect the
dignity of our compiler by not offering any suggestion at all for `use` items.
This resolves#50455 (but again, it would be desirable in the future to
make a correct suggestion instead of copping out like this).
r? @Manishearth
added missing implementation hint
Fixes [#50151](https://github.com/rust-lang/rust/issues/50151).
Actually, i don't know, should following code
`let x = |ref x: isize| { x += 1; };`
emit
`note: an implementation of std::ops::AddAssign might be missing for &isize`
or
`note: this is a reference to a type that + can be applied to; you need to dereference this variable once for this operation to work`
or both
Use the correct crt*.o files when linking musl targets.
This is supposed to support optionally using the system copy of musl
libc instead of the included one if supported. This currently only
affects the start files, which is enough to allow building rustc on musl
targets.
Most of the changes are analogous to crt-static.
Excluding the start files is something musl based distributions usually patch into their copy of rustc:
- https://github.com/alpinelinux/aports/blob/eb064c8/community/rust/musl-fix-linux_musl_base.patch
- https://github.com/voidlinux/void-packages/blob/77400fc/srcpkgs/rust/patches/link-musl-dynamically.patch
For third-party distributions that not yet carry those patches it would be nice if it was supported without the need to patch upstream sources.
## Reasons
### What breaks?
Some start files were missed when originally writing the logic to swap in musl start files (gcc comes with its own start files, which are suppressed by -nostdlib, but not manually included later on). This caused #36710, which also affects rustc with the internal llvm copy or any other system libraries that need crtbegin/crtend.
### How is it fixed?
The system linker already has all the logic to decide which start files to include, so we can just defer to it (except of course if it doesn't target musl).
### Why is it optional?
In #40113 it was first tried to remove the start files, which broke compiling musl-targeting static binaries with a glibc-targeting compiler. This is why it eventually landed without removing the start files. Being an option side-steps the issue.
### Why are the start files still installed?
This has the nice side-effect, that the produced rust-std-* binaries can still be used by on a glibc-targeting system with a rustc built against glibc.
## Does it work?
With the following build script (using [musl-cross-make](https://github.com/richfelker/musl-cross-make)): https://shadowice.org/~mixi/rust-musl/build.sh, I was able to cross-compile a musl-host musl-targeting rustc on a glibc-based system. The resulting binaries are at https://shadowice.org/~mixi/rust-musl/binaries/. This also requires #50103 and #50104 (which are also applied to the branch the build script uses).
Rename the 2018 edition lint names
* `rust_2018_breakage` -> `rust_2018_compatibility` - the lint for ensuring
that your code, in the 2015 edition, is compatible with the 2018 edition's
semantics. This is required to pass *before* you enable the 2018 edition.
* `rust_2018_migration` -> `rust_2018_idioms` - the lint for writing idiomatic
code after you've already enabled the 2018 edition
The Higher Intermediate Representation doesn't have spans for visibility
keywords, so we were assuming that the first whitespace-delimited token
in the item span was the `pub` to be weakened. This doesn't work for
brace-grouped `use`s, which get lowered as if they were several
individual `use` statements, but with spans that only cover the braced
path-segments. Constructing a correct suggestion here presents some
challenges—until someone works those out, we can at least protect the
dignity of our compiler marking the suggestion for `use` items as
potentially incorrect.
This resolves#50455 (but again, it would be desirable in the future to
make a correct suggestion instead of copping out like this).
Improve single-use and zero-use lifetime lints
The code now correctly identifies *when* to lint -- or more correctly, anyhow -- but it doesn't yet offer suggestions for how to fix.
(I just remembered when writing this I had meant to go back over some of these cases around e.g. impl Trait and double check that everything is right...)
cc #44752
r? @cramertj
Rollup of 18 pull requests
Successful merges:
- #49423 (Extend tests for RFC1598 (GAT))
- #50010 (Give SliceIndex impls a test suite of girth befitting the implementation (and fix a UTF8 boundary check))
- #50447 (Fix update-references for tests within subdirectories.)
- #50514 (Pull in a wasm fix from LLVM upstream)
- #50524 (Make DepGraph::previous_work_products immutable)
- #50532 (Don't use Lock for heavily accessed CrateMetadata::cnum_map.)
- #50538 ( Make CrateNum allocation more thread-safe. )
- #50564 (Inline `Span` methods.)
- #50565 (Use SmallVec for DepNodeIndex within dep_graph.)
- #50569 (Allow for specifying a linker plugin for cross-language LTO)
- #50572 (Clarify in the docs that `mul_add` is not always faster.)
- #50574 (add fn `into_inner(self) -> (Idx, Idx)` to RangeInclusive (#49022))
- #50575 (std: Avoid `ptr::copy` if unnecessary in `vec::Drain`)
- #50588 (Move "See also" disambiguation links for primitive types to top)
- #50590 (Fix tuple struct field spans)
- #50591 (Restore RawVec::reserve* documentation)
- #50598 (Remove unnecessary mutable borrow and resizing in DepGraph::serialize)
- #50606 (Retry when downloading the Docker cache.)
Failed merges:
- #50161 (added missing implementation hint)
- #50558 (Remove all reference to DepGraph::work_products)
Map the stack guard page with max protection on NetBSD
On NetBSD the initial mmap() protection of a mapping can not be made
less restrictive with mprotect().
So when mapping a stack guard page, use the maximum protection
we ever want to use, then mprotect() it to the permission we
want it to have initially.
Fixes#50313
* `rust_2018_breakage` -> `rust_2018_compatibility` - the lint for ensuring
that your code, in the 2015 edition, is compatible with the 2018 edition's
semantics. This is required to pass *before* you enable the 2018 edition.
* `rust_2018_migration` -> `rust_2018_idioms` - the lint for writing idiomatic
code after you've already enabled the 2018 edition
Retry when downloading the Docker cache.
As a safety measure, prevent spuriously needing to rebuild the docker image in case the network was reset while downloading.
Also, adjusted the retry function to insert a sleep between retries, because retrying immediately will often just hit the same issue.
Remove unnecessary mutable borrow and resizing in DepGraph::serialize
I might be mistaken, but I noticed this whilst in this file for something else. It appears that this mutable borrow is unnecessary and since it's locking it should be removed. The resizing looks redundant since nothing additional is added to the fingerprints in this function, so that can also be removed.
Restore RawVec::reserve* documentation
When the RawVec::try_reserve* methods were added, they took the place of
the ::reserve* methods in the source file, and new ::reserve* methods
wrapping the new try_reserve* methods were created. But the
documentation didn't move along, such that:
- reserve_* methods are barely documented.
- try_reserve_* methods have unmodified documentation from reserve_*,
such that their documentation indicate they are panicking/aborting.
This moves the documentation back to the right methods, with a
placeholder documentation for the try_reserve* methods.
std: Avoid `ptr::copy` if unnecessary in `vec::Drain`
This commit is spawned out of a performance regression investigation in #50496.
In tracking down this regression it turned out that the `expand_statements`
function in the compiler was taking quite a long time. Further investigation
showed two key properties:
* The function was "fast" on glibc 2.24 and slow on glibc 2.23
* The hottest function was memmove from glibc
Combined together it looked like glibc gained an optimization to the memmove
function in 2.24. Ideally we don't want to rely on this optimization, so I
wanted to dig further to see what was happening.
The hottest part of `expand_statements` was `Drop for Drain` in the call to
`splice` where we insert new statements into the original vector. This *should*
be a cheap operation because we're draining and replacing iterators of the exact
same length, but under the hood memmove was being called a lot, causing a
slowdown on glibc 2.23.
It turns out that at least one of the optimizations in glibc 2.24 was that
`memmove` where the src/dst are equal becomes much faster. [This program][prog]
executes in ~2.5s against glibc 2.23 and ~0.3s against glibc 2.24, exhibiting
how glibc 2.24 is optimizing `memmove` if the src/dst are equal.
And all that brings us to what this commit itself is doing. The change here is
purely to `Drop for Drain` to avoid the call to `ptr::copy` if the region being
copied doesn't actually need to be copied. For normal usage of just `Drain`
itself this check isn't really necessary, but because `Splice` internally
contains `Drain` this provides a nice speed boost on glibc 2.23. Overall this
should fix the regression seen in #50496 on glibc 2.23 and also fix the
regression on Windows where `memmove` looks to not have this optimization.
Note that the way `splice` was called in `expand_statements` would cause a
quadratic number of elements to be copied via `memmove` which is likely why the
tuple-stress benchmark showed such a severe regression.
Closes#50496
[prog]: https://gist.github.com/alexcrichton/c05bc51c6771bba5ae5b57561a6c1cd3
Allow for specifying a linker plugin for cross-language LTO
This PR makes the `-Zcross-lang-lto` flag optionally take the path to the `LLVMgold.so` linker plugin. If this path is specified, `rustc` will invoke the linker with the correct arguments (i.e. `-plugin` and various `-plugin-opt`s).
This can be used to ergonomically enable cross-language LTO for Rust programs with C/C++ dependencies:
```
clang -O2 test.c -otest.o -c -flto=thin
llvm-ar -rv libxxx.a test.o
rustc -L. main.rs -Zcross-lang-lto=/usr/lib64/LLVMgold.so -O -Clink-arg=-fuse-ld=gold
```
- Note that in theory this should work with Gold, LLD, and newer versions of binutils' LD but on my current system I could only get it to work with Gold.
- Also note that this will work best if the Clang version and Rust's LLVM version are close enough. Clang 6.0 works well with the current nightly.
r? @alexcrichton
Inline `Span` methods.
Because they are simple and hot.
This change speeds up some incremental runs of a few rustc-perf
benchmarks, the best by 3%.
Here are the ones with a speedup of at least 1%:
```
coercions
avg: -1.1% min: -3.4% max: -0.2%
html5ever-opt
avg: -0.8% min: -1.7% max: -0.2%
clap-rs-check
avg: -0.3% min: -1.4% max: 0.7%
html5ever
avg: -0.7% min: -1.2% max: -0.4%
html5ever-check
avg: -0.9% min: -1.1% max: -0.8%
clap-rs
avg: -0.4% min: -1.1% max: -0.1%
crates.io-check
avg: -0.8% min: -1.0% max: -0.6%
serde-opt
avg: -0.6% min: -1.0% max: -0.3%
```