memcache-async icon indicating copy to clipboard operation
memcache-async copied to clipboard

Fix conflicting async io feature compilation

Open filipeom opened this issue 6 months ago • 2 comments

Previously, enabling with-tokio would also activate the default feature (with-futures), because Cargo includes default features by design. This would lead to a compilation error due to duplicate definitions from both use statements. Example:

$ cargo build --features with-tokio
error[E0252]: the name `AsyncRead` is defined multiple times
 --> src/ascii.rs:8:34
  |
5 | use futures::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                    --------- previous import of the trait `AsyncRead` here
...
8 | use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                  ^^^^^^^^^ `AsyncRead` reimported here
  |
  = note: `AsyncRead` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
  |
8 | use tokio::io::{AsyncBufReadExt, AsyncRead as OtherAsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                            +++++++++++++++++

error[E0252]: the name `AsyncReadExt` is defined multiple times
 --> src/ascii.rs:8:45
  |
5 | use futures::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                               ------------ previous import of the trait `AsyncReadExt` here
...
8 | use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                             ^^^^^^^^^^^^ `AsyncReadExt` reimported here
  |
  = note: `AsyncReadExt` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
  |
8 | use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt as OtherAsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                                          ++++++++++++++++++++

error[E0252]: the name `AsyncWrite` is defined multiple times
 --> src/ascii.rs:8:59
  |
5 | use futures::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                                             ---------- previous import of the trait `AsyncWrite` here
...
8 | use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                                           ^^^^^^^^^^ `AsyncWrite` reimported here
  |
  = note: `AsyncWrite` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
  |
8 | use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite as OtherAsyncWrite, AsyncWriteExt, BufReader};
  |                                                                      ++++++++++++++++++

error[E0252]: the name `AsyncWriteExt` is defined multiple times
 --> src/ascii.rs:8:71
  |
5 | use futures::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                                                         ------------- previous import of the trait `AsyncWriteExt` here
...
8 | use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                                                       ^^^^^^^^^^^^^ `AsyncWriteExt` reimported here
  |
  = note: `AsyncWriteExt` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
  |
8 | use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt as OtherAsyncWriteExt, BufReader};
  |                                                                                     +++++++++++++++++++++

error[E0252]: the name `BufReader` is defined multiple times
 --> src/ascii.rs:8:86
  |
5 | use futures::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                                                                        --------- previous import of the type `BufReader` here
...
8 | use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                                                                                      ^^^^^^^^^ `BufReader` reimported here
  |
  = note: `BufReader` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
  |
8 | use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader as OtherBufReader};
  |                                                                                                +++++++++++++++++

warning: unused imports: `AsyncBufReadExt`, `AsyncReadExt`, `AsyncRead`, `AsyncWriteExt`, `AsyncWrite`, and `BufReader`
 --> src/ascii.rs:8:17
  |
8 | use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
  |                 ^^^^^^^^^^^^^^^  ^^^^^^^^^  ^^^^^^^^^^^^  ^^^^^^^^^^  ^^^^^^^^^^^^^  ^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

For more information about this error, try `rustc --explain E0252`.
warning: `memcache-async` (lib) generated 1 warning
error: could not compile `memcache-async` (lib) due to 6 previous errors; 1 warning emitted

This commit replaces the separate #[cfg] blocks with a single cfg_if macro. This creates a prioritized selection for the io backend.

filipeom avatar Aug 04 '25 12:08 filipeom

Hi! Would features = ["with-tokio"], default-features = false work? Can you rework it so that tokio dependency is optional only if tokio feature is enabled?

vavrusa avatar Dec 11 '25 18:12 vavrusa

Hi! Would features = ["with-tokio"], default-features = false work?

We ended up going with this as it was the simpler thing to do.

Can you rework it so that tokio dependency is optional only if tokio feature is enabled?

Yeah I can do that if you think this PR is still needed.

filipeom avatar Dec 12 '25 09:12 filipeom