dtolnay / async-trait

Type erasure for async trait methods
Apache License 2.0
1.81k stars 84 forks source link

Don't rely on Box being in the prelude #132

Closed Kestrer closed 3 years ago

Kestrer commented 3 years ago

This code:

use async_trait::async_trait;

struct Box;

#[async_trait]
trait Foo {
    async fn foo(&self);
}

#[async_trait]
impl Foo for () {
    async fn foo(&self) {}
}

Fails because async-trait uses Box instead of ::std::boxed::Box ::alloc::boxed::Box in its macro expansion.

taiki-e commented 3 years ago

If use ::std::boxed::Box path, cannot use async-trait on no-std environment.

Kestrer commented 3 years ago

Oh, then it should use ::alloc::boxed::Box.

taiki-e commented 3 years ago

Yeah, but note that alloc crate is not available without an explicit extern crate alloc.

taiki-e commented 3 years ago

note that alloc crate is not available without an explicit extern crate alloc.

The way to make this works correctly is a bit tricky. It's available in function body by importing like extern crate alloc as _alloc, but doing the same in the position of the return value can cause _alloc to conflict with _alloc generated by other #[async_trait]. Probably it needs a trick, such as including the hash value of the input AST in the imported crate name.

dtolnay commented 3 years ago

I would like to leave this as currently implemented. Nobody should redefine Box and then expect to have boxed trait objects in the same module using a different Box.