Unsatisfied trait bound error despite being implemented

I’m trying to implement a trait WebsocketIO for T but it always says the trait bounds were not satisfied when I’m trying to use it on my AsyncWebsocketClient. AsyncWebsocketClient is supposed to work with tokio-tungstenite.
Here is the libraries Cargo.toml

[package]
name = "websocket"
version = "0.1.0"
edition = "2021"

[dependencies]
embassy-futures = "0.1.1"
embassy-sync = "0.6.0"
futures = "0.3.30"
tokio-tungstenite = { version = "0.23.1", features = ["native-tls"] }

Here is the AsyncWebsocketClient:

pub struct AsyncWebsocketClient<'a, T, Status = WebsocketClosed> {
    inner: Arc<Mutex<&'a mut T>>,
    status: PhantomData<Status>,
}

It implements futures::Stream and futures::Sink:

impl<T> Stream for AsyncWebsocketClient<'_, T, WebsocketOpen>
where 
    T: Stream<Item = Message> + Unpin
{
    type Item = Message;

    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        let mut stream = block_on(self.inner.lock());
        Pin::new(&mut *stream).poll_next(cx)
    }
}

impl<T> Sink<Message> for AsyncWebsocketClient<'_, T, WebsocketOpen>
where 
    T: Sink<Message, Error = tokio_tungstenite::tungstenite::Error> + Unpin
{
    type Error = tokio_tungstenite::tungstenite::Error;

    fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        let mut stream = block_on(self.inner.lock());
        Pin::new(&mut *stream).poll_ready(cx)
    }

    fn start_send(self: Pin<&mut Self>, item: Message) -> Result<(), Self::Error> {
        let mut stream = block_on(self.inner.lock());
        Pin::new(&mut *stream).start_send(item)
    }

    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        let mut stream = block_on(self.inner.lock());
        Pin::new(&mut *stream).poll_flush(cx)
    }

    fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        let mut stream = block_on(self.inner.lock());
        Pin::new(&mut *stream).poll_close(cx)
    }
}

Here is the trait WebsocketIO which I want to implement for T. Similar to futures::SinkExt and futures::StreamExt.

pub trait WebsocketIO {
    async fn t_send(&mut self, message: Message) -> Result<(), tokio_tungstenite::tungstenite::Error>;
    async fn t_receive(&mut self) -> Option<Message>;
}

The implementation for T:

impl<T: ?Sized> WebsocketIO for T
where
    T: Stream<Item = Message> + Sink<Message, Error = tokio_tungstenite::tungstenite::Error> + Unpin
{
    async fn t_send(&mut self, message: Message) -> Result<(), tokio_tungstenite::tungstenite::Error> {
        use futures::SinkExt;
        self.send(message).await
    }

    async fn t_receive(&mut self) -> Option<Message> {
        use futures::StreamExt;
        self.next().await
    }
}

This is a simplified version of the actual AsyncWebsocketClient but is sufficient to reproduce the error. While the implementation works in a #[tokio::test] scope inside my library, the compiler throws an error as soon as I try to use my library in a project as a dependency. This is my example Cargo.toml:

[package]
name = "_std"
version = "0.1.0"
edition = "2021"

[dependencies]
websocket = { path = "../.."} # my library
tokio = { version = "1.38.0", features = ["full"] }
tokio-tungstenite = { version = "0.23.1", features = ["native-tls"] }


[[bin]]
name = "client"

Here is the example code I’m trying to test my AsyncWebsocketClient with:

use tokio_tungstenite::{connect_async, tungstenite::Message};
use websocket::{AsyncWebsocketClient, WebsocketIO};

#[tokio::main]
async fn main() {
    // connect to echo websocket server
    let mut stream = connect_async("wss://ws.postman-echo.com/raw")
        .await
        .expect("Failed to connect")
        .0;
    let mut client = AsyncWebsocketClient::open(&mut stream);
    client.t_send(Message::Text("Hello, world!".to_string())).await.unwrap();
}

Here is the error I’m getting due to unsatisfied trait bounds:

vscode ➜ /workspaces/rust/examples/std (master) $ cargo run --bin client
warning: unused import: `StreamExt`
 --> /workspaces/rust/src/lib.rs:4:62
  |
4 | use futures::{executor::block_on, lock::Mutex, Sink, Stream, StreamExt};
  |                                                              ^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified
  --> /workspaces/rust/src/lib.rs:66:5
   |
66 |     async fn t_send(&mut self, message: Message) -> Result<(), tokio_tungstenite::tungstenite::Error>;
   |     ^^^^^
   |
   = note: you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future`
   = note: `#[warn(async_fn_in_trait)]` on by default
help: you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send`, but these cannot be relaxed without a breaking API change
   |
66 -     async fn t_send(&mut self, message: Message) -> Result<(), tokio_tungstenite::tungstenite::Error>;
66 +     fn t_send(&mut self, message: Message) -> impl std::future::Future<Output = Result<(), tokio_tungstenite::tungstenite::Error>> + Send;
   |

warning: use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified
  --> /workspaces/rust/src/lib.rs:67:5
   |
67 |     async fn t_receive(&mut self) -> Option<Message>;
   |     ^^^^^
   |
   = note: you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future`
help: you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send`, but these cannot be relaxed without a breaking API change
   |
67 -     async fn t_receive(&mut self) -> Option<Message>;
67 +     fn t_receive(&mut self) -> impl std::future::Future<Output = Option<Message>> + Send;
   |

warning: `websocket` (lib) generated 3 warnings
   Compiling _std v0.1.0 (/workspaces/rust/examples/std)
error[E0599]: the method `t_send` exists for struct `AsyncWebsocketClient<'_, WebSocketStream<MaybeTlsStream<TcpStream>>, WebsocketOpen>`, but its trait bounds were not satisfied
  --> src/bin/client.rs:14:12
   |
14 |     client.t_send(Message::Text("Hello, world!".to_string())).await.unwrap();
   |            ^^^^^^
   |
  ::: /workspaces/rust/src/lib.rs:12:1
   |
12 | pub struct AsyncWebsocketClient<'a, T, Status = WebsocketClosed> {
   | ---------------------------------------------------------------- doesn't satisfy `<_ as Stream>::Item = Message`, `_: Stream` or `_: WebsocketIO`
   |
   = note: the following trait bounds were not satisfied:
           `<AsyncWebsocketClient<'_, WebSocketStream<tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>>, WebsocketOpen> as futures_core::stream::Stream>::Item = Message`
           which is required by `AsyncWebsocketClient<'_, WebSocketStream<tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>>, WebsocketOpen>: WebsocketIO`
           `AsyncWebsocketClient<'_, WebSocketStream<tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>>, WebsocketOpen>: futures_core::stream::Stream`
           which is required by `AsyncWebsocketClient<'_, WebSocketStream<tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>>, WebsocketOpen>: WebsocketIO`

warning: unused import: `WebsocketIO`
 --> src/bin/client.rs:4:39
  |
4 | use websocket::{AsyncWebsocketClient, WebsocketIO};
  |                                       ^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

For more information about this error, try `rustc --explain E0599`.
warning: `_std` (bin "client") generated 1 warning
error: could not compile `_std` (bin "client") due to 1 previous error; 1 warning emitted

I can’t explain to myself why the compiler tells me that Stream and Sink are not implemented for AsyncWebsocketClient<‘_, WebSocketStream<tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>>, WebsocketOpen>.

I also checked if it was a version mismatch but I couldn’t find any. Here is my cargo-tree output:

