-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
135: Forbid custom Unpin/Drop impl if trait has Pin<&mut self> receiver r=taiki-e a=taiki-e If a user creates their own `Unpin` or `Drop` implementation, trait implementations with `Pin<&mut self>` receiver can cause unsoundness. This was not a problem in `#[auto_enum]` attribute where enums are anonymized, but it becomes a problem when users have access to enums (i.e., when using `#[enum_derive]`). This is essentially a problem of `derive_utils`, the backend of the derive implementation of this crate, and I was investigating ways to fix it on the `derive_utils` side, but finally decided it would be difficult and removed support for the `Pin<&mut self>` receiver from `derive_utils`. (taiki-e/derive_utils#41) So, we ensure safety here by an `Unpin` implementation that implements `Unpin` only if all fields are `Unpin` (this also forbids custom `Unpin` implementation), and a hack that forbids custom `Drop` implementation. (Both are what `pin-project` does by default.) The `repr(packed)` check is unnecessary since `repr(packed)` is unavailable on enum. This would make it impossible to use together with `#[pin_project]` or `pin_project!`, or to create custom `Drop` or `Unpin` implementations -- If someone needs it, it is possible to add an option like use_pin_project to support them, so please leave a comment. Co-authored-by: Taiki Endo <te316e89@gmail.com>
- Loading branch information
Showing
32 changed files
with
1,115 additions
and
344 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,36 @@ | ||
use quote::ToTokens; | ||
|
||
use crate::derive::*; | ||
|
||
pub(crate) const NAME: &[&str] = &["Future"]; | ||
|
||
pub(crate) fn derive(data: &Data) -> Result<TokenStream> { | ||
Ok(derive_trait(data, parse_quote!(::core::future::Future), None, parse_quote! { | ||
pub(crate) fn derive(cx: &Context, data: &Data) -> Result<TokenStream> { | ||
cx.needs_pin_projection(); | ||
|
||
let ident = &data.ident; | ||
let pin = quote!(::core::pin::Pin); | ||
let trait_: syn::Path = parse_quote!(::core::future::Future); | ||
let mut impl_ = EnumImpl::from_trait(data, trait_.clone(), None, parse_quote! { | ||
trait Future { | ||
type Output; | ||
#[inline] | ||
fn poll( | ||
self: ::core::pin::Pin<&mut Self>, | ||
cx: &mut ::core::task::Context<'_>, | ||
) -> ::core::task::Poll<Self::Output>; | ||
} | ||
})) | ||
}) | ||
.build_impl(); | ||
|
||
let poll = data | ||
.variant_idents() | ||
.map(|v| quote!(#ident::#v(x) => #trait_::poll(#pin::new_unchecked(x), cx))); | ||
impl_.items.push(parse_quote! { | ||
#[inline] | ||
fn poll( | ||
self: #pin<&mut Self>, | ||
cx: &mut ::core::task::Context<'_>, | ||
) -> ::core::task::Poll<Self::Output> { | ||
unsafe { | ||
match self.get_unchecked_mut() { #(#poll,)* } | ||
} | ||
} | ||
}); | ||
|
||
Ok(impl_.into_token_stream()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.