Skip to content

Commit

Permalink
Update to syn 2 (#354)
Browse files Browse the repository at this point in the history
Effectively bumps MSRV to 1.56.0, due to syn 2 minimum requirements.

Co-authored-by: Matthew Maurer <mmaurer@google.com>
  • Loading branch information
daxpedda and maurer committed May 13, 2023
1 parent 6e0c2c2 commit ad3685e
Show file tree
Hide file tree
Showing 17 changed files with 108 additions and 123 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
fail-fast: false
matrix:
rust:
- '1.37'
- '1.56'
- stable
- beta
- nightly
Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
- run: cargo build --manifest-path tests/no-std/Cargo.toml --target thumbv6m-none-eabi
- run: cargo build --manifest-path tests/rust-2015/Cargo.toml --target thumbv6m-none-eabi
- run: cargo minimal-versions build --workspace --all-features --ignore-private
if: matrix.rust != '1.37'
if: matrix.rust != '1.56'

miri:
runs-on: ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "pin-project"
version = "1.0.12"
edition = "2018"
rust-version = "1.37"
rust-version = "1.56"
license = "Apache-2.0 OR MIT"
repository = "https://github.com/taiki-e/pin-project"
keywords = ["pin", "macros", "attribute"]
Expand Down Expand Up @@ -39,7 +39,7 @@ trybuild = "=1.0.67"

# For test on MSRV.
once_cell = "=1.14"
serde = "=1.0.156"
serde = "1.0.159"
toml = "=0.5.9"

[patch.crates-io]
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![crates.io](https://img.shields.io/crates/v/pin-project?style=flat-square&logo=rust)](https://crates.io/crates/pin-project)
[![docs.rs](https://img.shields.io/badge/docs.rs-pin--project-blue?style=flat-square&logo=docs.rs)](https://docs.rs/pin-project)
[![license](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue?style=flat-square)](#license)
[![rustc](https://img.shields.io/badge/rustc-1.37+-blue?style=flat-square&logo=rust)](https://www.rust-lang.org)
[![rustc](https://img.shields.io/badge/rustc-1.56+-blue?style=flat-square&logo=rust)](https://www.rust-lang.org)
[![build status](https://img.shields.io/github/actions/workflow/status/taiki-e/pin-project/ci.yml?branch=main&style=flat-square&logo=github)](https://github.com/taiki-e/pin-project/actions)

<!-- tidy:crate-doc:start -->
Expand All @@ -18,7 +18,7 @@ Add this to your `Cargo.toml`:
pin-project = "1"
```

*Compiler support: requires rustc 1.37+*
*Compiler support: requires rustc 1.56+*

## Examples

Expand Down
4 changes: 2 additions & 2 deletions pin-project-internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "pin-project-internal"
version = "1.0.12"
edition = "2018"
rust-version = "1.37"
rust-version = "1.56"
license = "Apache-2.0 OR MIT"
repository = "https://github.com/taiki-e/pin-project"
keywords = ["pin", "macros", "attribute"]
Expand All @@ -20,7 +20,7 @@ proc-macro = true
[dependencies]
proc-macro2 = "1"
quote = "1"
syn = { version = "1.0.56", features = ["full", "visit-mut"] }
syn = { version = "2.0.1", features = ["full", "visit-mut"] }

[dev-dependencies]
pin-project = { path = ".." }
11 changes: 5 additions & 6 deletions pin-project-internal/src/pin_project/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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");
Expand All @@ -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,
Expand Down
59 changes: 27 additions & 32 deletions pin-project-internal/src/pin_project/derive.rs
Original file line number Diff line number Diff line change
@@ -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::{
Expand Down Expand Up @@ -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",
));
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 ())
},
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
59 changes: 34 additions & 25 deletions pin-project-internal/src/pinned_drop.rs
Original file line number Diff line number Diff line change
@@ -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(())
Expand Down Expand Up @@ -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(())
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 = {
Expand All @@ -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);
Expand All @@ -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.
Expand Down
Loading

0 comments on commit ad3685e

Please sign in to comment.