-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to use auto_impl with async-trait #65
Comments
I also just had a realization that perhaps the code generation might not work anyway, since If you could confirm whether this is even possible to do with |
I've closed ebkalderon/tower-lsp#109 for now, but I would still like to know if this is possible. |
Hi there! Turns out we just didn't release a new version for quite some time! This PR you linked is not yet released. I just tested with the current
I guess I can release a new version soon! |
@ebkalderon Could you test your crate with our |
Thanks a lot for clarifying, @LukasKalbertodt! Sure, I'll try it out on my local clone right now. |
Hmm, I've revised the commit on the
|
I think the generated code should be corrected from this: impl<T: Foo + ?::std::marker::Sized + 'async_trait> Foo for ::std::boxed::Box<T> to this: impl<'async_trait, T: Foo + ?::std::marker::Sized + 'async_trait> Foo for ::std::boxed::Box<T> |
Interesting, thanks for checking. In this case, we can simply remove the trait Foo {
fn foo(&self)
where
Self: 'static;
}
impl<'a, T: 'a + Foo> Foo for &'a T {
fn foo(&self)
where
Self: 'static
{
(**self).foo()
}
} I don't quite know why it's allowed. First it seemed like this might be a bug and could allow for unsafety. But of course, as always, I couldn't find a way to trigger unsafety. But my reasoning is: inside It would be great if we can just ignore lifetime constraints on |
Well, if you check the desugared version of It doesn't make sense to me to take that method-bound lifetime and apply it to all of |
Yeah it's true, the |
I don't believe the two cases are directly comparable, despite sharing similar syntax. I think this might be another case of input and output lifetime elision being made explicit, but I'm not as familiar with the deeper intricacies of the elision rules to know for certain. For example, I wonder trait Foo {
fn foo1<'a, 'b: 'a>(&'b self) -> &'a str;
fn foo2<'a, 'b>(&'b self) -> &'a str
where
'b: 'a,
Self: 'b;
} Hopefully someone more knowledgeable than me can answer this question! |
I'm currently pretty busy, but I'll try to figure this out and fix this by the end of the month. |
No worries, @LukasKalbertodt. Take your time. Thanks for creating this awesome crate, by the way! |
I finally managed to take a closer look. I discovered the bug in my thoughts (i.e. why I was confused). In short: if we access a field (or something like that) of In any case, #67 should fix your problem. At least the following code compiles fine:
|
Awesome work, @LukasKalbertodt! That's a very subtle change, but it makes perfect sense. I really appreciate you looking into it. I tried enabling it in fn _assert_object_safe() {
fn assert_impl<T: LanguageServer>() {}
assert_impl::<Box<dyn LanguageServer>>();
} Error message:
This seems to be because Any idea why the |
@ebkalderon Are you sure you are not testing with an incorrect version of #[auto_impl(Box)]
trait Foo: Sync {
fn bar<'life0, 'async_trait>(
&'life0 self
) -> Pin<Box<dyn Future<Output = Result<u32, Error>> + Send + 'async_trait>> where
'life0: 'async_trait,
Self: 'async_trait;
}
fn _assert_object_safe() {
fn assert_impl<T: Foo>() {}
assert_impl::<Box<dyn Foo>>();
} And |
Sorry for the delayed response, @LukasKalbertodt! Indeed I was. I had checked out an incorrect commit ref and didn't get the changes. It seems to work just fine now. 👍 |
I was trying to use
auto_impl
to delegate the implementation ofBox<T> where T: Trait
andTrait
was a trait annotated with theasync-trait
procedural macro. I was using it like this:The ordering of the above macros matters, as it ensures that
async_trait
transformsFoo
into the following Rust code beforeauto_impl
parses it:Provided that the
Sync
bound shown above is present as a supertrait ofFoo
, the above code should be object safe. I expected#[auto_impl(Box)]
to emit the following implementation:However, it emitted the following implementation instead:
This meant that the following code was able to compile with a manual
Box
implementation but failed under theauto_impl
-generated implementation:Do you have an idea as to why the
?Sized
bound was not applied in this case?See ebkalderon/tower-lsp#109 for the original pull request that inspired this issue.
The text was updated successfully, but these errors were encountered: