Several printing functions (e.g. `short_string`) take a liftable
parameter. This commit changes the call sites to do the lifting instead.
This simplifies the type signatures and puts the `lift` calls inside
`tls::with` calls which is where they usually appear, and the minor cost
of having more `lift` call sites.
Remove unused spans from AttributeKind
Recently I noticed some spans in diagnostic attributes were never used. I went through and checked the other variants too.
Add a `Local::arg(i)` helper constructor
While reading through stuff I was noticing just how many `+1` fixes there were in various places (and comments explaining those fixups), so this adds a new inherent helper on `Local` for making an argument to help make this clearer.
r? mir
Clean up some traits
I was looking at various traits and found some unnecessary trait bounds, and some unnecessary traits. Details in individual commits.
r? @Nadrieril
Specifically:
- `HashStable` -> `StableHash` (trait)
- `HashStable` -> `StableHash` (derive)
- `HashStable_NoContext` -> `StableHash_NoContext` (derive)
Note: there are some names in `compiler/rustc_macros/src/hash_stable.rs`
that are still to be renamed, e.g. `HashStableMode`.
Part of MCP 983.
linker-messages is warn-by-default again
cc rust-lang/rust#136096
I ended up keeping it a lint and adding an option for lints to ignore `-Dwarnings` (there was already a lint that did that actually, it was just hard-coded in rustc_middle instead of in rustc_lint_defs like I'd expect). This allows people to actually see the warnings without them failing the build in CI.
While reading through stuff I was noticing just how many `+1` fixes there were in various places (and comments explaining that fixup), so this adds a new inherent helper on `Local` for making an argument to help make this clearer.
Move `feature*` methods from `parse` mod to `errors` mod.
As the FIXME comment says, these no longer use `ParseSess` and so the `parse` mod is not a good place for them. The `errors` mod is a better home.
r? @TaKO8Ki
RFC 430 says type parameters should be named "concise UpperCamelCase,
usually single uppercase letter". So either `Key` or `K` is more
appropriate than `KEY`, which looks like a constant.
I chose `K` because it's a well-known abbreviation of "key" used in lots
of places, e.g. `HashMap<K, V>`.
Simplify `HashStable`
This PR:
- Simplifies the `HashStable` trait, by moving its generic parameter from the trait to its single method.
- Eliminates the need for the non-obvious `derive(HashStable)`/`derive(HashStable_Generic)` distinction.
- Reduces the need for, and clarifies, the non-obvious `derive(HashStable)`/`derive(HashStable_NoContext)` distinction.
r? @fee1-dead
Every lifting root calls `unwrap`/`expect` on the result, except for
`ImmTy::fmt` but there's no good reason for that exception. Making
lifting infallible is sensible because it should only fail if the wrong
interner is somehow used, which indicates a major bug in rustc rather
than an error condition.
Various places where `lift` just isn't necessary. Either because we're
not within a closure passed to `tls::with`, or because the type being lifted
doesn't have a `'tcx` lifetime.
`std::hash::Hash` looks like this:
```
pub trait Hash {
fn hash<H>(&self, state: &mut H)
where H: Hasher;
...
}
```
The method is generic.
In contrast, `HashStable` looks like this:
```
pub trait HashStable<Hcx> {
fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher);
}
```
and impls look like this (in crates upstream of `rustc_middle`):
```
impl<Hcx: HashStableContext> HashStable<Hcx> for Path {
fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
...
}
}
```
or this (in `rustc_middle` and crates downstream of `rustc_middle`):
```
impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
...
}
}
```
Differences to `std::hash::Hash`:
- The trait is generic, rather than the method.
- The way impls are written depends their position in the crate graph.
- This explains why we have both `derive(HashStable)` and
`derive(HashStable_Generic)`. The former is for the
downstream-of-`rustc_middle` case, the latter is for the upstream of
`rustc_middle` case.
Why the differences? It all boils down to `HashStable` and
`HashStableContext` being in different crates. But the previous commit
fixed that, which means `HashStable` can be simplified to this, with a
generic method:
```
pub trait HashStable {
fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher);
}
```
and all impls look like this:
```
impl HashStable for Path {
fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
...
}
}
```
Other consequences:
- `derive(HashStable_Generic)` is no longer needed; `derive(HashStable)`
can be used instead.
- In this commit, `derive(HashStable_Generic` is made a synonym of
`derive(HashStable)`. The next commit will remove this synonym,
because it's a change that touches many lines.
- `#[stable_hash_generic]` is no longer needed (for `newtype_index`);
`#[stable_hash]` can be used instead.
- `#[stable_hash_no_context]` was already a synonym of
`#[stable_hash_generic]`, so it's also removed in favour of just
`#[stable_hash]`.
- The difference between `derive(HashStable)` and
`derive(HashStable_NoContext)` now comes down to the difference
between `synstructure::AddBounds::Generics` and
`synstructure::AddBounds::Fields`, which is basically "vanilla derive"
vs "(near) perfect derive".
- I have improved the comments on `HashStableMode` to better
explaining this subtle difference.
- `rustc_middle/src/ich/impls_syntax.rs` is no longer needed; the
relevant impls can be defined in the crate that defines the relevant
type.
- Occurrences of `for<'a> HashStable<StableHashingContext<'a>>` are
replaced with with `HashStable`, hooray.
- The commit adds a `HashStableContext::hashing_controls` method, which
is no big deal. (It's necessary for `AdtDefData::hash_stable`, which
calls `hashing_controls` and used to have an `hcx` that was a
concrete `StableHashingContext` but now has an `hcx` that is just
`Hcx: HashStableContext`.)
Overall this is a big simplification, removing a lot of confusing
complexity in stable hashing traits.
This puts it in the same crate as the `HashStable` and `ToStableHasher`
traits. This requires introducing three types `RawSpan`, `RawDefId` and
`RawDefPathHash` to work around the fact that `rustc_data_structures`
is upstream of `rustc_span` and so doesn't have access to `Span`,
`DefId`, and `DefPathHash`. This is a bit ugly but is worth it because
moving `HashStableContext` enables big cleanups across many crates in
subsequent commits.
privacy: share effective visibility initialization
Address one `FIXME` in `EffectiveVisibilities` by sharing the private effective visibility initialization path between `effective_vis_or_private` and `update`.
`update` now mutates the map entry in place instead of copying the effective visibility out and inserting it back at the end. The inserted default value and update logic are unchanged.
Validation:
- `git diff --check`
- `python x.py check compiler/rustc_middle`
Remove `WithCachedTypeInfo::stable_hash`.
We store a stable hash value in the most common interned values (e.g. types, predicates, regions). This is 16 bytes of data.
- In non-incremental builds it's a straightforward performance loss: the stable hash isn't computed or used, and the 16 bytes of space goes to waste (but it still gets hashed when interning).
- In incremental builds it avoids some hashing but doesn't seem to actually be a genuine performance win, and the complexity doesn't seem worth it.
r? @oli-obk
Change `ItemKind::Trait` to a field variant.
This changes `ItemKind::Trait` from an octuple(!!) to an enum variant with fields. Their names were chosen to match up with existing usage and minimize renaming.
I'm leaning towards renaming `ident` to `name` as well; let me know if that's desired.
Check closure's constness validity in the constness query
fixesrust-lang/rust#155584
instead of checking during ast lowering, where it's not easily possible to obtain all the right information in time. While lowering an assoc item we don't know if the parent was a const trait or a const impl. Tracing this information is quite annoying, and complicates a lot of code, which checking here after the fact is trivial.
Avoid Vec allocation in TyCtxt::mk_place_elem
`mk_place_elem` appends a single `PlaceElem` to an existing (interned) projection. The current implementation copies the projection into a fresh `Vec`, pushes the new element, and re-interns the slice, which allocates on every call.
Feed the elements through `mk_place_elems_from_iter` so that `CollectAndApply`'s hand-unrolled stack fast path (up to 9 elements, in `rustc_type_ir::interner`) kicks in for the common case of short projections and the `Vec` allocation is skipped entirely. The behavior is identical for longer projections (the fast path falls back to a `Vec` internally).