Combine types and regions in Substs into one interleaved list.#36002
Combine types and regions in Substs into one interleaved list.#36002bors merged 3 commits intorust-lang:masterfrom
Conversation
src/librustc/ty/subst.rs
Outdated
There was a problem hiding this comment.
Does this really need to be a regular assertion? A debug assertion might be more appropriate (do the nightlies have debug assertions enabled?).
There was a problem hiding this comment.
If it's not optimized out, then something's wrong. This would be a static_assert if we had those.
There was a problem hiding this comment.
Good point, didn't think of that.
|
OK. This is pretty slick. Here is one last random thought: It might be nice to have an enum But otherwise -- yeah, this is great. r=me modulo nits and suggestions. |
|
@nikomatsakis I seriously considered that and realized it wouldn't help much, maybe even cause deoptimizations due to "re-tagging" (I saw some examples in Servo where LLVM didn't see the connection). |
|
@eddyb I was not expecting it to yield more efficient code, just more correct code. IOW, it'd be harder to miss a case -- but I think that all or most the places I saw where we were doing exhaustive checks are places that you are very unlikely to miss anyway (that is, you will for sure hit e.g. encoding/substitution when writing test cases) |
|
@eddyb so tl;dr feel free to leave it as is. |
d03b762 to
7a8d482
Compare
|
@bors r=nikomatsakis |
|
📌 Commit 7a8d482 has been approved by |
…akis
Combine types and regions in Substs into one interleaved list.
Previously, `Substs` would contain types and regions, in two separate vectors, for example:
```rust
<X as Trait<'a, 'b, A, B>>::method::<'p, 'q, T, U>
/* corresponds to */
Substs { regions: ['a, 'b, 'p, 'q], types: [X, A, B, T, U] }
```
This PR continues the work started in rust-lang#35605 by further removing the distinction.
A new abstraction over types and regions is introduced in the compiler, `Kind`.
Each `Kind` is a pointer (`&TyS` or `&Region`), with the lowest two bits used as a tag.
Two bits were used instead of just one (type = `0`, region = `1`) to allow adding more kinds.
`Substs` contain only a `Vec<Kind>`, with `Self` first, followed by regions and types (in the definition order):
```rust
Substs { params: [X, 'a, 'b, A, B, 'p, 'q, T, U] }
```
The resulting interleaved list has the property of being the concatenation of parameters for the (potentially) nested generic items it describes, and can be sliced back into those components:
```rust
params[0..5] = [X, 'a, 'b, A, B] // <X as Trait<'a, 'b, A, B>>
params[5..9] = ['p, 'q, T, U] // <_>::method::<'p, 'q, T, U>
```
r? @nikomatsakis
Previously,
Substswould contain types and regions, in two separate vectors, for example:This PR continues the work started in #35605 by further removing the distinction.
A new abstraction over types and regions is introduced in the compiler,
Kind.Each
Kindis a pointer (&TySor&Region), with the lowest two bits used as a tag.Two bits were used instead of just one (type =
0, region =1) to allow adding more kinds.Substscontain only aVec<Kind>, withSelffirst, followed by regions and types (in the definition order):The resulting interleaved list has the property of being the concatenation of parameters for the (potentially) nested generic items it describes, and can be sliced back into those components:
r? @nikomatsakis