# Mismatched types error on associated type and trait objects

**URL:** <https://users.rust-lang.org/t/mismatched-types-error-on-associated-type-and-trait-objects/111393>\
**Category:** help\
**Created:** [May 14, 2024, 3:07pm UTC](https://users.rust-lang.org/t/mismatched-types-error-on-associated-type-and-trait-objects/111393 "2024-05-14T15:07:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![cococat](https://avatars.discourse-cdn.com/v4/letter/c/b782af/32.png) [@cococat](https://users.rust-lang.org/u/cococat)\
**Post date:** [May 14, 2024, 3:07pm UTC](https://users.rust-lang.org/t/mismatched-types-error-on-associated-type-and-trait-objects/111393/1 "2024-05-14T15:07:42Z")

</div>

I was trying to make a brief demo of a HTTP/HTTPS server, and came into a strange compiler error. I will show a simplified version of my code below to illustrate the problem.  
First I'd like to create a `Listener` trait, which will be implemented by stuff like `TcpListener` or `UdpListener`. The trait is simple:

```rust
trait Listener {
    type Conn;
    fn accept(&self) -> Self::Conn;
}

```

Next I want to make a `TlsListener` . Considering a TLS connection should be based on an established TCP connection, it should contain an underlying `Listener`, like:

```rust
struct TlsListener<Ln>
where
    Ln: Listener,
{
    ln: Ln,
}

```

Now I need to implement `Listener` trait for it, and that's when error occurs. I will replace the actual `accept` logic with some test code, and the lines commented with "not ok" will lead to an error:

```rust
fn test(_t: Pin<Box<dyn Unpin + 'static>>) {}
fn test_ref(_t: &Pin<Box<dyn Unpin + 'static>>) {}

impl<Ln> Listener for TlsListener<Ln>
where
    Ln: Listener,
    Ln::Conn: Unpin + 'static,
{
    type Conn = ();
    fn accept(&self) {
        // ok
        let conn = self.ln.accept();
        test(Box::pin(conn));

        // not ok
        let conn1 = self.ln.accept();
        test_ref(&Box::pin(conn1));
        
        // ok
        let conn2 = self.ln.accept();
        let boxed_conn2 = Box::new(conn2);
        test_ref(&Pin::new(boxed_conn2));
    }
}

```

The error log is:

```rust
error[E0308]: mismatched types
   --> src/main.rs:94:18
    |
94 | test_ref(&Box::pin(conn1));
    | -------- ^^^^^^^^^^^^^^^^ expected `&Pin<Box<dyn Unpin>>`, found `&Pin<Box<<Ln as Listener>::Conn>>`
    | |
    | arguments to this function are incorrect
    |
    = note: expected reference `&Pin<Box<(dyn Unpin + 'static)>>`
               found reference `&Pin<Box<<Ln as Listener>::Conn>>`
note: function defined here
   --> src/main.rs:108:4
    |
108 | fn test_ref(_: &Pin<Box<dyn Unpin + 'static>>) {}
    | ^^^^^^^^ ----------------------------------
help: consider constraining the associated type `<Ln as Listener>::Conn` to `(dyn Unpin + 'static)`
    |
77 | Ln: Listener<Conn = (dyn Unpin + 'static)>,
    | ++++++++++++++++++++++++++++++

For more information about this error, try `rustc --explain E0308`.

```

I wonder why it won't work after adding a reference, and why it becomes available again once I've seperated the `Box` and `Pin` operations.

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/quinedot/32/17693_2.png) [@quinedot](https://users.rust-lang.org/u/quinedot)\
**Post date:** [May 14, 2024, 6:07pm UTC](https://users.rust-lang.org/t/mismatched-types-error-on-associated-type-and-trait-objects/111393/2 "2024-05-14T18:07:12Z")

</div>

> [@cococat](#):
>
> I wonder why it won't work after adding a reference, and why it becomes available again once I've seperated the `Box` and `Pin` operations.

Some bad order of inference is going on. You can't coerce a `&Box<T>` or a `&Pin<Box<T>>` to a `&Box<dyn Trait>` or `&Pin<Box<dyn trait>>` because of [too much indirection.](https://quinedot.github.io/rust-learning/dyn-trait-coercions.html#no-nested-coercions) So the compiler decided you had created a `&Pin<Box<AssocType>>` before it tried to coerce it.

[See also this issue.](https://github.com/rust-lang/rust/issues/89299)

This change clues the compiler in that a coercion needs to happen before taking the reference.

```rust
        test_ref(&{ Box::pin(conn1) as _});

```

> **[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c717d23899fcd191e2f64e6fcc1107a3)**
>
> A browser interface to the Rust compiler to experiment with the language

Or just...

```rust
        test_ref(&Pin::new(Box::new(conn1)));

```

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [August 12, 2024, 6:07pm UTC](https://users.rust-lang.org/t/mismatched-types-error-on-associated-type-and-trait-objects/111393/3 "2024-08-12T18:07:39Z")

</div>

Closed on August 12, 2024, 6:07pm UTC

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
