diff options
-rw-r--r-- | .cargo_vcs_info.json | 7 | ||||
-rw-r--r-- | Android.bp | 2 | ||||
-rw-r--r-- | Cargo.toml | 13 | ||||
-rw-r--r-- | Cargo.toml.orig | 4 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | src/lib.rs | 14 | ||||
-rw-r--r-- | src/pin_project/args.rs | 56 | ||||
-rw-r--r-- | src/pin_project/attribute.rs | 15 | ||||
-rw-r--r-- | src/pin_project/derive.rs | 104 | ||||
-rw-r--r-- | src/pinned_drop.rs | 43 | ||||
-rw-r--r-- | src/utils.rs | 26 |
11 files changed, 146 insertions, 148 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 759ab72..60d79af 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,6 @@ { "git": { - "sha1": "6bd40906acb8574a3a0bbadc7cf1349fadac7d3c" - } -} + "sha1": "0273e6ecd64057f47c3b2ada6fb4e5c37357c185" + }, + "path_in_vcs": "pin-project-internal" +}
\ No newline at end of file @@ -43,7 +43,7 @@ rust_proc_macro { name: "libpin_project_internal", crate_name: "pin_project_internal", cargo_env_compat: true, - cargo_pkg_version: "1.0.8", + cargo_pkg_version: "1.0.10", srcs: ["src/lib.rs"], edition: "2018", rustlibs: [ @@ -3,20 +3,17 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "pin-project-internal" -version = "1.0.8" -authors = ["Taiki Endo <te316e89@gmail.com>"] +version = "1.0.10" description = "Implementation detail of the `pin-project` crate.\n" -documentation = "https://docs.rs/pin-project-internal" keywords = ["pin", "macros", "attribute"] categories = ["no-std", "rust-patterns"] license = "Apache-2.0 OR MIT" diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 3d0c564..78c2f44 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,11 +1,9 @@ [package] name = "pin-project-internal" -version = "1.0.8" -authors = ["Taiki Endo <te316e89@gmail.com>"] +version = "1.0.10" edition = "2018" license = "Apache-2.0 OR MIT" repository = "https://github.com/taiki-e/pin-project" -documentation = "https://docs.rs/pin-project-internal" keywords = ["pin", "macros", "attribute"] categories = ["no-std", "rust-patterns"] description = """ @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/pin-project-internal/pin-project-internal-1.0.8.crate" + value: "https://static.crates.io/crates/pin-project-internal/pin-project-internal-1.0.10.crate" } - version: "1.0.8" + version: "1.0.10" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 8 - day: 9 + year: 2022 + month: 3 + day: 1 } } @@ -8,7 +8,7 @@ ) ))] #![warn(unsafe_code)] -#![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)] +#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)] #![warn(clippy::default_trait_access, clippy::wildcard_imports)] #![allow(clippy::needless_doctest_main)] @@ -29,9 +29,9 @@ use proc_macro::TokenStream; /// /// This attribute creates projection types according to the following rules: /// -/// * For the fields that use `#[pin]` attribute, create the pinned reference to +/// - For the fields that use `#[pin]` attribute, create the pinned reference to /// the field. -/// * For the other fields, create a normal reference to the field. +/// - For the other fields, create a normal reference to the field. /// /// And the following methods are implemented on the original type: /// @@ -351,8 +351,8 @@ use proc_macro::TokenStream; /// This impl block acts just like a normal [`Drop`] impl, /// except for the following two: /// -/// * `drop` method takes [`Pin`]`<&mut Self>` -/// * Name of the trait is `PinnedDrop`. +/// - `drop` method takes [`Pin`]`<&mut Self>` +/// - Name of the trait is `PinnedDrop`. /// /// ```rust /// # use std::pin::Pin; @@ -495,8 +495,8 @@ pub fn pin_project(args: TokenStream, input: TokenStream) -> TokenStream { /// The impl block annotated with this attribute acts just like a normal /// [`Drop`] impl, except for the following two: /// -/// * `drop` method takes [`Pin`]`<&mut Self>` -/// * Name of the trait is `PinnedDrop`. +/// - `drop` method takes [`Pin`]`<&mut Self>` +/// - Name of the trait is `PinnedDrop`. /// /// ```rust /// # use std::pin::Pin; diff --git a/src/pin_project/args.rs b/src/pin_project/args.rs index c321260..d0d4f36 100644 --- a/src/pin_project/args.rs +++ b/src/pin_project/args.rs @@ -28,7 +28,7 @@ pub(super) fn parse_args(attrs: &[Attribute]) -> Result<Args> { } if let Some(attr) = attrs.find("pin_project") { - return Err(error!(attr, "duplicate #[pin_project] attribute")); + bail!(attr, "duplicate #[pin_project] attribute"); } let mut attrs = attrs.iter().filter(|attr| attr.path.is_ident(PIN)); @@ -37,7 +37,7 @@ pub(super) fn parse_args(attrs: &[Attribute]) -> Result<Args> { (attr, syn::parse2::<Input>(attr.tokens.clone()).unwrap().0) } else { // This only fails if another macro removes `#[pin]`. - return Err(error!(TokenStream::new(), "#[pin_project] attribute has been removed")); + bail!(TokenStream::new(), "#[pin_project] attribute has been removed"); }; if let Some(attr) = attrs.next() { @@ -51,11 +51,10 @@ pub(super) fn parse_args(attrs: &[Attribute]) -> Result<Args> { (Some(_), _) => attr, (None, _) => prev_attr, }; - Err(error!(span, "duplicate #[pin] attribute")) - } else { - // This `unwrap` only fails if another macro removes `#[pin]` and inserts own `#[pin]`. - syn::parse2(prev.1.unwrap()) + bail!(span, "duplicate #[pin] attribute"); } + // This `unwrap` only fails if another macro removes `#[pin]` and inserts own `#[pin]`. + syn::parse2(prev.1.unwrap()) } pub(super) struct Args { @@ -84,20 +83,19 @@ impl Parse for Args { has_prev: bool, ) -> Result<(Ident, TokenStream)> { if input.is_empty() { - return Err(error!(name, "expected `{0} = <identifier>`, found `{0}`", name)); + bail!(name, "expected `{0} = <identifier>`, found `{0}`", name); } let eq_token: Token![=] = input.parse()?; if input.is_empty() { let span = quote!(#name #eq_token); - return Err(error!(span, "expected `{0} = <identifier>`, found `{0} =`", name)); + bail!(span, "expected `{0} = <identifier>`, found `{0} =`", name); } let value: Ident = input.parse()?; let span = quote!(#name #value); if has_prev { - Err(error!(span, "duplicate `{}` argument", name)) - } else { - Ok((value, span)) + bail!(span, "duplicate `{}` argument", name); } + Ok((value, span)) } let mut pinned_drop = None; @@ -112,24 +110,24 @@ impl Parse for Args { if input.peek(Token![!]) { let bang: Token![!] = input.parse()?; if input.is_empty() { - return Err(error!(bang, "expected `!Unpin`, found `!`")); + bail!(bang, "expected `!Unpin`, found `!`"); } let unpin: kw::Unpin = input.parse()?; let span = quote!(#bang #unpin); if not_unpin.replace(span.span()).is_some() { - return Err(error!(span, "duplicate `!Unpin` argument")); + bail!(span, "duplicate `!Unpin` argument"); } } else { let token = input.parse::<Ident>()?; match &*token.to_string() { "PinnedDrop" => { if pinned_drop.replace(token.span()).is_some() { - return Err(error!(token, "duplicate `PinnedDrop` argument")); + bail!(token, "duplicate `PinnedDrop` argument"); } } "UnsafeUnpin" => { if unsafe_unpin.replace(token.span()).is_some() { - return Err(error!(token, "duplicate `UnsafeUnpin` argument")); + bail!(token, "duplicate `UnsafeUnpin` argument"); } } "project" => { @@ -145,18 +143,18 @@ impl Parse for Args { project_replace_value = Some(value); project_replace_span = Some(span.span()); } else if project_replace_span.is_some() { - return Err(error!(token, "duplicate `project_replace` argument")); + bail!(token, "duplicate `project_replace` argument"); } else { project_replace_span = Some(token.span()); } } "Replace" => { - return Err(error!( + bail!( token, "`Replace` argument was removed, use `project_replace` argument instead" - )); + ); } - _ => return Err(error!(token, "unexpected argument: {}", token)), + _ => bail!(token, "unexpected argument: {}", token), } } @@ -168,23 +166,17 @@ impl Parse for Args { if project.is_some() || project_ref.is_some() { if project == project_ref { - return Err(error!( + bail!( project_ref, "name `{}` is already specified by `project` argument", project_ref.as_ref().unwrap() - )); + ); } if let Some(ident) = &project_replace_value { if project == project_replace_value { - return Err(error!( - ident, - "name `{}` is already specified by `project` argument", ident - )); + bail!(ident, "name `{}` is already specified by `project` argument", ident); } else if project_ref == project_replace_value { - return Err(error!( - ident, - "name `{}` is already specified by `project_ref` argument", ident - )); + bail!(ident, "name `{}` is already specified by `project_ref` argument", ident); } } } @@ -253,6 +245,10 @@ impl ProjReplace { } pub(super) fn ident(&self) -> Option<&Ident> { - if let Self::Named { ident, .. } = self { Some(ident) } else { None } + if let Self::Named { ident, .. } = self { + Some(ident) + } else { + None + } } } diff --git a/src/pin_project/attribute.rs b/src/pin_project/attribute.rs index 92ed547..c8811cb 100644 --- a/src/pin_project/attribute.rs +++ b/src/pin_project/attribute.rs @@ -17,9 +17,9 @@ use crate::utils::SliceExt; // // At this stage, only attributes are parsed and the following attributes are // added to the attributes of the item. -// * `#[derive(InternalDerive)]` - An internal helper macro that does the above +// - `#[derive(InternalDerive)]` - An internal helper macro that does the above // processing. -// * `#[pin(__private(#args))]` - Pass the argument of `#[pin_project]` to +// - `#[pin(__private(#args))]` - Pass the argument of `#[pin_project]` to // proc-macro-derive (`InternalDerive`). pub(super) fn parse_attribute(args: &TokenStream, input: TokenStream) -> Result<TokenStream> { @@ -51,16 +51,15 @@ impl Parse for Input { if !ahead.peek(Token![struct]) && !ahead.peek(Token![enum]) { // If we check this only on proc-macro-derive, it may generate unhelpful error // messages. So it is preferable to be able to detect it here. - Err(error!( + bail!( input.parse::<TokenStream>()?, "#[pin_project] attribute may only be used on structs or enums" - )) + ); } else if let Some(attr) = attrs.find(PIN) { - Err(error!(attr, "#[pin] attribute may only be used on fields of structs or variants")) + bail!(attr, "#[pin] attribute may only be used on fields of structs or variants"); } else if let Some(attr) = attrs.find("pin_project") { - Err(error!(attr, "duplicate #[pin_project] attribute")) - } else { - Ok(Self { attrs, body: input.parse()? }) + bail!(attr, "duplicate #[pin_project] attribute"); } + Ok(Self { attrs, body: input.parse()? }) } } diff --git a/src/pin_project/derive.rs b/src/pin_project/derive.rs index 47c061f..3e578f7 100644 --- a/src/pin_project/derive.rs +++ b/src/pin_project/derive.rs @@ -38,10 +38,7 @@ pub(super) fn parse_derive(input: TokenStream) -> Result<TokenStream> { parse_enum(&mut cx, data, &mut generate)?; } Data::Union(_) => { - return Err(error!( - input, - "#[pin_project] attribute may only be used on structs or enums" - )); + bail!(input, "#[pin_project] attribute may only be used on structs or enums"); } } @@ -83,14 +80,17 @@ impl GenerateTokens { // but it is now removed. // // Refs: - // * https://github.com/rust-lang/rust/issues/63281 - // * https://github.com/taiki-e/pin-project/pull/53#issuecomment-525906867 - // * https://github.com/taiki-e/pin-project/pull/70 + // - https://github.com/rust-lang/rust/issues/63281 + // - https://github.com/taiki-e/pin-project/pull/53#issuecomment-525906867 + // - https://github.com/taiki-e/pin-project/pull/70 #allowed_lints + #[allow(unused_qualifications)] #[allow(clippy::semicolon_if_nothing_returned)] #[allow(clippy::use_self)] #[allow(clippy::used_underscore_binding)] const _: () = { + #[allow(unused_extern_crates)] + extern crate pin_project as _pin_project; #scoped #unpin_impl #drop_impl @@ -188,7 +188,7 @@ impl<'a> Context<'a> { .filter_map(Option::as_ref) .find(|name| **name == ident) { - return Err(error!(name, "name `{}` is the same as the original type name", name)); + bail!(name, "name `{}` is the same as the original type name", name); } let mut lifetime_name = String::from("'pin"); @@ -293,10 +293,12 @@ struct ProjectedFields { fn validate_struct(ident: &Ident, fields: &Fields) -> Result<()> { if fields.is_empty() { let msg = "#[pin_project] attribute may not be used on structs with zero fields"; - if let Fields::Unit = fields { Err(error!(ident, msg)) } else { Err(error!(fields, msg)) } - } else { - Ok(()) + if let Fields::Unit = fields { + bail!(ident, msg) + } + bail!(fields, msg) } + Ok(()) } fn validate_enum(brace_token: token::Brace, variants: &Variants) -> Result<()> { @@ -308,9 +310,9 @@ fn validate_enum(brace_token: token::Brace, variants: &Variants) -> Result<()> { } let has_field = variants.iter().try_fold(false, |has_field, v| { if let Some((_, e)) = &v.discriminant { - Err(error!(e, "#[pin_project] attribute may not be used on enums with discriminants")) + bail!(e, "#[pin_project] attribute may not be used on enums with discriminants"); } else if let Some(attr) = v.attrs.find(PIN) { - Err(error!(attr, "#[pin] attribute may only be used on fields of structs or variants")) + bail!(attr, "#[pin] attribute may only be used on fields of structs or variants"); } else if v.fields.is_empty() { Ok(has_field) } else { @@ -320,7 +322,7 @@ fn validate_enum(brace_token: token::Brace, variants: &Variants) -> Result<()> { if has_field { Ok(()) } else { - Err(error!(variants, "#[pin_project] attribute may not be used on enums with zero fields")) + bail!(variants, "#[pin_project] attribute may not be used on enums with zero fields"); } } @@ -581,10 +583,10 @@ fn visit_fields<'a>( #vis #ident #colon_token ::pin_project::__private::PhantomData<#ty>, }); proj_body.extend(quote! { - #ident #colon_token ::pin_project::__private::Pin::new_unchecked(#binding), + #ident #colon_token _pin_project::__private::Pin::new_unchecked(#binding), }); proj_move.extend(quote! { - #ident #colon_token ::pin_project::__private::PhantomData, + #ident #colon_token _pin_project::__private::PhantomData, }); cx.pinned_fields.push(ty); @@ -603,7 +605,7 @@ fn visit_fields<'a>( #binding, }); proj_move.extend(quote! { - #ident #colon_token ::pin_project::__private::ptr::read(#binding), + #ident #colon_token _pin_project::__private::ptr::read(#binding), }); } } @@ -658,7 +660,7 @@ fn proj_own_body( // if any of the destructors panic. { #( - let __guard = ::pin_project::__private::UnsafeDropInPlaceGuard(#pinned_fields); + let __guard = _pin_project::__private::UnsafeDropInPlaceGuard::new(#pinned_fields); )* } @@ -670,9 +672,9 @@ fn proj_own_body( /// Creates `Unpin` implementation for the original type. /// /// The kind of `Unpin` impl generated depends on `unpin_impl` field: -/// * `UnpinImpl::Unsafe` - Implements `Unpin` via `UnsafeUnpin` impl. -/// * `UnpinImpl::Negative` - Generates `Unpin` impl with bounds that will never be true. -/// * `UnpinImpl::Default` - Generates `Unpin` impl that requires `Unpin` for all pinned fields. +/// - `UnpinImpl::Unsafe` - Implements `Unpin` via `UnsafeUnpin` impl. +/// - `UnpinImpl::Negative` - Generates `Unpin` impl with bounds that will never be true. +/// - `UnpinImpl::Default` - Generates `Unpin` impl that requires `Unpin` for all pinned fields. fn make_unpin_impl(cx: &Context<'_>) -> TokenStream { match cx.unpin_impl { UnpinImpl::Unsafe(span) => { @@ -682,14 +684,14 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream { // Make the error message highlight `UnsafeUnpin` argument. proj_generics.make_where_clause().predicates.push(parse_quote_spanned! { span => - ::pin_project::__private::Wrapper<#lifetime, Self>: ::pin_project::UnsafeUnpin + _pin_project::__private::Wrapper<#lifetime, Self>: _pin_project::UnsafeUnpin }); let (impl_generics, _, where_clause) = proj_generics.split_for_impl(); let ty_generics = cx.orig.generics.split_for_impl().1; quote_spanned! { span => - impl #impl_generics ::pin_project::__private::Unpin for #orig_ident #ty_generics + impl #impl_generics _pin_project::__private::Unpin for #orig_ident #ty_generics #where_clause { } @@ -701,9 +703,9 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream { let lifetime = &cx.proj.lifetime; proj_generics.make_where_clause().predicates.push(parse_quote! { - ::pin_project::__private::Wrapper< - #lifetime, ::pin_project::__private::PhantomPinned - >: ::pin_project::__private::Unpin + _pin_project::__private::Wrapper< + #lifetime, _pin_project::__private::PhantomPinned + >: _pin_project::__private::Unpin }); let (proj_impl_generics, _, proj_where_clause) = proj_generics.split_for_impl(); @@ -713,7 +715,7 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream { // call-site span. let unsafety = <Token![unsafe]>::default(); quote_spanned! { span => - impl #proj_impl_generics ::pin_project::__private::Unpin + impl #proj_impl_generics _pin_project::__private::Unpin for #orig_ident #ty_generics #proj_where_clause { @@ -726,7 +728,7 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream { // impl, they'll get a "conflicting implementations of trait" error when // coherence checks are run. #[doc(hidden)] - #unsafety impl #proj_impl_generics ::pin_project::UnsafeUnpin + #unsafety impl #proj_impl_generics _pin_project::UnsafeUnpin for #orig_ident #ty_generics #proj_where_clause { @@ -781,7 +783,7 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream { let (_, ty_generics, where_clause) = cx.orig.generics.split_for_impl(); full_where_clause.predicates.push(parse_quote! { - #struct_ident #proj_ty_generics: ::pin_project::__private::Unpin + #struct_ident #proj_ty_generics: _pin_project::__private::Unpin }); quote! { @@ -797,15 +799,15 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream { // this 'public' type by creating this type in the inside of `const`. #[allow(missing_debug_implementations)] #vis struct #struct_ident #proj_generics #where_clause { - __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin< - #lifetime, (#(::pin_project::__private::PhantomData<#type_params>),*) + __pin_project_use_generics: _pin_project::__private::AlwaysUnpin< + #lifetime, (#(_pin_project::__private::PhantomData<#type_params>),*) >, #(#fields,)* #(#lifetime_fields,)* } - impl #proj_impl_generics ::pin_project::__private::Unpin + impl #proj_impl_generics _pin_project::__private::Unpin for #orig_ident #ty_generics #full_where_clause { @@ -818,7 +820,7 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream { // impl, they'll get a "conflicting implementations of trait" error when // coherence checks are run. #[doc(hidden)] - unsafe impl #proj_impl_generics ::pin_project::UnsafeUnpin + unsafe impl #proj_impl_generics _pin_project::UnsafeUnpin for #orig_ident #ty_generics #full_where_clause { @@ -831,8 +833,8 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream { /// Creates `Drop` implementation for the original type. /// /// The kind of `Drop` impl generated depends on `pinned_drop` field: -/// * `Some` - implements `Drop` via `PinnedDrop` impl. -/// * `None` - generates code that ensures that `Drop` trait is not implemented, +/// - `Some` - implements `Drop` via `PinnedDrop` impl. +/// - `None` - generates code that ensures that `Drop` trait is not implemented, /// instead of generating `Drop` impl. fn make_drop_impl(cx: &Context<'_>) -> TokenStream { let ident = cx.orig.ident; @@ -843,18 +845,18 @@ fn make_drop_impl(cx: &Context<'_>) -> TokenStream { // call-site span. let unsafety = <Token![unsafe]>::default(); quote_spanned! { span => - impl #impl_generics ::pin_project::__private::Drop for #ident #ty_generics + impl #impl_generics _pin_project::__private::Drop for #ident #ty_generics #where_clause { fn drop(&mut self) { #unsafety { // Safety - we're in 'drop', so we know that 'self' will // never move again. - let __pinned_self = ::pin_project::__private::Pin::new_unchecked(self); + let __pinned_self = _pin_project::__private::Pin::new_unchecked(self); // We call `pinned_drop` only once. Since `PinnedDrop::drop` // is an unsafe method and a private API, it is never called again in safe // code *unless the user uses a maliciously crafted macro*. - ::pin_project::__private::PinnedDrop::drop(__pinned_self); + _pin_project::__private::PinnedDrop::drop(__pinned_self); } } } @@ -886,7 +888,7 @@ fn make_drop_impl(cx: &Context<'_>) -> TokenStream { // This will result in a compilation error, which is exactly what we want. trait #trait_ident {} #[allow(clippy::drop_bounds, drop_bounds)] - impl<T: ::pin_project::__private::Drop> #trait_ident for T {} + impl<T: _pin_project::__private::Drop> #trait_ident for T {} impl #impl_generics #trait_ident for #ident #ty_generics #where_clause {} // Generate a dummy impl of `PinnedDrop`, to ensure that the user cannot implement it. @@ -900,10 +902,10 @@ fn make_drop_impl(cx: &Context<'_>) -> TokenStream { // they'll get a "conflicting implementations of trait" error when coherence // checks are run. #[doc(hidden)] - impl #impl_generics ::pin_project::__private::PinnedDrop for #ident #ty_generics + impl #impl_generics _pin_project::__private::PinnedDrop for #ident #ty_generics #where_clause { - unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {} + unsafe fn drop(self: _pin_project::__private::Pin<&mut Self>) {} } } } @@ -934,7 +936,7 @@ fn make_proj_impl( let mut project = Some(quote! { #vis fn project<#lifetime>( - self: ::pin_project::__private::Pin<&#lifetime mut Self>, + self: _pin_project::__private::Pin<&#lifetime mut Self>, ) -> #proj_ident #proj_ty_generics { unsafe { #proj_body @@ -944,7 +946,7 @@ fn make_proj_impl( let mut project_ref = Some(quote! { #[allow(clippy::missing_const_for_fn)] #vis fn project_ref<#lifetime>( - self: ::pin_project::__private::Pin<&#lifetime Self>, + self: _pin_project::__private::Pin<&#lifetime Self>, ) -> #proj_ref_ident #proj_ty_generics { unsafe { #proj_ref_body @@ -955,7 +957,7 @@ fn make_proj_impl( // It is enough to only set the span of the signature. let sig = quote_spanned! { span => #vis fn project_replace( - self: ::pin_project::__private::Pin<&mut Self>, + self: _pin_project::__private::Pin<&mut Self>, __replacement: Self, ) -> #proj_own_ident #orig_ty_generics }; @@ -966,10 +968,10 @@ fn make_proj_impl( // Destructors will run in reverse order, so next create a guard to overwrite // `self` with the replacement value without calling destructors. - let __guard = ::pin_project::__private::UnsafeOverwriteGuard { - target: __self_ptr, - value: ::pin_project::__private::ManuallyDrop::new(__replacement), - }; + let __guard = _pin_project::__private::UnsafeOverwriteGuard::new( + __self_ptr, + __replacement, + ); #proj_own_body } @@ -1001,8 +1003,8 @@ fn make_proj_impl( /// Checks that the `[repr(packed)]` attribute is not included. /// /// This currently does two checks: -/// * Checks the attributes of structs to ensure there is no `[repr(packed)]`. -/// * Generates a function that borrows fields without an unsafe block and +/// - Checks the attributes of structs to ensure there is no `[repr(packed)]`. +/// - Generates a function that borrows fields without an unsafe block and /// forbidding `unaligned_references` lint. fn ensure_not_packed(orig: &OriginalType<'_>, fields: Option<&Fields>) -> Result<TokenStream> { for meta in orig.attrs.iter().filter_map(|attr| attr.parse_meta().ok()) { @@ -1028,7 +1030,7 @@ fn ensure_not_packed(orig: &OriginalType<'_>, fields: Option<&Fields>) -> Result } else { "#[pin_project] attribute may not be used on #[repr(packed)] types" }; - return Err(error!(repr, msg)); + bail!(repr, msg); } } NestedMeta::Lit(..) => {} diff --git a/src/pinned_drop.rs b/src/pinned_drop.rs index a28a701..912989d 100644 --- a/src/pinned_drop.rs +++ b/src/pinned_drop.rs @@ -53,47 +53,44 @@ fn validate_impl(item: &ItemImpl) -> Result<()> { "#[pinned_drop] may only be used on implementation for the `PinnedDrop` trait"; if let Some(attr) = item.attrs.find("pinned_drop") { - return Err(error!(attr, "duplicate #[pinned_drop] attribute")); + bail!(attr, "duplicate #[pinned_drop] attribute"); } if let Some((_, path, _)) = &item.trait_ { if !path.is_ident("PinnedDrop") { - return Err(error!(path, INVALID_ITEM)); + bail!(path, INVALID_ITEM); } } else { - return Err(error!(item.self_ty, INVALID_ITEM)); + bail!(item.self_ty, INVALID_ITEM); } if item.unsafety.is_some() { - return Err(error!(item.unsafety, "implementing the trait `PinnedDrop` is not unsafe")); + bail!(item.unsafety, "implementing the trait `PinnedDrop` is not unsafe"); } if item.items.is_empty() { - return Err(error!(item, "not all trait items implemented, missing: `drop`")); + bail!(item, "not all trait items implemented, missing: `drop`"); } match &*item.self_ty { Type::Path(_) => {} ty => { - return Err(error!( - ty, - "implementing the trait `PinnedDrop` on this type is unsupported" - )); + bail!(ty, "implementing the trait `PinnedDrop` on this type is unsupported"); } } item.items.iter().enumerate().try_for_each(|(i, item)| match item { ImplItem::Const(item) => { - Err(error!(item, "const `{}` is not a member of trait `PinnedDrop`", item.ident)) + bail!(item, "const `{}` is not a member of trait `PinnedDrop`", item.ident) } ImplItem::Type(item) => { - Err(error!(item, "type `{}` is not a member of trait `PinnedDrop`", item.ident)) + bail!(item, "type `{}` is not a member of trait `PinnedDrop`", item.ident) } ImplItem::Method(method) => { validate_sig(&method.sig)?; if i == 0 { Ok(()) } else { - Err(error!(method, "duplicate definitions with name `drop`")) + bail!(method, "duplicate definitions with name `drop`") } } _ => unreachable!("unexpected ImplItem"), @@ -105,29 +102,30 @@ fn validate_impl(item: &ItemImpl) -> Result<()> { /// The correct signature is: `(mut) self: (<path>::)Pin<&mut Self>` fn validate_sig(sig: &Signature) -> Result<()> { fn get_ty_path(ty: &Type) -> Option<&Path> { - if let Type::Path(TypePath { qself: None, path }) = ty { Some(path) } else { None } + if let Type::Path(TypePath { qself: None, path }) = ty { + Some(path) + } else { + None + } } const INVALID_ARGUMENT: &str = "method `drop` must take an argument `self: Pin<&mut Self>`"; if sig.ident != "drop" { - return Err(error!( - sig.ident, - "method `{}` is not a member of trait `PinnedDrop", sig.ident, - )); + bail!(sig.ident, "method `{}` is not a member of trait `PinnedDrop", sig.ident,); } if let ReturnType::Type(_, ty) = &sig.output { match &**ty { Type::Tuple(ty) if ty.elems.is_empty() => {} - _ => return Err(error!(ty, "method `drop` must return the unit type")), + _ => bail!(ty, "method `drop` must return the unit type"), } } match sig.inputs.len() { 1 => {} 0 => return Err(Error::new(sig.paren_token.span, INVALID_ARGUMENT)), - _ => return Err(error!(sig.inputs, INVALID_ARGUMENT)), + _ => bail!(sig.inputs, INVALID_ARGUMENT), } if let Some(FnArg::Typed(arg)) = sig.receiver() { @@ -148,10 +146,7 @@ fn validate_sig(sig: &Signature) -> Result<()> { && get_ty_path(elem).map_or(false, |path| path.is_ident("Self")) { if sig.unsafety.is_some() { - return Err(error!( - sig.unsafety, - "implementing the method `drop` is not unsafe" - )); + bail!(sig.unsafety, "implementing the method `drop` is not unsafe"); } return Ok(()); } @@ -160,7 +155,7 @@ fn validate_sig(sig: &Signature) -> Result<()> { } } - Err(error!(sig.inputs[0], INVALID_ARGUMENT)) + bail!(sig.inputs[0], INVALID_ARGUMENT) } // from: diff --git a/src/utils.rs b/src/utils.rs index 3fa07e7..27373ef 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -15,12 +15,18 @@ use syn::{ pub(crate) type Variants = Punctuated<Variant, Token![,]>; -macro_rules! error { - ($span:expr, $msg:expr) => { - syn::Error::new_spanned(&$span, $msg) +macro_rules! format_err { + ($span:expr, $msg:expr $(,)?) => { + syn::Error::new_spanned(&$span as &dyn quote::ToTokens, &$msg as &dyn std::fmt::Display) }; ($span:expr, $($tt:tt)*) => { - error!($span, format!($($tt)*)) + format_err!($span, format!($($tt)*)) + }; +} + +macro_rules! bail { + ($($tt:tt)*) => { + return Err(format_err!($($tt)*)) }; } @@ -98,7 +104,11 @@ pub(crate) fn determine_visibility(vis: &Visibility) -> Visibility { /// This is almost equivalent to `syn::parse2::<Nothing>()`, but produces /// a better error message and does not require ownership of `tokens`. pub(crate) fn parse_as_empty(tokens: &TokenStream) -> Result<()> { - if tokens.is_empty() { Ok(()) } else { Err(error!(tokens, "unexpected token: {}", tokens)) } + if tokens.is_empty() { + Ok(()) + } else { + bail!(tokens, "unexpected token: `{}`", tokens) + } } pub(crate) fn respan<T>(node: &T, span: Span) -> T @@ -131,14 +141,14 @@ pub(crate) trait SliceExt { impl SliceExt for [Attribute] { /// # Errors /// - /// * There are multiple specified attributes. - /// * The `Attribute::tokens` field of the specified attribute is not empty. + /// - There are multiple specified attributes. + /// - The `Attribute::tokens` field of the specified attribute is not empty. fn position_exact(&self, ident: &str) -> Result<Option<usize>> { self.iter() .try_fold((0, None), |(i, mut prev), attr| { if attr.path.is_ident(ident) { if prev.replace(i).is_some() { - return Err(error!(attr, "duplicate #[{}] attribute", ident)); + bail!(attr, "duplicate #[{}] attribute", ident); } parse_as_empty(&attr.tokens)?; } |