Skip to content

Commit

Permalink
Prevent user call __drop_inner
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed May 11, 2020
1 parent 0aa5a0b commit c208c8c
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 4 deletions.
3 changes: 3 additions & 0 deletions examples/pinned_drop-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ impl<T> ::pin_project::__private::PinnedDrop for Struct<'_, T> {
unsafe fn drop(self: Pin<&mut Self>) {
#[allow(clippy::needless_pass_by_value)]
fn __drop_inner<T>(__self: Pin<&mut Struct<'_, T>>) {
// Added `__drop_inner` function to prevent user call outer `__drop_inner`.
fn __drop_inner() {}

**__self.project().was_dropped = true;
}
__drop_inner(self);
Expand Down
11 changes: 7 additions & 4 deletions pin-project-internal/src/pinned_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ fn parse_method(method: &ImplItemMethod) -> Result<()> {
match method.sig.inputs.len() {
1 => {}
0 => return Err(Error::new(method.sig.paren_token.span, INVALID_ARGUMENT)),
_ => return Err(error!(&method.sig.inputs, INVALID_ARGUMENT)),
_ => return Err(error!(method.sig.inputs, INVALID_ARGUMENT)),
}

if let Some(FnArg::Typed(pat)) = &method.sig.receiver() {
if let Some(FnArg::Typed(pat)) = method.sig.receiver() {
// (mut) self: <path>
if let Some(path) = get_ty_path(&pat.ty) {
let ty = path.segments.last().unwrap();
Expand Down Expand Up @@ -149,6 +149,7 @@ fn parse(item: &mut ItemImpl) -> Result<()> {
//
// unsafe fn drop(self: Pin<&mut Self>) {
// fn __drop_inner<T>(__self: Pin<&mut Foo<'_, T>>) {
// fn __drop_inner() {}
// // something
// }
// __drop_inner(self);
Expand All @@ -160,14 +161,16 @@ fn expand_item(item: &mut ItemImpl) {
let mut drop_inner = method.clone();

// `fn drop(mut self: Pin<&mut Self>)` -> `fn __drop_inner<T>(mut __self: Pin<&mut Receiver>)`
drop_inner.sig.ident = Ident::new("__drop_inner", drop_inner.sig.ident.span());
let ident = Ident::new("__drop_inner", drop_inner.sig.ident.span());
// Add `__drop_inner` function to prevent user call outer `__drop_inner`.
drop_inner.block.stmts.insert(0, parse_quote!(fn #ident() {}));
drop_inner.sig.ident = ident;
drop_inner.sig.generics = item.generics.clone();
if let FnArg::Typed(arg) = &mut drop_inner.sig.inputs[0] {
if let Pat::Ident(ident) = &mut *arg.pat {
prepend_underscore_to_self(&mut ident.ident);
}
}

let mut visitor = ReplaceReceiver(&item.self_ty);
visitor.visit_signature_mut(&mut drop_inner.sig);
visitor.visit_block_mut(&mut drop_inner.block);
Expand Down
1 change: 1 addition & 0 deletions tests/expand/tests/expand/pinned_drop-enum.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ impl<T, U> ::pin_project::__private::PinnedDrop for Enum<T, U> {
unsafe fn drop(self: Pin<&mut Self>) {
#[allow(clippy::needless_pass_by_value)]
fn __drop_inner<T, U>(__self: Pin<&mut Enum<T, U>>) {
fn __drop_inner() {}
let _this = __self;
}
__drop_inner(self);
Expand Down
1 change: 1 addition & 0 deletions tests/expand/tests/expand/pinned_drop-struct.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
unsafe fn drop(self: Pin<&mut Self>) {
#[allow(clippy::needless_pass_by_value)]
fn __drop_inner<T, U>(__self: Pin<&mut Struct<T, U>>) {
fn __drop_inner() {}
let _this = __self;
}
__drop_inner(self);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ impl<T, U> ::pin_project::__private::PinnedDrop for TupleStruct<T, U> {
unsafe fn drop(self: Pin<&mut Self>) {
#[allow(clippy::needless_pass_by_value)]
fn __drop_inner<T, U>(__self: Pin<&mut TupleStruct<T, U>>) {
fn __drop_inner() {}
let _this = __self;
}
__drop_inner(self);
Expand Down

0 comments on commit c208c8c

Please sign in to comment.