---
title: Type library plans
---
# Type library plans
## 2021-03-30
### Current status
* Have [`rustc_type_ir`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/index.html) crate
* `rustc_type_ir` contains "leaf types" like `FloatTy` etc
* contains `Debug` and `HashStable` implementations for those types
### Pending PR [#83142]
* Adds `Interner` trait
* Adds impl of `Interner` for `TyCtxt<'tcx>`
[#83142]: https://github.com/rust-lang/rust/pull/83142
### After this PR
### Eventual destination
```mermaid
graph TD;
rustc_type_ir --> rustc_middle
rustc_serialize --> rustc_type_ir
rustc_serialize --> rustc_middle
rustc_data_structures --> rustc_type_ir
rustc_data_structures --> rustc_middle
```
```rust=
// crate rustc_serialize
trait Enocder {}
trait Decoder {}
trait Encodable<E: Encoder> {}
trait Decodable<D: Decoder> {}
// crate rustc_data_structures
trait HashStable<CTX> { }
// crate rustc_serialize
// crate rustc_type_ir
trait Interner {
type SpanData;
type Span;
type InternedTy: Intern<Self, TyS<Self>>;
}
trait Intern<I, S> {
fn intern(interner: &I, source: S) -> Self;
}
struct Ty<I: Interned> {
interned: I::InternedTy
}
struct TyS<I: Interner> {
...
}
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Copy)]
pub enum BoundRegionKind<I: Interner> {
BrAnon(u32),
BrNamed(I::DefId, I::Symbol),
BrEnv,
}
// crate rustc_middle
trait TyEncoder<'tcx>: rustc_serialize::Encoder {}
trait TyDecoder<'tcx>: rustc_serialize::Decoder {}
impl<'tcx> rustc_type_ir::Interner for TyCtxt<'tcx> {
type DefId = DefId;
type Symbol = Symbol;
}
// Implication: all the impls will have to use `StableHashingContext` if they might reach `BoundRegionKind`
impl<CTX> rustc_data_structures::HashStable<StableHashingContext> for rustc_type_ir::BoundRegionKind<TyCtxt<'tcx>> {
...
}
impl<'tcx, CTX, E> Encodable<E> for rustc_type_ir::BoundRegionKind<TyCtxt<'tcx>>
where
E: TyEncoder<'tcx>
{
..
}
```
Alternative
```rust=
...
// crate rustc_type_ir
trait TyEncoder<I: Interner>: rustc_serialize::Encoder {}
trait TyDecoder<I: Interner>: rustc_serialize::Decoder {}
impl<'tcx, CTX, E> TyEncoder<I> for rustc_type_ir::TyKind<I>
where
E: TyEncoder<'tcx>
{
..
}
```
## 2021-04-01
### Should `rustc_type_ir` depends on `rustc_data_structures`?
Probably yes, so we can use the newtype index declarations and the like.
### Why should impl of `HashStable` for `BoundRegionKind` live in `rustc_middle`?
It's only important to rustc.
### But it *could* live in `rustc_type_ir`?
Yes, possibly behind a feature gate. It would mean that `rustc_type_ir` would depend on `rustc_data_structures`, but that's ok, and we may do that anyway.
### Why should impl of `Encodable` for `BoundRegionKind` live in `rustc_middle`?
Again, only important to rustc
### But it *could* live in `rustc_type_ir`?
It could. We'd need the impls to look something like this:
```rust=
impl<E, I> Encodable<E> for BoundRegionKind<I>
where
E: TyEncoder<I>,
I: Interner,
I::DefId: Encodable<E>
```
Also `TyEncoder` would have to move to `rustc_type_ir` and be made generic over `I: Interner`:
```rust=
pub trait TyEncoder<I: Interner>: Encoder {
const CLEAR_CROSS_CRATE: bool;
fn position(&self) -> usize;
fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<I>, usize>;
fn predicate_shorthands(
&mut self
) -> &mut FxHashMap<PredicateKind<I>, usize>;
fn encode_alloc_id(&mut self, alloc_id: &AllocId) -> Result<(), Self::Error>;
}
```