annotate stricter lifetimes on LateLintPass methods to allow them to forward to a Visitor
this unblocks clippy (rustup blocked after #37918)
clippy has lots of lints that internally call an `intravisit::Visitor`, but the current lifetimes on `LateLintPass` methods conflicted with the required lifetimes (there was no connection between the HIR elements and the `TyCtxt`)
r? @Manishearth
Adds `-Z mir-stats`, which is similar to `-Z hir-stats`.
Adds `-Z mir-stats`, which is similar to `-Z hir-stats`.
Some notes:
* This code attempts to present the breakdown of each variant for
every enum in the MIR. This is meant to guide decisions about how to
revise representations e.g. when to box payloads for rare variants
to shrink the size of the enum overall.
* I left out the "Total:" line that hir-stats presents, because this
implementation uses the MIR Visitor infrastructure, and the memory
usage of structures directly embedded in other structures (e.g. the
`func: Operand` in a `TerminatorKind:Call`) is not distinguished
from similar structures allocated in a `Vec` (e.g. the `args:
Vec<Operand>` in a `TerminatorKind::Call`). This means that a naive
summation of all the accumulated sizes is misleading, because it
will double-count the contribution of the `Operand` of the `func` as
well as the size of the whole `TerminatorKind`.
* I did consider abandoning the MIR Visitor and instead hand-coding
a traversal that distinguished embedded storage from indirect
storage. But such code would be fragile; better to just require
people to take care when interpreting the presented results.
* This traverses the `mir.promoted` rvalues to capture stats for MIR
stored there, even though the MIR visitor super_mir method does not
do so. (I did not observe any promoted mir being newly traversed when
compiling the rustc crate, however.)
* It might be nice to try to unify this code with hir-stats. Then
again, the reporting portion is the only common code (I think), and
it is small compared to the visitors in hir-stats and mir-stats.
in region, treat current (and future) item-likes alike
The `visit_fn` code mutates its surrounding context. Between *items*,
this was saved/restored, but between impl items it was not. This meant
that we wound up with `CallSiteScope` entries with two parents (or
more!). As far as I can tell, this is harmless in actual type-checking,
since the regions you interact with are always from at most one of those
branches. But it can slow things down.
Before, the effect was limited, since it only applied to impl items
within an impl. After #37660, impl items are visisted all together at
the end, and hence this could create a very messed up
hierarchy. Isolating impl item properly solves both issues.
I cannot come up with a way to unit-test this; for posterity, however,
you can observe the messed up hierarchies with a test as simple as the
following, which would create a callsite scope with two parents both
before and after
```
struct Foo {
}
impl Foo {
fn bar(&self) -> usize {
22
}
fn baz(&self) -> usize {
22
}
}
fn main() { }
```
Fixes#37864.
r? @michaelwoerister
cc @pnkfelix -- can you think of a way to make a regr test?
add a `-Z incremental-dump-hash` flag
This causes us to dump a bunch of has information to stdout that can be
useful in tracking down incremental compilation invalidations,
particularly across crates.
print option to dump target spec as JSON
This lets the user dump out the target spec that the compiler is using. This is useful to people defining their own target.json to compare it against existing targets or understand how different targets change internal settings. It is also potentially useful for Cargo to determine if something has changed with a target and it needs to rebuild things.
evaluate obligations in LIFO order during closure projection
This is an annoying gotcha with the projection cache's handling of
nested obligations.
Nested projection obligations enter the issue in this case:
```
DEBUG:rustc::traits::project: AssociatedTypeNormalizer: depth=3
normalized
<std::iter::Map<std::ops::Range<i32>,
[closure@not-a-recursion-error.rs:5:30: 5:53]> as
std::iter::IntoIterator>::Item to _#7t with 12 add'l obligations
```
Here the normalization result is the result of the nested impl
`<[closure@not-a-recursion-error.rs:5:30: 5:53] as FnMut(i32)>::Output`,
which is an additional obligation that is a part of "add'l obligations".
By itself, this is proper behaviour - the additional obligation is
returned, and the RFC 447 rules ensure that it is processed before the
output `#_7t` is used in any way.
However, the projection cache breaks this - it caches the
`<std::iter::Map<std::ops::Range<i32>,[closure@not-a-recursion-error.rs:5:30:
5:53]> as std::iter::IntoIterator>::Item = #_7t` resolution. Now
everybody else that attempts to look up the projection will just get
`#_7t` *without* any additional obligations. This obviously causes all
sorts of trouble (here a spurious `EvaluatedToAmbig` results in
specializations not being discarded
[here](9ca50bd4d5/src/librustc/traits/select.rs (L1705))).
The compiler works even with this projection cache gotcha because in most
cases during "one-pass evaluation". we tend to process obligations in LIFO
order - after an obligation is added to the cache, we process its nested
obligations before we do anything else (and if we have a cycle, we handle
it specifically) - which makes sure the inference variables are resolved
before they are used.
That "LIFO" order That was not done when projecting out of a closure, so
let's just fix that for the time being.
Fixes#38033.
Beta-nominating because regression.
r? @nikomatsakis
This option provides the user the ability to dump the configuration that
is in use by rustc for the target they are building for.
Signed-off-by: Doug Goldstein <cardoe@cardoe.com>
[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.)
The `visit_fn` code mutates its surrounding context. Between *items*,
this was saved/restored, but between impl items it was not. This meant
that we wound up with `CallSiteScope` entries with two parents (or
more!). As far as I can tell, this is harmless in actual type-checking,
since the regions you interact with are always from at most one of those
branches. But it can slow things down.
Before, the effect was limited, since it only applied to impl items
within an impl. After #37660, impl items are visisted all together at
the end, and hence this could create a very messed up
hierarchy. Isolating impl item properly solves both issues.
I cannot come up with a way to unit-test this; for posterity, however,
you can observe the messed up hierarchies with a test as simple as the
following, which would create a callsite scope with two parents both
before and after
```
struct Foo {
}
impl Foo {
fn bar(&self) -> usize {
22
}
fn baz(&self) -> usize {
22
}
}
fn main() { }
```
Fixes#37864.
This causes us to dump a bunch of has information to stdout that can be
useful in tracking down incremental compilation invalidations,
particularly across crates.
Some notes:
* This code attempts to present the breakdown of each variant for
every enum in the MIR. This is meant to guide decisions about how to
revise representations e.g. when to box payloads for rare variants
to shrink the size of the enum overall.
* I left out the "Total:" line that hir-stats presents, because this
implementation uses the MIR Visitor infrastructure, and the memory
usage of structures directly embedded in other structures (e.g. the
`func: Operand` in a `TerminatorKind:Call`) is not distinguished
from similar structures allocated in a `Vec` (e.g. the `args:
Vec<Operand>` in a `TerminatorKind::Call`). This means that a naive
summation of all the accumulated sizes is misleading, because it
will double-count the contribution of the `Operand` of the `func` as
well as the size of the whole `TerminatorKind`.
* I did consider abandoning the MIR Visitor and instead hand-coding
a traversal that distinguished embedded storage from indirect
storage. But such code would be fragile; better to just require
people to take care when interpreting the presented results.
* This traverses the `mir.promoted` rvalues to capture stats for MIR
stored there, even though the MIR visitor super_mir method does not
do so. (I did not observe any new mir being traversed when compiling
the rustc crate, however.)
* It might be nice to try to unify this code with hir-stats. Then
again, the reporting portion is the only common code (I think), and
it is small compared to the visitors in hir-stats and mir-stats.
rustdoc: link to cross-crate sources directly.
Fixes#37684 by implementing proper support for getting the `Span` of definitions across crates.
In rustdoc this is used to generate direct links to the original source instead of fragile redirects.
This functionality could be expanded further for making error reporting code more uniform and seamless across crates, although at the moment there is no actual source to print, only file/line/column information.
Closes#37870 which is also "fixes" #37684 by throwing away the builtin macro docs from libcore.
After this lands, #37727 could be reverted, although it doesn't matter much either way.
Refactor TraitObject to Slice<ExistentialPredicate>
For reference, the primary types changes in this PR are shown below. They may add in the understanding of what is discussed below, though they should not be required.
We change `TraitObject` into a list of `ExistentialPredicate`s to allow for a couple of things:
- Principal (ExistentialPredicate::Trait) is now optional.
- Region bounds are moved out of `TraitObject` into `TyDynamic`. This permits wrapping only the `ExistentialPredicate` list in `Binder`.
- `BuiltinBounds` and `BuiltinBound` are removed entirely from the codebase, to permit future non-constrained auto traits. These are replaced with `ExistentialPredicate::AutoTrait`, which only requires a `DefId`. For the time being, only `Send` and `Sync` are supported; this constraint can be lifted in a future pull request.
- Binder-related logic is extracted from `ExistentialPredicate` into the parent (`Binder<Slice<EP>>`), so `PolyX`s are inside `TraitObject` are replaced with `X`.
The code requires a sorting order for `ExistentialPredicate`s in the interned `Slice`. The sort order is asserted to be correct during interning, but the slices are not sorted at that point.
1. `ExistentialPredicate::Trait` are defined as always equal; **This may be wrong; should we be comparing them and sorting them in some way?**
1. `ExistentialPredicate::Projection`: Compared by `ExistentialProjection::sort_key`.
1. `ExistentialPredicate::AutoTrait`: Compared by `TraitDef.def_path_hash`.
Construction of `ExistentialPredicate`s is conducted through `TyCtxt::mk_existential_predicates`, which interns a passed iterator as a `Slice`. There are no convenience functions to construct from a set of separate iterators; callers must pass an iterator chain. The lack of convenience functions is primarily due to few uses and the relative difficulty in defining a nice API due to optional parts and difficulty in recognizing which argument goes where. It is also true that the current situation isn't significantly better than 4 arguments to a constructor function; but the extra work is deemed unnecessary as of this time.
```rust
// before this PR
struct TraitObject<'tcx> {
pub principal: PolyExistentialTraitRef<'tcx>,
pub region_bound: &'tcx ty::Region,
pub builtin_bounds: BuiltinBounds,
pub projection_bounds: Vec<PolyExistentialProjection<'tcx>>,
}
// after
pub enum ExistentialPredicate<'tcx> {
// e.g. Iterator
Trait(ExistentialTraitRef<'tcx>),
// e.g. Iterator::Item = T
Projection(ExistentialProjection<'tcx>),
// e.g. Send
AutoTrait(DefId),
}
```
They don't implement FnLikeNode anymore, instead are handled differently
further up in the call tree. Also, keep less information (just def ids
for the args).
Setup two tasks, one of which only processes the signatures, in order to
isolate the typeck entries for signatures from those for bodies.
Fixes#36078Fixes#37720