vscode ➜ /workspaces/rust/examples/std (master) $ cargo tree 
_std v0.1.0 (/workspaces/rust/examples/std)
├── tokio v1.38.0
│   ├── bytes v1.6.0
│   ├── libc v0.2.155
│   ├── mio v0.8.11
│   │   └── libc v0.2.155
│   ├── num_cpus v1.16.0
│   │   └── libc v0.2.155
│   ├── parking_lot v0.12.3
│   │   ├── lock_api v0.4.12
│   │   │   └── scopeguard v1.2.0
│   │   │   [build-dependencies]
│   │   │   └── autocfg v1.3.0
│   │   └── parking_lot_core v0.9.10
│   │       ├── cfg-if v1.0.0
│   │       ├── libc v0.2.155
│   │       └── smallvec v1.13.2
│   ├── pin-project-lite v0.2.14
│   ├── signal-hook-registry v1.4.2
│   │   └── libc v0.2.155
│   ├── socket2 v0.5.7
│   │   └── libc v0.2.155
│   └── tokio-macros v2.3.0 (proc-macro)
│       ├── proc-macro2 v1.0.86
│       │   └── unicode-ident v1.0.12
│       ├── quote v1.0.36
│       │   └── proc-macro2 v1.0.86 (*)
│       └── syn v2.0.68
│           ├── proc-macro2 v1.0.86 (*)
│           ├── quote v1.0.36 (*)
│           └── unicode-ident v1.0.12
├── tokio-tungstenite v0.23.1
│   ├── futures-util v0.3.30
│   │   ├── futures-channel v0.3.30
│   │   │   ├── futures-core v0.3.30
│   │   │   └── futures-sink v0.3.30
│   │   ├── futures-core v0.3.30
│   │   ├── futures-io v0.3.30
│   │   ├── futures-macro v0.3.30 (proc-macro)
│   │   │   ├── proc-macro2 v1.0.86 (*)
│   │   │   ├── quote v1.0.36 (*)
│   │   │   └── syn v2.0.68 (*)
│   │   ├── futures-sink v0.3.30
│   │   ├── futures-task v0.3.30
│   │   ├── memchr v2.7.4
│   │   ├── pin-project-lite v0.2.14
│   │   ├── pin-utils v0.1.0
│   │   └── slab v0.4.9
│   │       [build-dependencies]
│   │       └── autocfg v1.3.0
│   ├── log v0.4.21
│   ├── native-tls v0.2.12
│   │   ├── log v0.4.21
│   │   ├── openssl v0.10.64
│   │   │   ├── bitflags v2.6.0
│   │   │   ├── cfg-if v1.0.0
│   │   │   ├── foreign-types v0.3.2
│   │   │   │   └── foreign-types-shared v0.1.1
│   │   │   ├── libc v0.2.155
│   │   │   ├── once_cell v1.19.0
│   │   │   ├── openssl-macros v0.1.1 (proc-macro)
│   │   │   │   ├── proc-macro2 v1.0.86 (*)
│   │   │   │   ├── quote v1.0.36 (*)
│   │   │   │   └── syn v2.0.68 (*)
│   │   │   └── openssl-sys v0.9.102
│   │   │       └── libc v0.2.155
│   │   │       [build-dependencies]
│   │   │       ├── cc v1.0.101
│   │   │       ├── pkg-config v0.3.30
│   │   │       └── vcpkg v0.2.15
│   │   ├── openssl-probe v0.1.5
│   │   └── openssl-sys v0.9.102 (*)
│   ├── tokio v1.38.0 (*)
│   ├── tokio-native-tls v0.3.1
│   │   ├── native-tls v0.2.12 (*)
│   │   └── tokio v1.38.0 (*)
│   └── tungstenite v0.23.0
│       ├── byteorder v1.5.0
│       ├── bytes v1.6.0
│       ├── data-encoding v2.6.0
│       ├── http v1.1.0
│       │   ├── bytes v1.6.0
│       │   ├── fnv v1.0.7
│       │   └── itoa v1.0.11
│       ├── httparse v1.9.4
│       ├── log v0.4.21
│       ├── native-tls v0.2.12 (*)
│       ├── rand v0.8.5
│       │   ├── libc v0.2.155
│       │   ├── rand_chacha v0.3.1
│       │   │   ├── ppv-lite86 v0.2.17
│       │   │   └── rand_core v0.6.4
│       │   │       └── getrandom v0.2.15
│       │   │           ├── cfg-if v1.0.0
│       │   │           └── libc v0.2.155
│       │   └── rand_core v0.6.4 (*)
│       ├── sha1 v0.10.6
│       │   ├── cfg-if v1.0.0
│       │   ├── cpufeatures v0.2.12
│       │   └── digest v0.10.7
│       │       ├── block-buffer v0.10.4
│       │       │   └── generic-array v0.14.7
│       │       │       └── typenum v1.17.0
│       │       │       [build-dependencies]
│       │       │       └── version_check v0.9.4
│       │       └── crypto-common v0.1.6
│       │           ├── generic-array v0.14.7 (*)
│       │           └── typenum v1.17.0
│       ├── thiserror v1.0.61
│       │   └── thiserror-impl v1.0.61 (proc-macro)
│       │       ├── proc-macro2 v1.0.86 (*)
│       │       ├── quote v1.0.36 (*)
│       │       └── syn v2.0.68 (*)
│       └── utf-8 v0.7.6
└── websocket v0.1.0 (/workspaces/rust)
    ├── embassy-futures v0.1.1
    ├── embassy-sync v0.6.0
    │   ├── cfg-if v1.0.0
    │   ├── critical-section v1.1.2
    │   ├── embedded-io-async v0.6.1
    │   │   └── embedded-io v0.6.1
    │   ├── futures-util v0.3.30 (*)
    │   └── heapless v0.8.0
    │       ├── hash32 v0.3.1
    │       │   └── byteorder v1.5.0
    │       └── stable_deref_trait v1.2.0
    ├── futures v0.3.30
    │   ├── futures-channel v0.3.30 (*)
    │   ├── futures-core v0.3.30
    │   ├── futures-executor v0.3.30
    │   │   ├── futures-core v0.3.30
    │   │   ├── futures-task v0.3.30
    │   │   └── futures-util v0.3.30 (*)
    │   ├── futures-io v0.3.30
    │   ├── futures-sink v0.3.30
    │   ├── futures-task v0.3.30
    │   └── futures-util v0.3.30 (*)
    └── tokio-tungstenite v0.23.1 (*)

