When reuing a definition across codegen units, we obviously cannot use
internal linkage, but using external linkage means that we can end up
with multiple conflicting definitions of a single symbol across
multiple crates. Since the definitions should all be equal
semantically, we can use weak_odr linkage to resolve the situation.
Fixes#32518
We use a 64bit integer to pass the set of attributes that is to be
removed, but the called C function expects a 32bit integer. On most
platforms this doesn't cause any problems other than being unable to
unset some attributes, but on ARM even the lower 32bit aren't handled
correctly because the 64bit value is passed in different registers, so
the C function actually sees random garbage.
So we need to fix the relevant functions to use 32bit integers instead.
Additionally we need an implementation that actually accepts 64bit
integers because some attributes can only be unset that way.
Fixes#32360
As discussed in
https://github.com/rust-lang/rust/pull/32293#issuecomment-200597130,
adding link guards are a heuristic that is causing undue complications:
- the link guards inject extra public symbols, which is not always OK.
- link guards as implemented could be a non-trivial performance hit,
because no attempt is made to "de-duplicate" the dependency graph,
so at worst you have O(N!) calls to the link guard functions.
Nonetheless, link guards are very helpful in detecting errors, so it may
be worth adding them back in some modified form in the future.
This change has a few parts. We introduce a new `item_path` module for
constructing item paths. The job of this module is basically to make
nice, user-readable paths -- but these paths are not necessarily 100%
unique. They meant to help a *human* find code, but not necessarily a
compute. These paths are used to drive `item_path_str` but also symbol
names.
Because the paths are not unique, we also modify the symbol name hash to
include the full `DefPath`, whereas before it included only those
aspects of the def-path that were not included in the "informative"
symbol name.
Eventually, I'd like to make the item-path infrastructure a bit more
declarative. Right now it's based purely on strings. In particular, for
impls, we should supply the raw types to the `ItemPathBuffer`, so that
symbol names can be encoded using the C++ encoding scheme for better
integration with tooling.
We want to prevent compiling something against one version
of a dynamic library and then, at runtime accidentally
using a different version of the dynamic library. With the
old symbol-naming scheme this could not happen because every
symbol had the SVH in it and you'd get an error by the
dynamic linker when using the wrong version of a dylib. With
the new naming scheme this isn't the case any more, so this
patch adds the "link-guard" to prevent this error case.
This is implemented as follows:
- In every crate that we compile, we emit a function called
"__rustc_link_guard_<crate-name>_<crate-svh>"
- The body of this function contains calls to the
"__rustc_link_guard" functions of all dependencies.
- An executable contains a call to it's own
"__rustc_link_guard" function.
As a consequence the "__rustc_link_guard" function call graph
mirrors the crate graph and the dynamic linker will fail if a
wrong dylib is loaded somewhere because its
"__rustc_link_guard" function will contain a different SVH in
its name.
Scopes in mir
This PR adds scopes to MIR. There is a tree of scopes (each represented by a `ScopeId`). Every statement, variable, and terminator now has an associated scope and span. It also adds a `-Z dump-mir` switch one can use to conveniently examine the MIR as optimizations proceed.
The intention is two-fold. First, to support MIR debug-info. This PR does not attempt to modify trans to make use of the scope information, however.
Second, in a more temporary capacity, to support the goal of moving regionck and borowck into the MIR. To that end, the PR also constructs a "scope auxiliary" table storing the extent of each span (this is kept separate from the main MIR, since it contains node-ids) and the dom/post-dom of the region in the graph where the scope occurs. When we move to non-lexical lifetimes, I expect this auxiliary information to be discarded, but that is still some ways in the future (requires, at minimum, an RFC, and there are some thorny details to work out -- though I've got an in-progress draft).
Right now, I'm just dropping this auxiliary information after it is constructed. I was debating for some time whether to add some sort of sanity tests, but decided to just open this PR instead, because I couldn't figure out what such a test would look like (and we don't have independent tests for this today beyond the regionck and borrowck tests).
I'd prefer not to store the auxiliary data into any kind of "per-fn" map. Rather, I'd prefer that we do regionck/borrowck/whatever-else immediately after construction -- that is, we build the MIR for fn X and immediately thereafter do extended correctness checking on it. This will reduce peak memory usage and also ensure that the auxiliary data doesn't exist once optimizations begin. It also clarifies the transition point where static checks are complete and MIR can be more freely optimized.
cc @rust-lang/compiler @nagisa
This hack has long since outlived its usefulness; the transition to
trans passing around full substitutions is basically done. Instead of
`ErasedRegions`, just supply substitutions with a suitable number of
`'static` entries, and invoke `erase_regions` when needed (the latter of
which we already do).
Fix const trans
Fix#30615.
The idea was that when there are N autoderefs, first do N-1 derefs and check for autoref. If there is autoref, done, if not, do one more deref. But when N is zero, doing one more deref is wrong.
convert 99.9% of `try!`s to `?`s
The first commit is an automated conversion using the [untry] tool and the following command:
```
$ find -name '*.rs' -type f | xargs untry
```
at the root of the Rust repo.
[untry]: https://github.com/japaric/untry
cc @rust-lang/lang @alexcrichton @brson
Automated conversion using the untry tool [1] and the following command:
```
$ find -name '*.rs' -type f | xargs untry
```
at the root of the Rust repo.
[1]: https://github.com/japaric/untry
Move analysis for MIR borrowck
This PR adds code for doing MIR-based gathering of the moves in a `fn` and the dataflow to determine where uninitialized locations flow to, analogous to how the same thing is done in `borrowck`.
It also adds a couple attributes to print out graphviz visualizations of the analyzed MIR that includes the dataflow analysis results.
cc @nikomatsakis