Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ The minor version will be incremented upon a breaking change and the patch versi

### Fixes

- lang: Migrate `anchor-syn` from syn 1.x to syn 2.0, enabling correct IDL generation for crates that use modern Rust syntax (e.g. precise-capturing `+ use<T>`, C-string literals) ([#4521](https://github.com/solana-foundation/anchor/issues/4521)).
Comment thread
eteen12 marked this conversation as resolved.
Outdated
- lang: Avoid fatal errors in IDL building when modern Rust syntax is in use ([#4520](https://github.com/solana-foundation/anchor/pull/4520)).
- client: Avoid panic in `parse_logs_response` when a program-emitted log line ends with `invoke [1]` ([#4461](https://github.com/solana-foundation/anchor/issues/4461)).
- cli: Correctly honor `--skip-seed-phrase-validation` in `keygen recover` ([#4417](https://github.com/solana-foundation/anchor/pull/4417)).
Expand Down
27 changes: 17 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"lang/error",
"lang/syn",
"spl",
"tests/idl-forward-ref/programs/idl-forward-ref",
]
exclude = ["tests/cfo/deps/openbook-dex", "tests/swap/deps/openbook-dex"]
resolver = "2"
Expand Down Expand Up @@ -62,6 +63,7 @@ solana-transaction = "3.0.1"

# Non solana crates
cargo_toml = "0.22.3"
syn = "2"

[profile.release]
lto = true
Expand Down
2 changes: 1 addition & 1 deletion cli/cli-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ proc-macro = true
[dependencies]
quote = "1"
proc-macro2 = "1.0"
syn = "2.0"
syn = { workspace = true }
2 changes: 1 addition & 1 deletion lang/attribute/access-control/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ indexing-slicing = "deny"
[dependencies]
proc-macro2 = "1"
quote = "1"
syn = { version = "1", features = ["full"] }
syn = { workspace = true, features = ["full"] }
2 changes: 1 addition & 1 deletion lang/attribute/account/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ event-cpi = []
anchor-syn = { path = "../../syn", version = "1.0.2", features = ["hash"] }
proc-macro2 = "1"
quote = "1"
syn = { version = "1", features = ["full"] }
syn = { workspace = true, features = ["full"] }
48 changes: 22 additions & 26 deletions lang/attribute/account/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use {
parse::{Parse, ParseStream},
parse_macro_input,
spanned::Spanned,
token::{Comma, Paren},
Expr, Ident, LitStr,
token::Paren,
Expr, Ident, LitStr, Token,
},
};

Expand Down Expand Up @@ -324,7 +324,7 @@ struct AccountArgs {
impl Parse for AccountArgs {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut parsed = Self::default();
let args = input.parse_terminated::<_, Comma>(AccountArg::parse)?;
let args = input.parse_terminated(AccountArg::parse, Token![,])?;
for arg in args {
match arg {
AccountArg::ZeroCopy { is_unsafe } => {
Expand Down Expand Up @@ -414,33 +414,24 @@ pub fn derive_zero_copy_accessor(item: proc_macro::TokenStream) -> proc_macro::T
field
.attrs
.iter()
.find(|attr| anchor_syn::parser::tts_to_string(&attr.path) == "accessor")
.find(|attr| anchor_syn::parser::tts_to_string(attr.path()) == "accessor")
.map(|attr| {
let mut tts = attr.tokens.clone().into_iter();
// if user writes #[accessor] with no arguments on a field, tts.next() returns None
let g_stream = match tts.next() {
Some(proc_macro2::TokenTree::Group(g)) => g.stream(),
Some(_) => {
let tokens = match &attr.meta {
syn::Meta::List(list) => list.tokens.clone(),
_ => {
return syn::Error::new_spanned(
&attr.tokens,
"invalid `#[accessor]` syntax, expected `#[accessor(Type)]`",
)
.into_compile_error();
}
None => {
return syn::Error::new_spanned(
&attr.tokens,
attr,
"`#[accessor]` requires a type argument, e.g `#[accessor(MyType)]`",
)
.into_compile_error();
}
};
let accessor_ty = match g_stream.into_iter().next() {
let accessor_ty = match tokens.into_iter().next() {
Some(token) => token,
None => {
return syn::Error::new_spanned(
&attr.tokens,
"`#[accessor]` requires a type inside the parantheses e.g \
attr,
"`#[accessor]` requires a type inside the parentheses e.g \
`#[accessor(MyType)]`",
)
.into_compile_error()
Expand Down Expand Up @@ -543,7 +534,7 @@ pub fn zero_copy(
let attr = account_strct
.attrs
.iter()
.find(|attr| anchor_syn::parser::tts_to_string(&attr.path) == "repr");
.find(|attr| anchor_syn::parser::tts_to_string(attr.path()) == "repr");

let repr = match attr {
// Users might want to manually specify repr modifiers e.g. repr(C, packed)
Expand All @@ -560,12 +551,17 @@ pub fn zero_copy(
let mut has_pod_attr = false;
let mut has_zeroable_attr = false;
for attr in account_strct.attrs.iter() {
let token_string = attr.tokens.to_string();
if token_string.contains("bytemuck :: Pod") {
has_pod_attr = true;
if !attr.path().is_ident("derive") {
continue;
}
if token_string.contains("bytemuck :: Zeroable") {
has_zeroable_attr = true;
if let syn::Meta::List(list) = &attr.meta {
let tokens_str = list.tokens.to_string();
if tokens_str.contains("bytemuck :: Pod") {
has_pod_attr = true;
}
if tokens_str.contains("bytemuck :: Zeroable") {
has_zeroable_attr = true;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion lang/attribute/constant/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ idl-build = ["anchor-syn/idl-build"]
[dependencies]
anchor-syn = { path = "../../syn", version = "1.0.2" }
quote = "1"
syn = { version = "1", features = ["full"] }
syn = { workspace = true, features = ["full"] }
2 changes: 1 addition & 1 deletion lang/attribute/error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ idl-build = ["anchor-syn/idl-build"]
[dependencies]
anchor-syn = { path = "../../syn", version = "1.0.2" }
quote = "1"
syn = { version = "1", features = ["full"] }
syn = { workspace = true, features = ["full"] }
2 changes: 1 addition & 1 deletion lang/attribute/event/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ idl-build = ["anchor-syn/idl-build"]
anchor-syn = { path = "../../syn", version = "1.0.2", features = ["hash"] }
proc-macro2 = "1"
quote = "1"
syn = { version = "1", features = ["full"] }
syn = { workspace = true, features = ["full"] }
2 changes: 1 addition & 1 deletion lang/attribute/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ anyhow = "1"
heck = "0.3"
proc-macro2 = "1"
quote = "1"
syn = { version = "1", features = ["full"] }
syn = { workspace = true, features = ["full"] }
2 changes: 1 addition & 1 deletion lang/derive/accounts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ init-if-needed = ["anchor-syn/init-if-needed"]
[dependencies]
anchor-syn = { path = "../../syn", version = "1.0.2" }
quote = "1"
syn = { version = "1", features = ["full"] }
syn = { workspace = true, features = ["full"] }
2 changes: 1 addition & 1 deletion lang/derive/serde/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ anchor-syn = { path = "../../syn", version = "1.0.2" }
proc-macro-crate = "3.4.0"
proc-macro2 = "1"
quote = "1"
syn = { version = "1", features = ["full"] }
syn = { workspace = true, features = ["full"] }

[dev-dependencies]
# Serialization macros require `anchor-lang` to be available to locate `borsh`
Expand Down
34 changes: 22 additions & 12 deletions lang/derive/serde/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,29 @@ use {
proc_macro2::{Span, TokenStream as TokenStream2},
proc_macro_crate::FoundCrate,
quote::quote,
syn::{parse_macro_input, DeriveInput, Ident, Meta, NestedMeta},
syn::{parse_macro_input, DeriveInput, Ident},
};

/// Only one item-level `#[borsh]` attribute may be present, and we apply our own borsh attribute.
/// Remove any user-provided `#[borsh]` attributes to apply in our generated derive.
fn extract_borsh_attrs(input: &mut DeriveInput) -> Vec<NestedMeta> {
fn extract_borsh_attrs(input: &mut DeriveInput) -> Vec<syn::Meta> {
input
.attrs
.extract_if(.., |attr| attr.path.is_ident("borsh"))
.extract_if(.., |attr| attr.path().is_ident("borsh"))
.filter_map(|attr| {
if let Ok(Meta::List(list)) = attr.parse_meta() {
Some(list)
if let syn::Meta::List(list) = attr.meta {
Some(list.tokens)
} else {
None
}
})
.flat_map(|list| list.nested)
.flat_map(|tokens| {
syn::parse::Parser::parse2(
syn::punctuated::Punctuated::<syn::Meta, syn::Token![,]>::parse_terminated,
tokens,
)
.unwrap_or_default()
})
.collect()
}

Expand All @@ -43,19 +49,19 @@ fn find_field_borsh_attr(input: &DeriveInput) -> Option<&syn::Attribute> {
.fields
.iter()
.flat_map(|field| field.attrs.iter())
.find(|attr| attr.path.is_ident("borsh")),
.find(|attr| attr.path().is_ident("borsh")),
syn::Data::Enum(data) => data
.variants
.iter()
.flat_map(|variant| variant.fields.iter())
.flat_map(|field| field.attrs.iter())
.find(|attr| attr.path.is_ident("borsh")),
.find(|attr| attr.path().is_ident("borsh")),
syn::Data::Union(data) => data
.fields
.named
.iter()
.flat_map(|field| field.attrs.iter())
.find(|attr| attr.path.is_ident("borsh")),
.find(|attr| attr.path().is_ident("borsh")),
}
}

Expand Down Expand Up @@ -131,9 +137,13 @@ fn gen_borsh_deserialize(input: TokenStream) -> TokenStream {
let unsupported = borsh_attrs.iter().find(|attr| {
!matches!(
attr,
NestedMeta::Meta(Meta::NameValue(nv))
syn::Meta::NameValue(nv)
if nv.path.is_ident("use_discriminant")
&& matches!(&nv.lit, syn::Lit::Bool(b) if !b.value)
&& matches!(
&nv.value,
syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Bool(b), .. })
if !b.value
)
)
});
if let Some(attr) = unsupported {
Expand Down Expand Up @@ -200,7 +210,7 @@ pub fn anchor_deserialize(input: TokenStream) -> TokenStream {
gen_borsh_deserialize(input)
}

fn helper_attrs(mac: &str, borsh_attrs: Vec<NestedMeta>) -> TokenStream2 {
fn helper_attrs(mac: &str, borsh_attrs: Vec<syn::Meta>) -> TokenStream2 {
// We need to emit the original borsh deserialization macros on our type,
// but derive macros can't emit other derives. To get around this, we use a hack:
// 1. Define an `__erase` attribute macro which deletes the item it is applied to
Expand Down
2 changes: 1 addition & 1 deletion lang/derive/space/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ indexing-slicing = "deny"
[dependencies]
proc-macro2 = "1"
quote = "1"
syn = { version = "1", features = ["extra-traits"] }
syn = { workspace = true, features = ["extra-traits", "parsing"] }
6 changes: 3 additions & 3 deletions lang/derive/space/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use {
punctuated::Punctuated,
spanned::Spanned,
token::Comma,
Attribute, DeriveInput, Expr, Field, Fields, GenericArgument, PathArguments, Type,
Attribute, DeriveInput, Expr, Field, Fields, GenericArgument, PathArguments, Token, Type,
TypeArray,
},
};
Expand Down Expand Up @@ -201,7 +201,7 @@ fn get_first_ty_arg(args: &PathArguments) -> Option<Type> {

fn parse_len_arg(item: ParseStream) -> Result<VecDeque<TokenStream2>, syn::Error> {
// Parse comma-separated expressions
let exprs = item.parse_terminated::<Expr, syn::token::Comma>(Expr::parse)?;
let exprs = item.parse_terminated(Expr::parse, Token![,])?;
let mut result = VecDeque::new();

// Push them in reverse because get_next_arg() pops from the back
Expand All @@ -221,7 +221,7 @@ fn parse_len_arg(item: ParseStream) -> Result<VecDeque<TokenStream2>, syn::Error
fn get_max_len_args(attributes: &[Attribute]) -> Option<VecDeque<TokenStream2>> {
attributes
.iter()
.find(|a| a.path.is_ident("max_len"))
.find(|a| a.path().is_ident("max_len"))
.and_then(|a| a.parse_args_with(parse_len_arg).ok())
}

Expand Down
Loading
Loading