Conversation
This comment has been minimized.
This comment has been minimized.
|
Why on earth is |
|
I just tried PR on an aarch64-unknown-linux-gnu box that I have and it compiled fine. Weird. |
This comment has been minimized.
This comment has been minimized.
`def_id.to_stable_hash_key(hcx)` calls `hcx.def_path_hash(def_id)`. This commit replaces various other occurrences of the latter form with the former form. It's all inlined so there should be no perf effects. This will make things easier for the next commit, which will change `DefId::to_stable_hash_key`.
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.
`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.
Overall this is a big simplification, removing a lots of confusing
complexity in stable hashing traits.
It's now just a synonym for `derive(HashStable)`.
Thanks to the `HashStable` trait being simplified, `HashStable_NoContext` is only needed when a (near) perfect derive is required. In practice, this means it's only needed for types with a generic `<I: Interner>` parameter. This commit replaces `derive(HashStable_NoContext)` with `derive(HashStable)` for all types that don't have `<I: Interner>`.
`rustc_middle::ich` is now just a very thin wrapper around `rustc_middle::ich::hcx`, so the contents of the latter can be moved into the former.
XXX: It's causing problems on aarch64-gnu-llvm-21-1 on CI.
3bc77fb to
9e9a113
Compare
| /// visible. | ||
| pub trait HashStableContext { | ||
| /// The main event: stable hashing of a span. | ||
| fn span_hash_stable(&mut self, span: RawSpan, hasher: &mut StableHasher); |
There was a problem hiding this comment.
| fn span_hash_stable(&mut self, span: RawSpan, hasher: &mut StableHasher); | |
| fn span_hash_stable(&mut self, span: Self::Span, hasher: &mut StableHasher); |
Perhaps Span, DefId and RawDefPathHash could be associated types in HashStableContext?
Then impl HashStableContext for StableHashingContext could fill them with concrete types.
If that works then "type erased" versions of the aforementioned types could be avoided.
There was a problem hiding this comment.
I tried that but I couldn't get it to work.
There was a problem hiding this comment.
Specifically, if I add an associate type MySpan to the trait, then in Span::hash_stable I get this error:
error[E0308]: mismatched types
--> compiler/rustc_span/src/lib.rs:2793:30
|
2793 | hcx.span_hash_stable(*self, hasher)
| ---------------- ^^^^^ expected associated type, found `Span`
| |
| arguments to this method are incorrect
|
= note: expected associated type `<Hcx as HashStableContext>::MySpan`
found struct `span_encoding::Span`
help: consider constraining the associated type `<Hcx as HashStableContext>::MySpan` to `span_encoding::Span`
|
2791 | fn hash_stable<Hcx: HashStableContext<MySpan = span_encoding::Span>>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
| ++++++++++++++++++++++++++++++
Then if I try the help suggestion I get this error:
error[E0271]: type mismatch resolving `<Hcx as HashStableContext>::MySpan == Span`
--> compiler/rustc_span/src/lib.rs:2791:43
|
2791 | ...ashStableContext<MySpan = Span>>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
| ^^^^^^^^^^^^^ expected `Span`, found associated type
|
= note: expected struct `span_encoding::Span`
found associated type `<Hcx as HashStableContext>::MySpan`
note: the requirement `<Hcx as HashStableContext>::MySpan == span_encoding::Span` appears on the `impl`'s method `hash_stable` but not on the corresponding trait's method
--> compiler/rustc_data_structures/src/stable_hasher.rs:82:8
In other words, the impl method no longer matches the trait method.
Maybe there's a way around this? I couldn't find one.
There was a problem hiding this comment.
You can probably make it work with appropriate bounds on the associated types for the impl, but that's going to be crate dependent so still doesn't play nicely with the proc macro. I think you'd need to keep the generic on the trait too.
|
☔ The latest upstream changes (presumably #154368) made this pull request unmergeable. Please resolve the merge conflicts. |
|
This is blocked by #154924. |
|
@bors try @rust-timer queue |
|
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
|
🔒 Merge conflict A merge attempt failed due to a merge conflict. Please rebase on top of the latest base How do I rebase?Assuming
You may also read Please avoid the "Resolve conflicts" button on GitHub. Sometimes step 4 will complete without asking for resolution. This is usually due to difference between how |
This PR:
HashStabletrait, by moving its generic parameter from the trait to its single method.derive(HashStable)/derive(HashStable_Generic)distinction.derive(HashStable)/derive(HashStable_NoContext)distinction.