Closed chipsenkbeil closed 3 years ago
Note that this breaks compatibility with no-std environment.
@taiki-e, should there be another test environment to support the no-std environment? Would be good for this to be caught in automated test.
Reading through the issue, you mentioned a trick is needed to get this to work. I don't work outside of the std environment, so am not familiar with what would need to be done here. Would be happy to help if there's some good reading material to get me caught up.
I've been bitten by async-trait in quite a few cases where I'm trying to be hygienic, but have to manually include a reference to Box
because of the lack of complete pathing. Hoping to help this get resolved.
Reading through the issue, you mentioned a trick is needed to get this to work. I don't work outside of the std environment, so am not familiar with what would need to be done here. Would be happy to help if there's some good reading material to get me caught up.
The basic idea is to import the alloc
crate in front of the trait/impl when expanding the code and refer that crate.
extern crate alloc as _alloc;
trait ...
fn method() -> ::_alloc::boxed::Box<...> // <- instead of `Box`
However, this way may result in crate name collisions (multiple _alloc in the same scope).
One of the workarounds for collisions is using the crate name that contains the hash value of the input tokens instead of _alloc. Something like:
#[proc_macro_attribute]
pub fn async_trait(args: ..., input: ...) -> ... {
// ...
let alloc_crate = format_ident!("_alloc{}", hash(&input));
// ...
quote! {
extern crate alloc as #alloc_crate;
}
}
use std::{collections::hash_map::DefaultHasher, hash::Hasher};
fn hash(input: &TokenStream) -> u64 {
let mut hasher = DefaultHasher::new();
hasher.write(input.to_string().as_bytes());
hasher.finish()
}
Resolves #163.