For a better understanding here is also my project tree:

rust
├─ .devcontainer
│  └─ devcontainer.json
├─ .git
│  ├─ FETCH_HEAD
│  ├─ HEAD
│  ├─ config
│  ├─ description
│  ├─ hooks
│  │  ├─ applypatch-msg.sample
│  │  ├─ commit-msg.sample
│  │  ├─ fsmonitor-watchman.sample
│  │  ├─ post-update.sample
│  │  ├─ pre-applypatch.sample
│  │  ├─ pre-commit.sample
│  │  ├─ pre-merge-commit.sample
│  │  ├─ pre-push.sample
│  │  ├─ pre-rebase.sample
│  │  ├─ pre-receive.sample
│  │  ├─ prepare-commit-msg.sample
│  │  ├─ push-to-checkout.sample
│  │  └─ update.sample
│  ├─ info
│  │  └─ exclude
│  ├─ objects
│  │  ├─ info
│  │  └─ pack
│  └─ refs
│     ├─ heads
│     └─ tags
├─ .github
│  └─ dependabot.yml
├─ .gitignore
├─ Cargo.lock
├─ Cargo.toml
├─ README.md
├─ examples
│  └─ std
│     ├─ Cargo.lock
│     ├─ Cargo.toml
│     └─ src
│        └─ bin
│           └─ client.rs
└─ src
   └─ lib.rs

I expect the program to compile as intended, as all trait bounds needed for WebsocketIO are implemented.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật