diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-02-17 02:46:30 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-02-17 02:46:30 +0000 |
commit | 7d13b67a219988408fd4b617b3dec7d2faa9bbc5 (patch) | |
tree | 5bc3ea8b1f2ca69cb6970ca3c7bc93cbcd309502 | |
parent | f2efcdc612a75dc5dcfe0321b247f83d5e289272 (diff) | |
parent | 063e3bea92d73e862ee9271415ae1871214649ae (diff) | |
download | pin-project-internal-7d13b67a219988408fd4b617b3dec7d2faa9bbc5.tar.gz |
Snap for 8192738 from 063e3bea92d73e862ee9271415ae1871214649ae to tm-frc-documentsui-release
Change-Id: Id823518a92b795ab2ad476fc8203e66d4452b3dc
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 27 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | Cargo.toml.orig | 2 | ||||
-rw-r--r-- | METADATA | 8 | ||||
-rw-r--r-- | TEST_MAPPING | 8 | ||||
-rw-r--r-- | cargo2android.json | 4 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/pin_project/derive.rs | 128 | ||||
-rw-r--r-- | src/pinned_drop.rs | 3 | ||||
-rw-r--r-- | src/utils.rs | 19 |
11 files changed, 114 insertions, 91 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 6cfdedc..759ab72 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "a51d39fcdb31fe78cc61c0053ead2beb65a4156d" + "sha1": "6bd40906acb8574a3a0bbadc7cf1349fadac7d3c" } } @@ -1,4 +1,4 @@ -// This file is generated by cargo2android.py --run --dependencies --tests. +// This file is generated by cargo2android.py --config cargo2android.json. // Do not modify this file as changes will be overridden on upgrade. package { @@ -42,6 +42,8 @@ license { rust_proc_macro { name: "libpin_project_internal", crate_name: "pin_project_internal", + cargo_env_compat: true, + cargo_pkg_version: "1.0.8", srcs: ["src/lib.rs"], edition: "2018", rustlibs: [ @@ -50,26 +52,3 @@ rust_proc_macro { "libsyn", ], } - -rust_test_host { - name: "pin-project-internal_host_test_src_lib", - crate_name: "pin_project_internal", - srcs: ["src/lib.rs"], - test_suites: ["general-tests"], - auto_gen_config: true, - test_options: { - unit_test: true, - }, - edition: "2018", - rustlibs: [ - "libproc_macro2", - "libquote", - "libsyn", - ], -} - -// dependent_library ["feature_list"] -// proc-macro2-1.0.26 "default,proc-macro" -// quote-1.0.9 "default,proc-macro" -// syn-1.0.68 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote,visit-mut" -// unicode-xid-0.2.1 "default" @@ -13,7 +13,7 @@ [package] edition = "2018" name = "pin-project-internal" -version = "1.0.6" +version = "1.0.8" authors = ["Taiki Endo <te316e89@gmail.com>"] description = "Implementation detail of the `pin-project` crate.\n" documentation = "https://docs.rs/pin-project-internal" diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 707c32b..3d0c564 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "pin-project-internal" -version = "1.0.6" +version = "1.0.8" authors = ["Taiki Endo <te316e89@gmail.com>"] edition = "2018" license = "Apache-2.0 OR MIT" @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/pin-project-internal/pin-project-internal-1.0.6.crate" + value: "https://static.crates.io/crates/pin-project-internal/pin-project-internal-1.0.8.crate" } - version: "1.0.6" + version: "1.0.8" license_type: NOTICE last_upgrade_date { year: 2021 - month: 4 - day: 1 + month: 8 + day: 9 } } diff --git a/TEST_MAPPING b/TEST_MAPPING deleted file mode 100644 index 7e10dd0..0000000 --- a/TEST_MAPPING +++ /dev/null @@ -1,8 +0,0 @@ -// Generated by update_crate_tests.py for tests that depend on this crate. -{ - "presubmit": [ - { - "name": "futures-util_device_test_src_lib" - } - ] -} diff --git a/cargo2android.json b/cargo2android.json new file mode 100644 index 0000000..341300b --- /dev/null +++ b/cargo2android.json @@ -0,0 +1,4 @@ +{ + "run": true, + "tests": true +}
\ No newline at end of file @@ -9,7 +9,7 @@ ))] #![warn(unsafe_code)] #![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)] -#![warn(clippy::all, clippy::default_trait_access)] +#![warn(clippy::default_trait_access, clippy::wildcard_imports)] #![allow(clippy::needless_doctest_main)] // older compilers require explicit `extern crate`. diff --git a/src/pin_project/derive.rs b/src/pin_project/derive.rs index 82539ca..47c061f 100644 --- a/src/pin_project/derive.rs +++ b/src/pin_project/derive.rs @@ -3,7 +3,7 @@ use quote::{format_ident, quote, quote_spanned, ToTokens}; use syn::{ parse_quote, token, visit_mut::VisitMut, Attribute, Data, DataEnum, DeriveInput, Error, Field, Fields, FieldsNamed, FieldsUnnamed, Generics, Ident, Index, Lifetime, LifetimeDef, Meta, - MetaList, NestedMeta, Result, Token, Type, Variant, Visibility, WhereClause, + MetaList, MetaNameValue, NestedMeta, Result, Token, Type, Variant, Visibility, WhereClause, }; use super::{ @@ -88,6 +88,7 @@ impl GenerateTokens { // * https://github.com/taiki-e/pin-project/pull/70 #allowed_lints #[allow(clippy::semicolon_if_nothing_returned)] + #[allow(clippy::use_self)] #[allow(clippy::used_underscore_binding)] const _: () = { #scoped @@ -112,12 +113,13 @@ fn global_allowed_lints() -> TokenStream { #[allow(clippy::unknown_clippy_lints)] #[allow(clippy::pattern_type_mismatch)] #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct. + #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326 } } /// Returns attributes used on projected types. -fn proj_allowed_lints(kind: TypeKind) -> (TokenStream, TokenStream, TokenStream) { - let large_enum_variant = if kind == Enum { +fn proj_allowed_lints(cx: &Context<'_>) -> (TokenStream, TokenStream, TokenStream) { + let large_enum_variant = if cx.kind == Enum { Some(quote! { #[allow(variant_size_differences)] #[allow(clippy::large_enum_variant)] @@ -126,20 +128,22 @@ fn proj_allowed_lints(kind: TypeKind) -> (TokenStream, TokenStream, TokenStream) None }; let global_allowed_lints = global_allowed_lints(); + let proj_mut_allowed_lints = if cx.project { Some(&global_allowed_lints) } else { None }; let proj_mut = quote! { - #global_allowed_lints + #proj_mut_allowed_lints #[allow(dead_code)] // This lint warns unused fields/variants. #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. - #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326} }; + let proj_ref_allowed_lints = if cx.project_ref { Some(&global_allowed_lints) } else { None }; let proj_ref = quote! { - #global_allowed_lints + #proj_ref_allowed_lints #[allow(dead_code)] // This lint warns unused fields/variants. #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&<ty>>`. - #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326 }; + let proj_own_allowed_lints = + if cx.project_replace.ident().is_some() { Some(&global_allowed_lints) } else { None }; let proj_own = quote! { - #global_allowed_lints + #proj_own_allowed_lints #[allow(dead_code)] // This lint warns unused fields/variants. #large_enum_variant }; @@ -152,7 +156,7 @@ struct Context<'a> { /// The projected types. proj: ProjectedType, /// Types of the pinned fields. - pinned_fields: Vec<Type>, + pinned_fields: Vec<&'a Type>, /// Kind of the original type: struct or enum kind: TypeKind, @@ -320,13 +324,13 @@ fn validate_enum(brace_token: token::Brace, variants: &Variants) -> Result<()> { } } -fn parse_struct( - cx: &mut Context<'_>, - fields: &Fields, +fn parse_struct<'a>( + cx: &mut Context<'a>, + fields: &'a Fields, generate: &mut GenerateTokens, ) -> Result<()> { // Do this first for a better error message. - let packed_check = ensure_not_packed(&cx.orig, fields)?; + let packed_check = ensure_not_packed(&cx.orig, Some(fields))?; validate_struct(cx.orig.ident, fields)?; @@ -368,7 +372,7 @@ fn parse_struct( Fields::Unit => unreachable!(), }; - let (proj_attrs, proj_ref_attrs, proj_own_attrs) = proj_allowed_lints(cx.kind); + let (proj_attrs, proj_ref_attrs, proj_own_attrs) = proj_allowed_lints(cx); generate.extend(cx.project, quote! { #proj_attrs #vis struct #proj_ident #proj_generics #where_clause_fields @@ -402,9 +406,9 @@ fn parse_struct( Ok(()) } -fn parse_enum( - cx: &mut Context<'_>, - DataEnum { brace_token, variants, .. }: &DataEnum, +fn parse_enum<'a>( + cx: &mut Context<'a>, + DataEnum { brace_token, variants, .. }: &'a DataEnum, generate: &mut GenerateTokens, ) -> Result<()> { if let ProjReplace::Unnamed { span } = &cx.project_replace { @@ -414,8 +418,12 @@ fn parse_enum( )); } - // We don't need to check for `#[repr(packed)]`, - // since it does not apply to enums. + // #[repr(packed)] cannot be apply on enums and will be rejected by rustc. + // However, we should not rely on the behavior of rustc that rejects this. + // https://github.com/taiki-e/pin-project/pull/324#discussion_r612388001 + // + // Do this first for a better error message. + ensure_not_packed(&cx.orig, None)?; validate_enum(*brace_token, variants)?; @@ -437,7 +445,7 @@ fn parse_enum( let proj_generics = &cx.proj.generics; let proj_where_clause = &cx.proj.where_clause; - let (proj_attrs, proj_ref_attrs, proj_own_attrs) = proj_allowed_lints(cx.kind); + let (proj_attrs, proj_ref_attrs, proj_own_attrs) = proj_allowed_lints(cx); if cx.project { generate.extend(true, quote! { #proj_attrs @@ -483,7 +491,7 @@ fn parse_enum( Ok(()) } -fn visit_variants(cx: &mut Context<'_>, variants: &Variants) -> Result<ProjectedVariants> { +fn visit_variants<'a>(cx: &mut Context<'a>, variants: &'a Variants) -> Result<ProjectedVariants> { let mut proj_variants = TokenStream::new(); let mut proj_ref_variants = TokenStream::new(); let mut proj_own_variants = TokenStream::new(); @@ -540,10 +548,10 @@ fn visit_variants(cx: &mut Context<'_>, variants: &Variants) -> Result<Projected }) } -fn visit_fields( - cx: &mut Context<'_>, +fn visit_fields<'a>( + cx: &mut Context<'a>, variant_ident: Option<&Ident>, - fields: &Fields, + fields: &'a Fields, delim: Delimiter, ) -> Result<ProjectedFields> { fn surround(delim: Delimiter, tokens: TokenStream) -> TokenStream { @@ -561,8 +569,8 @@ fn visit_fields( for (i, Field { attrs, vis, ident, colon_token, ty }) in fields.iter().enumerate() { let binding = ident.clone().unwrap_or_else(|| format_ident!("_{}", i)); proj_pat.extend(quote!(#binding,)); + let lifetime = &cx.proj.lifetime; if attrs.position_exact(PIN)?.is_some() { - let lifetime = &cx.proj.lifetime; proj_fields.extend(quote! { #vis #ident #colon_token ::pin_project::__private::Pin<&#lifetime mut (#ty)>, }); @@ -579,10 +587,9 @@ fn visit_fields( #ident #colon_token ::pin_project::__private::PhantomData, }); - cx.pinned_fields.push(ty.clone()); + cx.pinned_fields.push(ty); pinned_bindings.push(binding); } else { - let lifetime = &cx.proj.lifetime; proj_fields.extend(quote! { #vis #ident #colon_token &#lifetime mut (#ty), }); @@ -608,7 +615,7 @@ fn visit_fields( let proj_own_fields = surround(delim, proj_own_fields); let proj_move = Group::new(delim, proj_move); - let proj_own_body = proj_own_body(cx, variant_ident, Some(proj_move), &pinned_bindings); + let proj_own_body = proj_own_body(cx, variant_ident, Some(&proj_move), &pinned_bindings); Ok(ProjectedFields { proj_pat, @@ -626,7 +633,7 @@ fn visit_fields( fn proj_own_body( cx: &Context<'_>, variant_ident: Option<&Ident>, - proj_move: Option<Group>, + proj_move: Option<&Group>, pinned_fields: &[Ident], ) -> TokenStream { let ident = &cx.proj.own_ident; @@ -886,7 +893,7 @@ fn make_drop_impl(cx: &Context<'_>) -> TokenStream { // Since the user did not pass `PinnedDrop` to `#[pin_project]`, any `PinnedDrop` // impl will not actually be called. Unfortunately, we can't detect this situation // directly from either the `#[pin_project]` or `#[pinned_drop]` attributes, since - // we don't know what other attirbutes/impl may exist. + // we don't know what other attributes/impl may exist. // // To ensure that users don't accidentally write a non-functional `PinnedDrop` // impls, we emit one ourselves. If the user ends up writing a `PinnedDrop` impl, @@ -996,8 +1003,8 @@ fn make_proj_impl( /// 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 -/// forbidding `safe_packed_borrows` lint. -fn ensure_not_packed(orig: &OriginalType<'_>, fields: &Fields) -> Result<TokenStream> { +/// 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()) { if let Meta::List(list) = meta { if list.path.is_ident("repr") { @@ -1005,22 +1012,36 @@ fn ensure_not_packed(orig: &OriginalType<'_>, fields: &Fields) -> Result<TokenSt match repr { NestedMeta::Meta(Meta::Path(path)) | NestedMeta::Meta(Meta::List(MetaList { path, .. })) - if path.is_ident("packed") => - { - return Err(error!( - repr, - "#[pin_project] attribute may not be used on #[repr(packed)] types" - )); + | NestedMeta::Meta(Meta::NameValue(MetaNameValue { path, .. })) => { + if path.is_ident("packed") { + let msg = if fields.is_none() { + // #[repr(packed)] cannot be apply on enums and will be rejected by rustc. + // However, we should not rely on the behavior of rustc that rejects this. + // https://github.com/taiki-e/pin-project/pull/324#discussion_r612388001 + "#[repr(packed)] attribute should be applied to a struct or union" + } else if let NestedMeta::Meta(Meta::NameValue(..)) = repr { + // #[repr(packed = "")] is not valid format of #[repr(packed)] and will be + // rejected by rustc. + // However, we should not rely on the behavior of rustc that rejects this. + // https://github.com/taiki-e/pin-project/pull/324#discussion_r612388001 + "#[repr(packed)] attribute should not be name-value pair" + } else { + "#[pin_project] attribute may not be used on #[repr(packed)] types" + }; + return Err(error!(repr, msg)); + } } - _ => {} + NestedMeta::Lit(..) => {} } } } } } - // As proc-macro-derive can't rewrite the structure definition, - // it's probably no longer necessary, but it keeps it for now. + let fields = match fields { + Some(fields) => fields, + None => return Ok(TokenStream::new()), + }; // Workaround for https://github.com/taiki-e/pin-project/issues/32 // Through the tricky use of proc macros, it's possible to bypass @@ -1029,7 +1050,7 @@ fn ensure_not_packed(orig: &OriginalType<'_>, fields: &Fields) -> Result<TokenSt // struct, we generate code like this: // // ```rust - // #[forbid(safe_packed_borrows)] + // #[forbid(unaligned_references)] // fn assert_not_repr_packed(val: &MyStruct) { // let _field1 = &val.field1; // let _field2 = &val.field2; @@ -1038,10 +1059,8 @@ fn ensure_not_packed(orig: &OriginalType<'_>, fields: &Fields) -> Result<TokenSt // } // ``` // - // Taking a reference to a packed field is unsafe, and applying - // `#[forbid(safe_packed_borrows)]` makes sure that doing this without - // an `unsafe` block (which we deliberately do not generate) - // is a hard error. + // Taking a reference to a packed field is UB, and applying + // `#[forbid(unaligned_references)]` makes sure that doing this is a hard error. // // If the struct ends up having `#[repr(packed)]` applied somehow, // this will generate an (unfriendly) error message. Under all reasonable @@ -1061,6 +1080,21 @@ fn ensure_not_packed(orig: &OriginalType<'_>, fields: &Fields) -> Result<TokenSt // `#[repr(packed)]` in the first place. // // See also https://github.com/taiki-e/pin-project/pull/34. + // + // Note: + // - pin-project v0.4.3 or later (#135, v0.4.0-v0.4.2 are already yanked for + // another reason) is internally proc-macro-derive, so they are not + // affected by the problem that the struct definition is rewritten by + // another macro after the #[pin_project] is expanded. + // So this is probably no longer necessary, but it keeps it for now. + // + // - Lint-based tricks aren't perfect, but they're much better than nothing: + // https://github.com/taiki-e/pin-project-lite/issues/26 + // + // - Enable both unaligned_references and safe_packed_borrows lints + // because unaligned_references lint does not exist in older compilers: + // https://github.com/taiki-e/pin-project-lite/pull/55 + // https://github.com/rust-lang/rust/pull/82525 let mut field_refs = vec![]; match fields { Fields::Named(FieldsNamed { named, .. }) => { @@ -1080,7 +1114,7 @@ fn ensure_not_packed(orig: &OriginalType<'_>, fields: &Fields) -> Result<TokenSt let (impl_generics, ty_generics, where_clause) = orig.generics.split_for_impl(); let ident = orig.ident; Ok(quote! { - #[forbid(safe_packed_borrows)] + #[forbid(unaligned_references, safe_packed_borrows)] fn __assert_not_repr_packed #impl_generics (this: &#ident #ty_generics) #where_clause { #(let _ = #field_refs;)* } diff --git a/src/pinned_drop.rs b/src/pinned_drop.rs index ecf52dd..a28a701 100644 --- a/src/pinned_drop.rs +++ b/src/pinned_drop.rs @@ -189,6 +189,9 @@ fn expand_impl(item: &mut ItemImpl) { None } + // `PinnedDrop` is a private trait and should not appear in docs. + item.attrs.push(parse_quote!(#[doc(hidden)])); + let path = &mut item.trait_.as_mut().unwrap().1; *path = parse_quote_spanned! { path.span() => ::pin_project::__private::PinnedDrop diff --git a/src/utils.rs b/src/utils.rs index 37f35ba..3fa07e7 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -176,7 +176,9 @@ impl<'a> ParseBufferExt<'a> for ParseBuffer<'a> { // visitors // Replace `self`/`Self` with `__self`/`self_ty`. -// Based on https://github.com/dtolnay/async-trait/blob/0.1.35/src/receiver.rs +// Based on: +// - https://github.com/dtolnay/async-trait/blob/0.1.35/src/receiver.rs +// - https://github.com/dtolnay/async-trait/commit/6029cbf375c562ca98fa5748e9d950a8ff93b0e7 pub(crate) struct ReplaceReceiver<'a>(pub(crate) &'a TypePath); @@ -259,7 +261,7 @@ impl ReplaceReceiver<'_> { match iter.peek() { Some(TokenTree::Punct(p)) if p.as_char() == ':' => { let span = ident.span(); - out.extend(quote_spanned!(span=> <#self_ty>)) + out.extend(quote_spanned!(span=> <#self_ty>)); } _ => out.extend(quote!(#self_ty)), } @@ -313,7 +315,6 @@ impl VisitMut for ReplaceReceiver<'_> { // `Self::method` -> `<Receiver>::method` fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) { if expr.qself.is_none() { - prepend_underscore_to_self(&mut expr.path.segments[0].ident); self.self_to_qself(&mut expr.qself, &mut expr.path); } visit_mut::visit_expr_path_mut(self, expr); @@ -341,11 +342,21 @@ impl VisitMut for ReplaceReceiver<'_> { visit_mut::visit_pat_tuple_struct_mut(self, pat); } + fn visit_path_mut(&mut self, path: &mut Path) { + if path.segments.len() == 1 { + // Replace `self`, but not `self::function`. + prepend_underscore_to_self(&mut path.segments[0].ident); + } + for segment in &mut path.segments { + self.visit_path_arguments_mut(&mut segment.arguments); + } + } + fn visit_item_mut(&mut self, item: &mut Item) { match item { // Visit `macro_rules!` because locally defined macros can refer to `self`. Item::Macro(item) if item.mac.path.is_ident("macro_rules") => { - self.visit_macro_mut(&mut item.mac) + self.visit_macro_mut(&mut item.mac); } // Otherwise, do not recurse into nested items. _ => {} |