# Why async_std::println! macro is not thread-safe?

rustc version:

``````❯ rustc --version
rustc 1.64.0-nightly (1c7b36d4d 2022-07-12)
``````

my code:

``````#[tokio::main]
async fn main() {
tokio::spawn(async {
foo().await;
}).await;
}

async fn foo() {
async_std::println!("hi").await;
}
``````

cargo check with `-Z macro-backtrace`:

``````❯ cargo check
Checking asdf v0.1.0 (/home/jo/asdf)
error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
--> src/main.rs:3:5
|
3   |     tokio::spawn(async {
|     ^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `core::fmt::Opaque`
= note: required because of the requirements on the impl of `std::marker::Send` for `&core::fmt::Opaque`
= note: required because it appears within the type `ArgumentV1<'_>`
= note: required because it appears within the type `[ArgumentV1<'_>; 0]`
= note: required because it captures the following types: `ResumeTy`, `&str`, `[&str; 1]`, `&[&str]`, `&[&str; 1]`, `[ArgumentV1<'_>; 0]`, `&[ArgumentV1<'_>]`, `&[ArgumentV1<'_>; 0]`, `Arguments<'_>`, `impl for<'r> Future<Output = ()>`, `()`
note: required because it's used within this `async` block
--> /home/jo/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.12.0/src/macros.rs:89:29
|
87  |   macro_rules! println {
|   -------------------- in this expansion of `async_std::println!`
88  |       () => (\$crate::print!("\n"));
89  |       (\$(\$arg:tt)*) => (async {
|  _____________________________^
90  | |         \$crate::io::_print(format_args!(\$(\$arg)*)).await;
91  | |         \$crate::io::_print(format_args!("\n")).await;
92  | |     })
| |_____^
|
::: src/main.rs:9:5
|
9   |       async_std::println!("hi").await;
|       ------------------------- in this macro invocation
= note: required because it captures the following types: `ResumeTy`, `[static generator@/home/jo/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.12.0/src/macros.rs:89:29: 92:6]`, `impl Future<Output = ()>`, `()`
note: required because it's used within this `async fn` body
--> src/main.rs:8:16
|
8   |   async fn foo() {
|  ________________^
9   | |     async_std::println!("hi").await;
10  | | }
| |_^
= note: required because it captures the following types: `ResumeTy`, `impl Future<Output = ()>`, `()`
note: required because it's used within this `async` block
--> src/main.rs:3:24
|
3   |       tokio::spawn(async {
|  ________________________^
4   | |         foo().await;
5   | |     }).await;
| |_____^
note: required by a bound in `tokio::spawn`
|
127 |         T: Future + Send + 'static,
|                     ^^^^ required by this bound in `tokio::spawn`

I really don't get the `cargo check` message. Should I just use the std println macro instead?
The `format_args!` macro internally puts all values to be printed into opaque containers. Those opaque containers never implement `Send` or `Sync` as the contained value may implement neither. I wouldn't be surprised if this problem you hit related to the reason that `async_std::println!()` is marked as unstable.