diff options
Diffstat (limited to 'patches/syn-2.diff')
-rw-r--r-- | patches/syn-2.diff | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/patches/syn-2.diff b/patches/syn-2.diff new file mode 100644 index 0000000..143c988 --- /dev/null +++ b/patches/syn-2.diff @@ -0,0 +1,378 @@ +diff --git a/src/pin_project/args.rs b/src/pin_project/args.rs +index d0d4f36..d242ae7 100644 +--- a/src/pin_project/args.rs ++++ b/src/pin_project/args.rs +@@ -16,10 +16,9 @@ pub(super) fn parse_args(attrs: &[Attribute]) -> Result<Args> { + impl Parse for Input { + fn parse(input: ParseStream<'_>) -> Result<Self> { + Ok(Self((|| { +- let content = input.parenthesized().ok()?; +- let private = content.parse::<Ident>().ok()?; ++ let private = input.parse::<Ident>().ok()?; + if private == "__private" { +- content.parenthesized().ok()?.parse::<TokenStream>().ok() ++ input.parenthesized().ok()?.parse::<TokenStream>().ok() + } else { + None + } +@@ -31,10 +30,10 @@ pub(super) fn parse_args(attrs: &[Attribute]) -> Result<Args> { + bail!(attr, "duplicate #[pin_project] attribute"); + } + +- let mut attrs = attrs.iter().filter(|attr| attr.path.is_ident(PIN)); ++ let mut attrs = attrs.iter().filter(|attr| attr.path().is_ident(PIN)); + + let prev = if let Some(attr) = attrs.next() { +- (attr, syn::parse2::<Input>(attr.tokens.clone()).unwrap().0) ++ (attr, syn::parse2::<Input>(attr.meta.require_list()?.tokens.clone())?.0) + } else { + // This only fails if another macro removes `#[pin]`. + bail!(TokenStream::new(), "#[pin_project] attribute has been removed"); +@@ -46,7 +45,7 @@ pub(super) fn parse_args(attrs: &[Attribute]) -> Result<Args> { + // has the same span as `#[pin_project]`, it is possible + // that a useless error message will be generated. + // So, use the span of `prev_attr` if it is not a valid attribute. +- let res = syn::parse2::<Input>(attr.tokens.clone()).unwrap().0; ++ let res = syn::parse2::<Input>(attr.meta.require_list()?.tokens.clone())?.0; + let span = match (prev_res, res) { + (Some(_), _) => attr, + (None, _) => prev_attr, +diff --git a/src/pin_project/derive.rs b/src/pin_project/derive.rs +index fd2375d..d2b2b5e 100644 +--- a/src/pin_project/derive.rs ++++ b/src/pin_project/derive.rs +@@ -1,9 +1,9 @@ + use proc_macro2::{Delimiter, Group, Span, TokenStream}; + 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, MetaNameValue, NestedMeta, Result, Token, Type, Variant, Visibility, WhereClause, ++ parse_quote, punctuated::Punctuated, token, visit_mut::VisitMut, Attribute, Data, DataEnum, ++ DeriveInput, Error, Field, Fields, FieldsNamed, FieldsUnnamed, Generics, Ident, Index, ++ Lifetime, LifetimeParam, Meta, Result, Token, Type, Variant, Visibility, WhereClause, + }; + + use super::{ +@@ -235,7 +235,7 @@ impl<'a> Context<'a> { + } + } + +-#[derive(Copy, Clone, Eq, PartialEq)] ++#[derive(Copy, Clone, PartialEq)] + enum TypeKind { + Enum, + Struct, +@@ -305,7 +305,7 @@ fn validate_struct(ident: &Ident, fields: &Fields) -> Result<()> { + fn validate_enum(brace_token: token::Brace, variants: &Variants) -> Result<()> { + if variants.is_empty() { + return Err(Error::new( +- brace_token.span, ++ brace_token.span.join(), + "#[pin_project] attribute may not be used on enums without variants", + )); + } +@@ -569,7 +569,9 @@ fn visit_fields<'a>( + let mut proj_move = TokenStream::new(); + let mut pinned_bindings = Vec::with_capacity(fields.len()); + +- for (i, Field { attrs, vis, ident, colon_token, ty }) in fields.iter().enumerate() { ++ for (i, Field { attrs, vis, ident, colon_token, ty, mutability: _ }) in ++ fields.iter().enumerate() ++ { + let binding = ident.clone().unwrap_or_else(|| format_ident!("_{}", i)); + proj_pat.extend(quote!(#binding,)); + let lifetime = &cx.proj.lifetime; +@@ -768,7 +770,7 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream { + // This ensures that any unused type parameters + // don't end up with `Unpin` bounds. + let lifetime_fields = cx.orig.generics.lifetimes().enumerate().map( +- |(i, LifetimeDef { lifetime, .. })| { ++ |(i, LifetimeParam { lifetime, .. })| { + let field_ident = format_ident!("__lifetime{}", i); + quote!(#field_ident: &#lifetime ()) + }, +@@ -1016,33 +1018,26 @@ fn make_proj_impl( + /// - 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()) { +- if let Meta::List(list) = meta { ++ for attr in orig.attrs { ++ if let Meta::List(ref list) = attr.meta { + if list.path.is_ident("repr") { +- for repr in list.nested.iter() { +- match repr { +- NestedMeta::Meta(Meta::Path(path)) +- | NestedMeta::Meta(Meta::List(MetaList { path, .. })) +- | 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" +- }; +- bail!(repr, msg); +- } +- } +- NestedMeta::Lit(..) => {} ++ for repr in list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)? { ++ if repr.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 repr.require_name_value().is_ok() { ++ // #[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" ++ }; ++ bail!(repr, msg); + } + } + } +@@ -1063,10 +1058,10 @@ fn ensure_not_packed(orig: &OriginalType<'_>, fields: Option<&Fields>) -> Result + // ```rust + // #[forbid(unaligned_references)] + // fn assert_not_repr_packed(val: &MyStruct) { +- // let _field1 = &val.field1; +- // let _field2 = &val.field2; ++ // let _field_1 = &val.field_1; ++ // let _field_2 = &val.field_2; + // ... +- // let _fieldn = &val.fieldn; ++ // let _field_n = &val.field_n; + // } + // ``` + // +diff --git a/src/pinned_drop.rs b/src/pinned_drop.rs +index 912989d..d30ecbe 100644 +--- a/src/pinned_drop.rs ++++ b/src/pinned_drop.rs +@@ -1,16 +1,18 @@ + use proc_macro2::TokenStream; + use quote::{format_ident, quote, ToTokens}; + use syn::{ +- parse_quote, spanned::Spanned, visit_mut::VisitMut, Error, FnArg, GenericArgument, ImplItem, +- ItemImpl, Pat, PatIdent, Path, PathArguments, Result, ReturnType, Signature, Token, Type, +- TypePath, TypeReference, ++ parse_quote, spanned::Spanned, token::Colon, visit_mut::VisitMut, Error, FnArg, ++ GenericArgument, Ident, ImplItem, ItemImpl, Pat, PatIdent, PatType, Path, PathArguments, ++ Result, ReturnType, Signature, Token, Type, TypePath, TypeReference, + }; + +-use crate::utils::{parse_as_empty, prepend_underscore_to_self, ReplaceReceiver, SliceExt}; ++use crate::utils::{ReplaceReceiver, SliceExt}; + + pub(crate) fn attribute(args: &TokenStream, mut input: ItemImpl) -> TokenStream { + let res = (|| -> Result<()> { +- parse_as_empty(args)?; ++ if !args.is_empty() { ++ bail!(args, "unexpected argument: `{}`", args) ++ } + validate_impl(&input)?; + expand_impl(&mut input); + Ok(()) +@@ -85,7 +87,7 @@ fn validate_impl(item: &ItemImpl) -> Result<()> { + ImplItem::Type(item) => { + bail!(item, "type `{}` is not a member of trait `PinnedDrop`", item.ident) + } +- ImplItem::Method(method) => { ++ ImplItem::Fn(method) => { + validate_sig(&method.sig)?; + if i == 0 { + Ok(()) +@@ -124,14 +126,15 @@ fn validate_sig(sig: &Signature) -> Result<()> { + + match sig.inputs.len() { + 1 => {} +- 0 => return Err(Error::new(sig.paren_token.span, INVALID_ARGUMENT)), ++ 0 => return Err(Error::new(sig.paren_token.span.join(), INVALID_ARGUMENT)), + _ => bail!(sig.inputs, INVALID_ARGUMENT), + } + +- if let Some(FnArg::Typed(arg)) = sig.receiver() { ++ if let Some(arg) = sig.receiver() { + // (mut) self: <path> + if let Some(path) = get_ty_path(&arg.ty) { +- let ty = path.segments.last().unwrap(); ++ let ty = ++ path.segments.last().expect("Type paths should always have at least one segment"); + if let PathArguments::AngleBracketed(args) = &ty.arguments { + // (mut) self: (<path>::)<ty><&mut <elem>..> + if let Some(GenericArgument::Type(Type::Reference(TypeReference { +@@ -175,25 +178,16 @@ fn validate_sig(sig: &Signature) -> Result<()> { + // } + // + fn expand_impl(item: &mut ItemImpl) { +- fn get_arg_pat(arg: &mut FnArg) -> Option<&mut PatIdent> { +- if let FnArg::Typed(arg) = arg { +- if let Pat::Ident(ident) = &mut *arg.pat { +- return Some(ident); +- } +- } +- 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; ++ let path = &mut item.trait_.as_mut().expect("unexpected inherent impl").1; + *path = parse_quote_spanned! { path.span() => + ::pin_project::__private::PinnedDrop + }; + + let method = +- if let ImplItem::Method(method) = &mut item.items[0] { method } else { unreachable!() }; ++ if let ImplItem::Fn(method) = &mut item.items[0] { method } else { unreachable!() }; + + // `fn drop(mut self: Pin<&mut Self>)` -> `fn __drop_inner<T>(mut __self: Pin<&mut Receiver>)` + let drop_inner = { +@@ -203,8 +197,20 @@ fn expand_impl(item: &mut ItemImpl) { + drop_inner.block.stmts.insert(0, parse_quote!(fn #ident() {})); + drop_inner.sig.ident = ident; + drop_inner.sig.generics = item.generics.clone(); +- let self_pat = get_arg_pat(&mut drop_inner.sig.inputs[0]).unwrap(); +- prepend_underscore_to_self(&mut self_pat.ident); ++ let receiver = drop_inner.sig.receiver().expect("drop() should have a receiver").clone(); ++ let pat = Box::new(Pat::Ident(PatIdent { ++ attrs: Vec::new(), ++ by_ref: None, ++ mutability: receiver.mutability, ++ ident: Ident::new("__self", receiver.self_token.span()), ++ subpat: None, ++ })); ++ drop_inner.sig.inputs[0] = FnArg::Typed(PatType { ++ attrs: receiver.attrs, ++ pat, ++ colon_token: Colon::default(), ++ ty: receiver.ty, ++ }); + let self_ty = if let Type::Path(ty) = &*item.self_ty { ty } else { unreachable!() }; + let mut visitor = ReplaceReceiver(self_ty); + visitor.visit_signature_mut(&mut drop_inner.sig); +@@ -214,9 +220,12 @@ fn expand_impl(item: &mut ItemImpl) { + + // `fn drop(mut self: Pin<&mut Self>)` -> `unsafe fn drop(self: Pin<&mut Self>)` + method.sig.unsafety = Some(<Token![unsafe]>::default()); +- let self_pat = get_arg_pat(&mut method.sig.inputs[0]).unwrap(); +- self_pat.mutability = None; +- let self_token = &self_pat.ident; ++ let self_token = if let FnArg::Receiver(ref mut rec) = method.sig.inputs[0] { ++ rec.mutability = None; ++ &rec.self_token ++ } else { ++ panic!("drop() should have a receiver") ++ }; + + method.block.stmts = parse_quote! { + #[allow(clippy::needless_pass_by_value)] // This lint does not warn the receiver. +diff --git a/src/utils.rs b/src/utils.rs +index 27373ef..3f4ec85 100644 +--- a/src/utils.rs ++++ b/src/utils.rs +@@ -8,7 +8,7 @@ use syn::{ + punctuated::Punctuated, + token, + visit_mut::{self, VisitMut}, +- Attribute, ExprPath, ExprStruct, Generics, Ident, Item, Lifetime, LifetimeDef, Macro, PatPath, ++ Attribute, ExprPath, ExprStruct, Generics, Ident, Item, Lifetime, LifetimeParam, Macro, + PatStruct, PatTupleStruct, Path, PathArguments, PredicateType, QSelf, Result, Token, Type, + TypeParamBound, TypePath, Variant, Visibility, WherePredicate, + }; +@@ -42,7 +42,7 @@ pub(crate) fn determine_lifetime_name(lifetime_name: &mut String, generics: &mut + struct CollectLifetimes(Vec<String>); + + impl VisitMut for CollectLifetimes { +- fn visit_lifetime_def_mut(&mut self, def: &mut LifetimeDef) { ++ fn visit_lifetime_param_mut(&mut self, def: &mut LifetimeParam) { + self.0.push(def.lifetime.to_string()); + } + } +@@ -84,7 +84,7 @@ pub(crate) fn insert_lifetime_and_bound( + pub(crate) fn insert_lifetime(generics: &mut Generics, lifetime: Lifetime) { + generics.lt_token.get_or_insert_with(<Token![<]>::default); + generics.gt_token.get_or_insert_with(<Token![>]>::default); +- generics.params.insert(0, LifetimeDef::new(lifetime).into()); ++ generics.params.insert(0, LifetimeParam::new(lifetime).into()); + } + + /// Determines the visibility of the projected types and projection methods. +@@ -93,24 +93,12 @@ pub(crate) fn insert_lifetime(generics: &mut Generics, lifetime: Lifetime) { + /// Otherwise, returned visibility is the same as given visibility. + pub(crate) fn determine_visibility(vis: &Visibility) -> Visibility { + if let Visibility::Public(token) = vis { +- parse_quote_spanned!(token.pub_token.span => pub(crate)) ++ parse_quote_spanned!(token.span => pub(crate)) + } else { + vis.clone() + } + } + +-/// Checks if `tokens` is an empty `TokenStream`. +-/// +-/// 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 { +- bail!(tokens, "unexpected token: `{}`", tokens) +- } +-} +- + pub(crate) fn respan<T>(node: &T, span: Span) -> T + where + T: ToTokens + Parse, +@@ -146,11 +134,11 @@ impl SliceExt for [Attribute] { + 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 attr.path().is_ident(ident) { + if prev.replace(i).is_some() { + bail!(attr, "duplicate #[{}] attribute", ident); + } +- parse_as_empty(&attr.tokens)?; ++ attr.meta.require_path_only()?; + } + Ok((i + 1, prev)) + }) +@@ -158,7 +146,7 @@ impl SliceExt for [Attribute] { + } + + fn find(&self, ident: &str) -> Option<&Attribute> { +- self.iter().position(|attr| attr.path.is_ident(ident)).map(|i| &self[i]) ++ self.iter().position(|attr| attr.path().is_ident(ident)).map(|i| &self[i]) + } + } + +@@ -335,13 +323,6 @@ impl VisitMut for ReplaceReceiver<'_> { + visit_mut::visit_expr_struct_mut(self, expr); + } + +- fn visit_pat_path_mut(&mut self, pat: &mut PatPath) { +- if pat.qself.is_none() { +- self.self_to_qself(&mut pat.qself, &mut pat.path); +- } +- visit_mut::visit_pat_path_mut(self, pat); +- } +- + fn visit_pat_struct_mut(&mut self, pat: &mut PatStruct) { + self.self_to_expr_path(&mut pat.path); + visit_mut::visit_pat_struct_mut(self, pat); |