---
# System prepended metadata

title: Type library plans

---

---
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>;
}
```

