Remove interior mutability from TraitDef by turning fields into queries
This PR gets rid of anything `std::cell` in `TraitDef` by
- moving the global list of trait impls from `TraitDef` into a query,
- moving the list of trait impls relevent for some self-type from `TraitDef` into a query
- moving the specialization graph of trait impls into a query, and
- moving `TraitDef::object_safety` into a query.
I really like how querifying things not only helps with incremental compilation and on-demand, but also just plain makes the code cleaner `:)`
There are also some smaller fixes in the PR. Commits can be reviewed separately.
r? @eddyb or @nikomatsakis
Move the code for loading metadata from rlibs and dylibs from
rustc_metadata into rustc_trans, and introduce a trait to avoid
introducing a direct dependency on rustc_trans.
This means rustc_metadata is no longer rebuilt when LLVM changes.
rustc: Add a new `-Z force-unstable-if-unmarked` flag
This commit adds a new `-Z` flag to the compiler for use when bootstrapping the
compiler itself. We want to be able to use crates.io crates, but we also want
the usage of such crates to be as ergonomic as possible! To that end compiler
crates are a little tricky in that the crates.io crates are not annotated as
unstable, nor do they expect to pull in unstable dependencies.
To cover all these situations it's intended that the compiler will forever now
bootstrap with `-Z force-unstable-if-unmarked`. This flags serves a dual purpose
of forcing crates.io crates to themselves be unstable while also allowing them
to use other "unstable" crates.io crates. This should mean that adding a
dependency to compiler no longer requires upstream modification with
unstable/staged_api attributes for inclusion!
This commit adds a new `-Z` flag to the compiler for use when bootstrapping the
compiler itself. We want to be able to use crates.io crates, but we also want
the usage of such crates to be as ergonomic as possible! To that end compiler
crates are a little tricky in that the crates.io crates are not annotated as
unstable, nor do they expect to pull in unstable dependencies.
To cover all these situations it's intended that the compiler will forever now
bootstrap with `-Z force-unstable-if-unmarked`. This flags serves a dual purpose
of forcing crates.io crates to themselves be unstable while also allowing them
to use other "unstable" crates.io crates. This should mean that adding a
dependency to compiler no longer requires upstream modification with
unstable/staged_api attributes for inclusion!
This is a more principled version of the `RefCell` we were using
before. We now allocate a `Steal<Mir<'tcx>>` for each intermediate MIR
pass; when the next pass steals the entry, any later attempts to use it
will panic (there is no way to *test* if MIR is stolen, you're just
supposed to *know*).
The new setup is as follows. There is a pipeline of MIR passes that each
run **per def-id** to optimize a particular function. You are intended
to request MIR at whatever stage you need it. At the moment, there is
only one stage you can request:
- `optimized_mir(def_id)`
This yields the final product. Internally, it pulls the MIR for the
given def-id through a series of steps. Right now, these are still using
an "interned ref-cell" but they are intended to "steal" from one
another:
- `mir_build` -- performs the initial construction for local MIR
- `mir_pass_set` -- performs a suite of optimizations and transformations
- `mir_pass` -- an individual optimization within a suite
So, to construct the optimized MIR, we invoke:
mir_pass_set((MIR_OPTIMIZED, def_id))
which will build up the final MIR.
When -Z profile is passed, the GCDAProfiling LLVM pass is added
to the pipeline, which uses debug information to instrument the IR.
After compiling with -Z profile, the $(OUT_DIR)/$(CRATE_NAME).gcno
file is created, containing initial profiling information.
After running the program built, the $(OUT_DIR)/$(CRATE_NAME).gcda
file is created, containing branch counters.
The created *.gcno and *.gcda files can be processed using
the "llvm-cov gcov" and "lcov" tools. The profiling data LLVM
generates does not faithfully follow the GCC's format for *.gcno
and *.gcda files, and so it will probably not work with other tools
(such as gcov itself) that consume these files.
Implement a file-path remapping feature in support of debuginfo and reproducible builds
This PR adds the `-Zremap-path-prefix-from`/`-Zremap-path-prefix-to` commandline option pair and is a more general implementation of #41419. As opposed to the previous attempt, this implementation should enable reproducible builds regardless of the working directory of the compiler.
This implementation of the feature is more general in the sense that the re-mapping will affect *all* paths the compiler emits, including the ones in error messages.
r? @alexcrichton
#37653 support `default impl` for specialization
this commit implements the first step of the `default impl` feature:
> all items in a `default impl` are (implicitly) `default` and hence
> specializable.
In order to test this feature I've copied all the tests provided for the
`default` method implementation (in run-pass/specialization and
compile-fail/specialization directories) and moved the `default` keyword
from the item to the impl.
See [referenced](https://github.com/rust-lang/rust/issues/37653) issue for further info
r? @aturon
this commit implements the first step of the `default impl` feature:
all items in a `default impl` are (implicitly) `default` and hence
specializable.
In order to test this feature I've copied all the tests provided for the
`default` method implementation (in run-pass/specialization and
compile-fail/specialization directories) and moved the `default` keyword
from the item to the impl.
See referenced issue for further info
this avoids parsing item attributes on each call to `item_attrs`, which takes
off 33% (!) of translation time and 50% (!) of trans-item collection time.
This may seem like overkill, but it's exactly what we want/need for
incremental compilation I think. In particular, while generating code
for some codegen unit X, we can wind up querying about any number of
external items, and we only want to be forced to rebuild X is some of
those changed from a foreign item to otherwise. Factoring this into a
query means we would re-run only if some `false` became `true` (or vice
versa).
Instead of collecting all potential inputs to some metadata entry and
hashing those, we directly hash the values we are storing in metadata.
This is more accurate and doesn't suffer from quadratic blow-up when
many entries have the same dependencies.
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
on-demand-ify `custom_coerce_unsized_kind` and `inherent-impls`
This "on-demand" task both checks for errors and computes the custom unsized kind, if any. This task is only defined on impls of `CoerceUnsized`; invoking it on any other kind of impl results in a bug. This is just to avoid having an `Option`, could easily be changed.
r? @eddyb
There are now 3 queries:
- inherent_impls(def-id): for a given type, get a `Rc<Vec<DefId>>` with
all its inherent impls. This internally uses `crate_inherent_impls`,
doing some hacks to keep the current deps (which, btw, are not clearly
correct).
- crate_inherent_impls(crate): gathers up a map from types
to `Rc<Vec<DefId>>`, touching the entire krate, possibly generating
errors.
- crate_inherent_impls_overlap_check(crate): performs overlap checks
between the inherent impls for a given type, generating errors.
This "on-demand" task both checks for errors and computes the custom
unsized kind, if any. This task is only defined on impls of
`CoerceUnsized`; invoking it on any other kind of impl results in a bug.
This is just to avoid having an `Option`, could easily be changed.
This removes the Cell from AdtDef. Also, moving destructor validity
checking to on-demand (forced during item-type checking) ensures that
invalid destructors can't cause ICEs.
Fixes#38868.
Fixes#40132.
Refactor the parser to consume token trees
This is groundwork for efficiently parsing attribute proc macro invocations, bang macro invocations, and `TokenStream`-based attributes and fragment matchers.
This improves parsing performance by 8-15% and expansion performance by 0-5% on a sampling of the compiler's crates.
r? @nrc
Cleanup refactoring around DefPath handling
This PR makes two big changes:
* All DefPaths of a crate are now stored in metadata in their own table (as opposed to `DefKey`s as part of metadata `Entry`s.
* The compiler will no longer allocate a pseudo-local DefId for inlined HIR nodes (because those are gross). Inlined HIR nodes will have a NodeId but they don't have there own DefId anymore. Turns out they were not needed anymore either. Hopefully HIR inlining will be gone completely one day but if until then we start needing to be able to map inlined NodeIds to original DefIds, we can add an additional table to metadata that allows for reconstructing this.
Overall this makes for some nice simplifications and removal of special cases.
r? @eddyb
cc @rust-lang/compiler
[9/n] rustc: move type information out of AdtDef and TraitDef.
_This is part of a series ([prev](https://github.com/rust-lang/rust/pull/37688) | [next]()) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well.
If any motivation is unclear, please ask for additional PR description clarifications or code comments._
<hr>
Both `AdtDef` and `TraitDef` contained type information (field types, generics and predicates) which was required to create them, preventing their use before that type information exists, or in the case of field types, *mutation* was required, leading to a variance-magicking implementation of `ivar`s.
This PR takes that information out and the resulting cleaner setup could even eventually end up merged with HIR, because, just like `AssociatedItem` before it, there's no dependency on types anymore.
(With one exception, variant discriminants should probably be moved into their own map later.)
This commit is an implementation of [RFC 1721] which adds a new target feature
to the compiler, `crt-static`, which can be used to select how the C runtime for
a target is linked. Most targets dynamically linke the C runtime by default with
the notable exception of some of the musl targets.
[RFC 1721]: https://github.com/rust-lang/rfcs/blob/master/text/1721-crt-static.md
This commit first adds the new target-feature, `crt-static`. If enabled, then
the `cfg(target_feature = "crt-static")` will be available. Targets like musl
will have this enabled by default. This feature can be controlled through the
standard target-feature interface, `-C target-feature=+crt-static` or
`-C target-feature=-crt-static`.
Next this adds an gated and unstable `#[link(cfg(..))]` feature to enable the
`crt-static` semantics we want with libc. The exact behavior of this attribute
is a little squishy, but it's intended to be a forever-unstable
implementation detail of the liblibc crate.
Specifically the `#[link(cfg(..))]` annotation means that the `#[link]`
directive is only active in a compilation unit if that `cfg` value is satisfied.
For example when compiling an rlib, these directives are just encoded and
ignored for dylibs, and all staticlibs are continued to be put into the rlib as
usual. When placing that rlib into a staticlib, executable, or dylib, however,
the `cfg` is evaluated *as if it were defined in the final artifact* and the
library is decided to be linked or not.
Essentially, what'll happen is:
* On MSVC with `-C target-feature=-crt-static`, the `msvcrt.lib` library will be
linked to.
* On MSVC with `-C target-feature=+crt-static`, the `libcmt.lib` library will be
linked to.
* On musl with `-C target-feature=-crt-static`, the object files in liblibc.rlib
are removed and `-lc` is passed instead.
* On musl with `-C target-feature=+crt-static`, the object files in liblibc.rlib
are used and `-lc` is not passed.
This commit does **not** include an update to the liblibc module to implement
these changes. I plan to do that just after the 1.14.0 beta release is cut to
ensure we get ample time to test this feature.
cc #37406
[2/n] rustc_metadata: move is_extern_item to trans.
*This is part of a series ([prev](https://github.com/rust-lang/rust/pull/37400) | [next](https://github.com/rust-lang/rust/pull/37402)) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well.
If any motivation is unclear, please ask for additional PR description clarifications or code comments.*
<hr>
Minor cleanup missed by #36551: `is_extern_item` is one of, if not the only `CrateStore` method who takes a `TyCtxt` but doesn't produce something cached in it, and such methods are going away.