Repository: rust
Issue: Rust cannot resolve trait bound for associated type
Labels: A-lifetimes,A-trait-system,A-associated-items,T-compiler,C-bug,T-types

I am trying to implement the Family design pattern as per [this post by Luka](http://lukaskalbertodt.github.io/2018/08/03/solving-the-generalized-streaming-iterator-problem-without-gats.html) and [this one by Niko](http://smallcultfollowing.com/babysteps/blog/2016/11/03/associated-type-constructors-part-2-family-traits/#introducing-type-families).

My goal is to abstract db transactions thanks to a `Db` trait that exposes read and write transaction. The `Db` trait have 2 associated types, `Writer` and `Reader` that define the operations that can be done on them. Ultimately, by being generic over the `Reader` and `Writer` types, I hope to be able to mock the actual db operations.



I tried this code:

This is what I have come up with: 
<details><summary>Code</summary>
<p>

```rust
use std::marker::PhantomData;
use std::error::Error;

/// The `Db` trait represent an interaction with a transactional database.
pub trait Db {
    /// A writer representing the writable operation that can be operated on a database
    type Writer: for<'a> TxnFamily<'a>;
    /// A reader representing the readable operation that can be operated on a database
    type Reader: for<'a> TxnFamily<'a>;

    /// Provide the user with a writer representing a transaction. This function should commit if
    /// txn return Ok(_), an abort otherwise.
    fn write<'a, F, T, E>(&'a self, txn: F) -> anyhow::Result<Result<T, E>>
        where F: FnOnce(&mut <Self::Writer as TxnFamily<'a>>::Out) -> Result<T, E>,
              E: Error;

    /// Provide a reader representing a transaction.
    fn read<'a, F, T, E>(&'a self, txn: F) -> anyhow::Result<Result<T, E>>
        where F: FnOnce(&<Self::Reader as TxnFamily<'a>>::Out) -> Result<T, E>,
              E: Error;
}

pub trait TxnFamily<'a> { type Out; }

pub trait KvStoreDbWriter {
    fn put_key(&self, key: String, value: u64) -> anyhow::Result<()>;
}

impl<'a> KvStoreDbWriter for MapKvStoreDbWriter<'a> {
    fn put_key(&self, key: String, value: u64) -> anyhow::Result<()> {
        todo!()
    }
}

impl<'a> KvStoreDbReader for MapKvStoreDbReader<'a> {
    fn get_key(&self, key: &str) -> anyhow::Result<Option<u64>> {
        todo!()
    }
}

pub trait KvStoreDbReader {
    fn get_key(&self, key: &str) -> anyhow::Result<Option<u64>>;
}

// it doesn't matter wha this do either, but it is parametric
// over a lifetime for the length of the transaction.
pub struct MapKvStoreDbReader<'a>(PhantomData<&'a ()>);
pub struct MapKvStoreDbWriter<'a>(PhantomData<&'a ()>);


// What the MapKvStore actually do is irelevant,
// we want to be able to mock it a some point.
pub struct MapKvStoreDb;

pub struct MapKvStoreDbWriterTxn;
impl<'a> TxnFamily<'a> for MapKvStoreDbWriterTxn {
    type Out = MapKvStoreDbWriter<'a>;
}

pub struct MapKvStoreDbReaderTxn;
impl<'a> TxnFamily<'a> for MapKvStoreDbReaderTxn {
    type Out = MapKvStoreDbReader<'a>;
}

impl Db for MapKvStoreDb {
    type Writer = MapKvStoreDbWriterTxn;
    type Reader = MapKvStoreDbReaderTxn;
    fn write<'a, F, T, E>(&'a self, _txn: F) -> anyhow::Result<Result<T, E>>
        where F: FnOnce(&mut MapKvStoreDbWriter<'a>) -> Result<T, E>,
              E: Error {
                  todo!()
              }

    fn read<'a, F, T, E>(&'a self, _txn: F) -> anyhow::Result<Result<T, E>>
        where F: FnOnce(&MapKvStoreDbReader<'a>) -> Result<T, E>,
              E: Error {
                  todo!()
              }
}

struct KvStore<M> {
    store: M
}

impl<M> KvStore<M>
where
    M: Db,
    for<'a> <M::Reader as TxnFamily<'a>>::Out: KvStoreDbReader,
    for<'a> <M::Writer as TxnFamily<'a>>::Out: KvStoreDbWriter,
    
{
   fn new(store: M) -> Self {
       Self { store }
   } 
}

fn main() { 
    let store = MapKvStoreDb;
    let kv_store = KvStore::new(store);
}
```
</p>
</details>

and there on the playground https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=01bba28ff362a5f59da198b38a127d0e

I expect it to compile without error, since `MapKvStoreDb` implements `Db<Writer = MapKvStoreDbWriterTxn, Reader = MapKvStoreDbReaderTxn>`, and `MapKvStoreDbReaderTxn` implement `TxnFamily` whose `Out` implements `KvStoreDbReader`, and same for ` MapKvStoreDbWriterTxn`.

Instead, I get this error:
```
   Compiling playground v0.0.1 (/playground)
error[E0599]: no function or associated item named `new` found for struct `KvStore<_>` in the current scope
  --> src/main.rs:99:29
   |
81 | struct KvStore<M> {
   | ----------------- function or associated item `new` not found for this
...
99 |     let kv_store = KvStore::new(store);
   |                             ^^^ function or associated item not found in `KvStore<_>`
   |
   = note: the method `new` exists but the following trait bounds were not satisfied:
           `<_ as TxnFamily<'a>>::Out: KvStoreDbReader`
           `<_ as TxnFamily<'a>>::Out: KvStoreDbWriter`
```