From b83bf4784ee9732a6bea12aaa7547ae01b3ef6b0 Mon Sep 17 00:00:00 2001
From: Sam Johnson <sam@durosoft.com>
Date: Wed, 12 Apr 2023 14:42:22 -0400
Subject: [PATCH] Globally upgrade to syn 2.x and latest quote and proc_macro2
 1x versions (#13846)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* globally upgrade quote to latest 1.0.x (1.0.26)

* globally upgrade syn to final 1.0.x version (1.0.109)

* globally upgrade proc-macro2 to 1.0.56

* upgrade to syn v2.0.13 and fix everything except NestedMeta

* fix parse nested metadata code in decl_runtime_apis.rs

* Port more stuff to syn 2.0

* Make the rest compile

* Ignore error

* update to syn 2.0.14

---------

Co-authored-by: Bastian Köcher <info@kchr.de>
---
 substrate/Cargo.lock                          |  36 +++---
 substrate/bin/node/cli/tests/telemetry.rs     |   5 +-
 substrate/client/chain-spec/derive/Cargo.toml |   6 +-
 .../client/chain-spec/derive/src/impls.rs     |   2 +-
 substrate/client/consensus/babe/src/lib.rs    |   5 +-
 .../client/db/src/pinned_blocks_cache.rs      |   5 +-
 .../client/service/test/src/client/mod.rs     |   5 +-
 substrate/client/state-db/src/lib.rs          |  10 +-
 .../client/tracing/proc-macro/Cargo.toml      |   6 +-
 .../frame/contracts/proc-macro/Cargo.toml     |   6 +-
 .../frame/contracts/proc-macro/src/lib.rs     |  10 +-
 .../solution-type/Cargo.toml                  |   6 +-
 .../solution-type/src/lib.rs                  |   4 +-
 substrate/frame/nfts/src/tests.rs             |   6 +-
 substrate/frame/scheduler/src/migration.rs    |  10 +-
 .../frame/staking/reward-curve/Cargo.toml     |   6 +-
 substrate/frame/support/procedural/Cargo.toml |   6 +-
 .../frame/support/procedural/src/benchmark.rs |  90 ++++++-------
 .../procedural/src/construct_runtime/mod.rs   |   2 +-
 .../procedural/src/construct_runtime/parse.rs |  31 ++---
 .../procedural/src/default_no_bound.rs        |   4 +-
 .../procedural/src/pallet/expand/call.rs      |  10 +-
 .../procedural/src/pallet/expand/constants.rs |   2 +-
 .../src/pallet/expand/documentation.rs        | 119 ++++++------------
 .../procedural/src/pallet/expand/storage.rs   |  25 ++--
 .../procedural/src/pallet/parse/call.rs       |   6 +-
 .../procedural/src/pallet/parse/composite.rs  |  25 ++--
 .../procedural/src/pallet/parse/config.rs     |  36 ++++--
 .../procedural/src/pallet/parse/error.rs      |   2 +-
 .../src/pallet/parse/extra_constants.rs       |   4 +-
 .../procedural/src/pallet/parse/helper.rs     |   9 +-
 .../procedural/src/pallet/parse/hooks.rs      |   2 +-
 .../procedural/src/pallet/parse/storage.rs    |  12 +-
 .../procedural/src/pallet/parse/type_value.rs |   6 +-
 .../support/procedural/src/pallet_error.rs    |  79 +++++-------
 .../genesis_config/genesis_config_def.rs      |   7 +-
 .../support/procedural/src/storage/mod.rs     |   4 +-
 .../src/storage/print_pallet_upgrade.rs       |  14 +--
 .../frame/support/procedural/tools/Cargo.toml |   6 +-
 .../procedural/tools/derive/Cargo.toml        |   6 +-
 .../frame/support/procedural/tools/src/lib.rs |  13 +-
 .../pallet_ui/pallet_doc_arg_non_path.stderr  |   2 +-
 .../tests/pallet_ui/pallet_doc_empty.stderr   |   2 +-
 .../pallet_ui/pallet_doc_invalid_arg.stderr   |   2 +-
 .../pallet_ui/pallet_doc_multiple_args.stderr |   2 +-
 ...result_query_parenthesized_generics.stderr |   4 +-
 .../primitives/api/proc-macro/Cargo.toml      |   6 +-
 .../api/proc-macro/src/decl_runtime_apis.rs   |  91 ++++++--------
 .../api/proc-macro/src/impl_runtime_apis.rs   |   6 +-
 .../proc-macro/src/mock_impl_runtime_apis.rs  |   8 +-
 .../api/proc-macro/src/runtime_metadata.rs    |   4 +-
 .../primitives/api/proc-macro/src/utils.rs    |  14 ++-
 .../primitives/arithmetic/src/per_things.rs   |  10 +-
 .../core/hashing/proc-macro/Cargo.toml        |   6 +-
 substrate/primitives/debug-derive/Cargo.toml  |   6 +-
 .../runtime-interface/proc-macro/Cargo.toml   |   6 +-
 .../bare_function_interface.rs                |  15 ++-
 .../host_function_interface.rs                |   6 +-
 .../src/runtime_interface/trait_decl_impl.rs  |  18 +--
 .../runtime-interface/proc-macro/src/utils.rs |  26 ++--
 .../primitives/version/proc-macro/Cargo.toml  |   6 +-
 substrate/test-utils/derive/Cargo.toml        |   6 +-
 62 files changed, 409 insertions(+), 485 deletions(-)

diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index 6a1f29aa28e..b0a96af545b 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -2351,7 +2351,7 @@ dependencies = [
  "quote",
  "scale-info",
  "sp-arithmetic",
- "syn 1.0.109",
+ "syn 2.0.14",
  "trybuild",
 ]
 
@@ -2489,7 +2489,7 @@ dependencies = [
  "proc-macro-warning",
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -2500,7 +2500,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -2509,7 +2509,7 @@ version = "3.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -2724,7 +2724,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.13",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -5912,7 +5912,7 @@ version = "4.0.0-dev"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -6795,7 +6795,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "sp-runtime",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -8401,7 +8401,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -9630,7 +9630,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -10181,7 +10181,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -10490,7 +10490,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "sp-core-hashing",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -10507,7 +10507,7 @@ version = "5.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -10737,7 +10737,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -10962,7 +10962,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "sp-version",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -11388,7 +11388,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.14",
 ]
 
 [[package]]
@@ -11444,9 +11444,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.13"
+version = "2.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec"
+checksum = "fcf316d5356ed6847742d036f8a39c3b8435cac10bd528a4bd461928a6ab34d5"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -11705,7 +11705,7 @@ checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.13",
+ "syn 2.0.14",
 ]
 
 [[package]]
diff --git a/substrate/bin/node/cli/tests/telemetry.rs b/substrate/bin/node/cli/tests/telemetry.rs
index f6e46775a22..176d2e81ad0 100644
--- a/substrate/bin/node/cli/tests/telemetry.rs
+++ b/substrate/bin/node/cli/tests/telemetry.rs
@@ -57,8 +57,9 @@ async fn telemetry_works() {
 						}
 					},
 
-					Event::TextFrame { .. } =>
-						panic!("Got a TextFrame over the socket, this is a bug"),
+					Event::TextFrame { .. } => {
+						panic!("Got a TextFrame over the socket, this is a bug")
+					},
 
 					// Connection has been closed.
 					Event::ConnectionError { .. } => {},
diff --git a/substrate/client/chain-spec/derive/Cargo.toml b/substrate/client/chain-spec/derive/Cargo.toml
index d733bda9b16..c16cd45a994 100644
--- a/substrate/client/chain-spec/derive/Cargo.toml
+++ b/substrate/client/chain-spec/derive/Cargo.toml
@@ -16,6 +16,6 @@ proc-macro = true
 
 [dependencies]
 proc-macro-crate = "1.1.3"
-proc-macro2 = "1.0.37"
-quote = "1.0.10"
-syn = "1.0.98"
+proc-macro2 = "1.0.56"
+quote = "1.0.26"
+syn = "2.0.14"
diff --git a/substrate/client/chain-spec/derive/src/impls.rs b/substrate/client/chain-spec/derive/src/impls.rs
index e54c1895e4a..c0624897c13 100644
--- a/substrate/client/chain-spec/derive/src/impls.rs
+++ b/substrate/client/chain-spec/derive/src/impls.rs
@@ -35,7 +35,7 @@ pub fn extension_derive(ast: &DeriveInput) -> proc_macro::TokenStream {
 			.named
 			.iter()
 			.find_map(|f| {
-				if f.attrs.iter().any(|attr| attr.path.is_ident(ATTRIBUTE_NAME)) {
+				if f.attrs.iter().any(|attr| attr.path().is_ident(ATTRIBUTE_NAME)) {
 					let typ = &f.ty;
 					Some(quote! { #typ })
 				} else {
diff --git a/substrate/client/consensus/babe/src/lib.rs b/substrate/client/consensus/babe/src/lib.rs
index a59870ced06..e540cae1f7e 100644
--- a/substrate/client/consensus/babe/src/lib.rs
+++ b/substrate/client/consensus/babe/src/lib.rs
@@ -556,8 +556,9 @@ fn aux_storage_cleanup<C: HeaderMetadata<Block> + HeaderBackend<Block>, Block: B
 		Ok(meta) => {
 			hashes.insert(meta.parent);
 		},
-		Err(err) =>
-			warn!(target: LOG_TARGET, "Failed to lookup metadata for block `{:?}`: {}", first, err,),
+		Err(err) => {
+			warn!(target: LOG_TARGET, "Failed to lookup metadata for block `{:?}`: {}", first, err,)
+		},
 	}
 
 	// Cleans data for finalized block's ancestors
diff --git a/substrate/client/db/src/pinned_blocks_cache.rs b/substrate/client/db/src/pinned_blocks_cache.rs
index f50a7081df6..7b346b4631e 100644
--- a/substrate/client/db/src/pinned_blocks_cache.rs
+++ b/substrate/client/db/src/pinned_blocks_cache.rs
@@ -149,8 +149,9 @@ impl<Block: BlockT> PinnedBlocksCache<Block> {
 					self.cache.len()
 				);
 			},
-			None =>
-				log::warn!(target: LOG_TARGET, "Unable to bump reference count. hash = {}", hash),
+			None => {
+				log::warn!(target: LOG_TARGET, "Unable to bump reference count. hash = {}", hash)
+			},
 		};
 	}
 
diff --git a/substrate/client/service/test/src/client/mod.rs b/substrate/client/service/test/src/client/mod.rs
index 1b282a342d5..520a9b52fea 100644
--- a/substrate/client/service/test/src/client/mod.rs
+++ b/substrate/client/service/test/src/client/mod.rs
@@ -158,8 +158,9 @@ fn finality_notification_check(
 			assert_eq!(notif.hash, *finalized.last().unwrap());
 			assert_eq!(stale_heads, stale_heads_expected);
 		},
-		Err(TryRecvError::Closed) =>
-			panic!("unexpected notification result, client send channel was closed"),
+		Err(TryRecvError::Closed) => {
+			panic!("unexpected notification result, client send channel was closed")
+		},
 		Err(TryRecvError::Empty) => assert!(finalized.is_empty()),
 	}
 }
diff --git a/substrate/client/state-db/src/lib.rs b/substrate/client/state-db/src/lib.rs
index b41240d629b..c656f126ae6 100644
--- a/substrate/client/state-db/src/lib.rs
+++ b/substrate/client/state-db/src/lib.rs
@@ -187,12 +187,14 @@ impl fmt::Debug for StateDbError {
 				"Incompatible pruning modes [stored: {:?}; requested: {:?}]",
 				stored, requested
 			),
-			Self::TooManySiblingBlocks { number } =>
-				write!(f, "Too many sibling blocks at #{number} inserted"),
+			Self::TooManySiblingBlocks { number } => {
+				write!(f, "Too many sibling blocks at #{number} inserted")
+			},
 			Self::BlockAlreadyExists => write!(f, "Block already exists"),
 			Self::Metadata(message) => write!(f, "Invalid metadata: {}", message),
-			Self::BlockUnavailable =>
-				write!(f, "Trying to get a block record from db while it is not commit to db yet"),
+			Self::BlockUnavailable => {
+				write!(f, "Trying to get a block record from db while it is not commit to db yet")
+			},
 			Self::BlockMissing => write!(f, "Block record is missing from the pruning window"),
 		}
 	}
diff --git a/substrate/client/tracing/proc-macro/Cargo.toml b/substrate/client/tracing/proc-macro/Cargo.toml
index 031f1fe49d9..54078fe1f2c 100644
--- a/substrate/client/tracing/proc-macro/Cargo.toml
+++ b/substrate/client/tracing/proc-macro/Cargo.toml
@@ -16,6 +16,6 @@ proc-macro = true
 
 [dependencies]
 proc-macro-crate = "1.1.3"
-proc-macro2 = "1.0.37"
-quote = { version = "1.0.10", features = ["proc-macro"] }
-syn = { version = "1.0.98", features = ["proc-macro", "full", "extra-traits", "parsing"] }
+proc-macro2 = "1.0.56"
+quote = { version = "1.0.26", features = ["proc-macro"] }
+syn = { version = "2.0.14", features = ["proc-macro", "full", "extra-traits", "parsing"] }
diff --git a/substrate/frame/contracts/proc-macro/Cargo.toml b/substrate/frame/contracts/proc-macro/Cargo.toml
index 08dafcc6a8f..c700d1e3356 100644
--- a/substrate/frame/contracts/proc-macro/Cargo.toml
+++ b/substrate/frame/contracts/proc-macro/Cargo.toml
@@ -15,9 +15,9 @@ targets = ["x86_64-unknown-linux-gnu"]
 proc-macro = true
 
 [dependencies]
-proc-macro2 = "1"
-quote = "1"
-syn = { version = "1.0.98", features = ["full"] }
+proc-macro2 = "1.0.56"
+quote = "1.0.26"
+syn = { version = "2.0.14", features = ["full"] }
 
 [dev-dependencies]
 
diff --git a/substrate/frame/contracts/proc-macro/src/lib.rs b/substrate/frame/contracts/proc-macro/src/lib.rs
index d54470dd06f..a6a8187bc8a 100644
--- a/substrate/frame/contracts/proc-macro/src/lib.rs
+++ b/substrate/frame/contracts/proc-macro/src/lib.rs
@@ -209,13 +209,13 @@ impl HostFn {
 			"only #[version(<u8>)], #[unstable], #[prefixed_alias] and #[deprecated] attributes are allowed.";
 		let span = item.span();
 		let mut attrs = item.attrs.clone();
-		attrs.retain(|a| !a.path.is_ident("doc"));
+		attrs.retain(|a| !a.path().is_ident("doc"));
 		let mut maybe_version = None;
 		let mut is_stable = true;
 		let mut alias_to = None;
 		let mut not_deprecated = true;
 		while let Some(attr) = attrs.pop() {
-			let ident = attr.path.get_ident().ok_or(err(span, msg))?.to_string();
+			let ident = attr.path().get_ident().ok_or(err(span, msg))?.to_string();
 			match ident.as_str() {
 				"version" => {
 					if maybe_version.is_some() {
@@ -377,7 +377,7 @@ impl EnvDef {
 			_ => None,
 		};
 
-		let selector = |a: &syn::Attribute| a.path.is_ident("prefixed_alias");
+		let selector = |a: &syn::Attribute| a.path().is_ident("prefixed_alias");
 
 		let aliases = items
 			.iter()
@@ -401,7 +401,7 @@ impl EnvDef {
 }
 
 fn is_valid_special_arg(idx: usize, arg: &FnArg) -> bool {
-	let pat = if let FnArg::Typed(pat) = arg { pat } else { return false };
+	let FnArg::Typed(pat) = arg else { return false };
 	let ident = if let syn::Pat::Ident(ref ident) = *pat.pat { &ident.ident } else { return false };
 	let name_ok = match idx {
 		0 => ident == "ctx" || ident == "_ctx",
@@ -434,7 +434,7 @@ fn expand_func_doc(func: &HostFn) -> TokenStream2 {
 			);
 			quote! { #[doc = #alias_doc] }
 		} else {
-			let docs = func.item.attrs.iter().filter(|a| a.path.is_ident("doc")).map(|d| {
+			let docs = func.item.attrs.iter().filter(|a| a.path().is_ident("doc")).map(|d| {
 				let docs = d.to_token_stream();
 				quote! { #docs }
 			});
diff --git a/substrate/frame/election-provider-support/solution-type/Cargo.toml b/substrate/frame/election-provider-support/solution-type/Cargo.toml
index eb9598dca20..95ad6f22666 100644
--- a/substrate/frame/election-provider-support/solution-type/Cargo.toml
+++ b/substrate/frame/election-provider-support/solution-type/Cargo.toml
@@ -15,9 +15,9 @@ targets = ["x86_64-unknown-linux-gnu"]
 proc-macro = true
 
 [dependencies]
-syn = { version = "1.0.98", features = ["full", "visit"] }
-quote = "1.0"
-proc-macro2 = "1.0.37"
+syn = { version = "2.0.14", features = ["full", "visit"] }
+quote = "1.0.26"
+proc-macro2 = "1.0.56"
 proc-macro-crate = "1.1.3"
 
 [dev-dependencies]
diff --git a/substrate/frame/election-provider-support/solution-type/src/lib.rs b/substrate/frame/election-provider-support/solution-type/src/lib.rs
index f79554321d5..6938953071a 100644
--- a/substrate/frame/election-provider-support/solution-type/src/lib.rs
+++ b/substrate/frame/election-provider-support/solution-type/src/lib.rs
@@ -161,7 +161,7 @@ fn check_attributes(input: ParseStream) -> syn::Result<bool> {
 		return Ok(false)
 	}
 	let attr = attrs.pop().expect("attributes vec with len 1 can be popped.");
-	if attr.path.is_ident("compact") {
+	if attr.path().is_ident("compact") {
 		Ok(true)
 	} else {
 		Err(syn::Error::new_spanned(attr, "compact solution can accept only #[compact]"))
@@ -200,7 +200,7 @@ impl Parse for SolutionDef {
 						format!("Expected binding: `{} = ...`", expected),
 					))
 				},
-				syn::GenericArgument::Binding(syn::Binding { ident, ty, .. }) => {
+				syn::GenericArgument::AssocType(syn::AssocType { ident, ty, .. }) => {
 					// check that we have the right keyword for this position in the argument list
 					if ident == expected {
 						Ok(ty.clone())
diff --git a/substrate/frame/nfts/src/tests.rs b/substrate/frame/nfts/src/tests.rs
index 0fc6fcd15c4..d36f8b54e2b 100644
--- a/substrate/frame/nfts/src/tests.rs
+++ b/substrate/frame/nfts/src/tests.rs
@@ -2700,7 +2700,11 @@ fn claim_swap_should_work() {
 		Balances::make_free_balance_be(&user_1, initial_balance);
 		Balances::make_free_balance_be(&user_2, initial_balance);
 
-		assert_ok!(Nfts::force_create(RuntimeOrigin::root(), user_1.clone(), default_collection_config()));
+		assert_ok!(Nfts::force_create(
+			RuntimeOrigin::root(),
+			user_1.clone(),
+			default_collection_config()
+		));
 
 		assert_ok!(Nfts::mint(
 			RuntimeOrigin::signed(user_1.clone()),
diff --git a/substrate/frame/scheduler/src/migration.rs b/substrate/frame/scheduler/src/migration.rs
index e641d2895aa..5b3a7631eea 100644
--- a/substrate/frame/scheduler/src/migration.rs
+++ b/substrate/frame/scheduler/src/migration.rs
@@ -297,8 +297,9 @@ pub mod v4 {
 					target: TARGET,
 					"Did not clean up any agendas. v4::CleanupAgendas can be removed."
 				),
-				Some(n) =>
-					log::info!(target: TARGET, "Cleaned up {} agendas, now {}", n, new_agendas),
+				Some(n) => {
+					log::info!(target: TARGET, "Cleaned up {} agendas, now {}", n, new_agendas)
+				},
 				None => unreachable!(
 					"Number of agendas cannot increase, old {} new {}",
 					old_agendas, new_agendas
@@ -560,8 +561,9 @@ mod test {
 						"Agenda {} should be removed",
 						i
 					),
-					Some(new) =>
-						assert_eq!(Agenda::<Test>::get(i as u64), new, "Agenda wrong {}", i),
+					Some(new) => {
+						assert_eq!(Agenda::<Test>::get(i as u64), new, "Agenda wrong {}", i)
+					},
 				}
 			}
 		});
diff --git a/substrate/frame/staking/reward-curve/Cargo.toml b/substrate/frame/staking/reward-curve/Cargo.toml
index c761517ea68..4a97d20a5f0 100644
--- a/substrate/frame/staking/reward-curve/Cargo.toml
+++ b/substrate/frame/staking/reward-curve/Cargo.toml
@@ -16,9 +16,9 @@ proc-macro = true
 
 [dependencies]
 proc-macro-crate = "1.1.3"
-proc-macro2 = "1.0.37"
-quote = "1.0.10"
-syn = { version = "1.0.98", features = ["full", "visit"] }
+proc-macro2 = "1.0.56"
+quote = "1.0.26"
+syn = { version = "2.0.14", features = ["full", "visit"] }
 
 [dev-dependencies]
 sp-runtime = { version = "7.0.0", path = "../../../primitives/runtime" }
diff --git a/substrate/frame/support/procedural/Cargo.toml b/substrate/frame/support/procedural/Cargo.toml
index 6dbdd3b3a59..d57b81a3444 100644
--- a/substrate/frame/support/procedural/Cargo.toml
+++ b/substrate/frame/support/procedural/Cargo.toml
@@ -19,9 +19,9 @@ derive-syn-parse = "0.1.5"
 Inflector = "0.11.4"
 cfg-expr = "0.10.3"
 itertools = "0.10.3"
-proc-macro2 = "1.0.37"
-quote = "1.0.10"
-syn = { version = "1.0.98", features = ["full"] }
+proc-macro2 = "1.0.56"
+quote = "1.0.26"
+syn = { version = "2.0.14", features = ["full"] }
 frame-support-procedural-tools = { version = "4.0.0-dev", path = "./tools" }
 proc-macro-warning = { version = "0.2.0", default-features = false }
 
diff --git a/substrate/frame/support/procedural/src/benchmark.rs b/substrate/frame/support/procedural/src/benchmark.rs
index 4f9994b6cd0..cf091e7cb0c 100644
--- a/substrate/frame/support/procedural/src/benchmark.rs
+++ b/substrate/frame/support/procedural/src/benchmark.rs
@@ -21,14 +21,13 @@ use derive_syn_parse::Parse;
 use frame_support_procedural_tools::generate_crate_access_2018;
 use proc_macro::TokenStream;
 use proc_macro2::{Ident, Span, TokenStream as TokenStream2};
-use quote::{quote, quote_spanned, ToTokens};
+use quote::{quote, ToTokens};
 use syn::{
-	parenthesized,
 	parse::{Nothing, ParseStream},
 	parse_quote,
 	punctuated::Punctuated,
 	spanned::Spanned,
-	token::{Colon2, Comma, Gt, Lt, Paren},
+	token::{Comma, Gt, Lt, PathSep},
 	Attribute, Error, Expr, ExprBlock, ExprCall, ExprPath, FnArg, Item, ItemFn, ItemMod, LitInt,
 	Pat, Path, PathArguments, PathSegment, Result, ReturnType, Signature, Stmt, Token, Type,
 	TypePath, Visibility, WhereClause,
@@ -45,6 +44,9 @@ mod keywords {
 	custom_keyword!(skip_meta);
 	custom_keyword!(BenchmarkError);
 	custom_keyword!(Result);
+
+	pub const BENCHMARK_TOKEN: &str = stringify!(benchmark);
+	pub const BENCHMARKS_TOKEN: &str = stringify!(benchmarks);
 }
 
 /// This represents the raw parsed data for a param definition such as `x: Linear<10, 20>`.
@@ -95,27 +97,20 @@ impl syn::parse::Parse for BenchmarkAttrKeyword {
 
 impl syn::parse::Parse for BenchmarkAttrs {
 	fn parse(input: ParseStream) -> syn::Result<Self> {
-		let lookahead = input.lookahead1();
-		if !lookahead.peek(Paren) {
-			let _nothing: Nothing = input.parse()?;
-			return Ok(BenchmarkAttrs { skip_meta: false, extra: false })
-		}
-		let content;
-		let _paren: Paren = parenthesized!(content in input);
 		let mut extra = false;
 		let mut skip_meta = false;
-		let args = Punctuated::<BenchmarkAttrKeyword, Token![,]>::parse_terminated(&content)?;
+		let args = Punctuated::<BenchmarkAttrKeyword, Token![,]>::parse_terminated(&input)?;
 		for arg in args.into_iter() {
 			match arg {
 				BenchmarkAttrKeyword::Extra => {
 					if extra {
-						return Err(content.error("`extra` can only be specified once"))
+						return Err(input.error("`extra` can only be specified once"))
 					}
 					extra = true;
 				},
 				BenchmarkAttrKeyword::SkipMeta => {
 					if skip_meta {
-						return Err(content.error("`skip_meta` can only be specified once"))
+						return Err(input.error("`skip_meta` can only be specified once"))
 					}
 					skip_meta = true;
 				},
@@ -150,8 +145,6 @@ struct BenchmarkDef {
 	call_def: BenchmarkCallDef,
 	verify_stmts: Vec<Stmt>,
 	last_stmt: Option<Stmt>,
-	extra: bool,
-	skip_meta: bool,
 	fn_sig: Signature,
 	fn_vis: Visibility,
 	fn_attrs: Vec<Attribute>,
@@ -218,7 +211,7 @@ fn parse_params(item_fn: &ItemFn) -> Result<Vec<ParamDef>> {
 			return Err(Error::new(
 					var_span,
 					"Benchmark parameter names must consist of a single lowercase letter (a-z) and no other characters.",
-				))
+				));
 		};
 		let name = ident.ident.to_token_stream().to_string();
 		if name.len() > 1 {
@@ -253,9 +246,9 @@ fn parse_params(item_fn: &ItemFn) -> Result<Vec<ParamDef>> {
 /// Used in several places where the `#[extrinsic_call]` or `#[body]` annotation is missing
 fn missing_call<T>(item_fn: &ItemFn) -> Result<T> {
 	return Err(Error::new(
-		item_fn.block.brace_token.span,
+		item_fn.block.brace_token.span.join(),
 		"No valid #[extrinsic_call] or #[block] annotation could be found in benchmark function body."
-	))
+	));
 }
 
 /// Finds the `BenchmarkCallDef` and its index (within the list of stmts for the fn) and
@@ -264,10 +257,10 @@ fn missing_call<T>(item_fn: &ItemFn) -> Result<T> {
 fn parse_call_def(item_fn: &ItemFn) -> Result<(usize, BenchmarkCallDef)> {
 	// #[extrinsic_call] / #[block] handling
 	let call_defs = item_fn.block.stmts.iter().enumerate().filter_map(|(i, child)| {
-			if let Stmt::Semi(Expr::Call(expr_call), _semi) = child {
+			if let Stmt::Expr(Expr::Call(expr_call), _semi) = child {
 				// #[extrinsic_call] case
 				expr_call.attrs.iter().enumerate().find_map(|(k, attr)| {
-					let segment = attr.path.segments.last()?;
+					let segment = attr.path().segments.last()?;
 					let _: keywords::extrinsic_call = syn::parse(segment.ident.to_token_stream().into()).ok()?;
 					let mut expr_call = expr_call.clone();
 
@@ -281,10 +274,10 @@ fn parse_call_def(item_fn: &ItemFn) -> Result<(usize, BenchmarkCallDef)> {
 
 					Some(Ok((i, BenchmarkCallDef::ExtrinsicCall { origin, expr_call, attr_span: attr.span() })))
 				})
-			} else if let Stmt::Expr(Expr::Block(block)) = child {
+			} else if let Stmt::Expr(Expr::Block(block), _) = child {
 				// #[block] case
 				block.attrs.iter().enumerate().find_map(|(k, attr)| {
-					let segment = attr.path.segments.last()?;
+					let segment = attr.path().segments.last()?;
 					let _: keywords::block = syn::parse(segment.ident.to_token_stream().into()).ok()?;
 					let mut block = block.clone();
 
@@ -310,7 +303,7 @@ fn parse_call_def(item_fn: &ItemFn) -> Result<(usize, BenchmarkCallDef)> {
 
 impl BenchmarkDef {
 	/// Constructs a [`BenchmarkDef`] by traversing an existing [`ItemFn`] node.
-	pub fn from(item_fn: &ItemFn, extra: bool, skip_meta: bool) -> Result<BenchmarkDef> {
+	pub fn from(item_fn: &ItemFn) -> Result<BenchmarkDef> {
 		let params = parse_params(item_fn)?;
 		ensure_valid_return_type(item_fn)?;
 		let (i, call_def) = parse_call_def(&item_fn)?;
@@ -346,8 +339,6 @@ impl BenchmarkDef {
 			call_def,
 			verify_stmts,
 			last_stmt,
-			extra,
-			skip_meta,
 			fn_sig: item_fn.sig.clone(),
 			fn_vis: item_fn.vis.clone(),
 			fn_attrs: item_fn.attrs.clone(),
@@ -375,7 +366,7 @@ pub fn benchmarks(
 	let mod_attrs: Vec<&Attribute> = module
 		.attrs
 		.iter()
-		.filter(|attr| syn::parse2::<keywords::benchmarks>(attr.to_token_stream()).is_err())
+		.filter(|attr| !attr.path().is_ident(keywords::BENCHMARKS_TOKEN))
 		.collect();
 
 	let mut benchmark_names: Vec<Ident> = Vec::new();
@@ -391,35 +382,32 @@ pub fn benchmarks(
 		let Item::Fn(func) = stmt else { return None };
 
 		// find #[benchmark] attribute on function def
-		let benchmark_attr = func.attrs.iter().find_map(|attr| {
-			let seg = attr.path.segments.last()?;
-			syn::parse::<keywords::benchmark>(seg.ident.to_token_stream().into()).ok()?;
-			Some(attr)
-		})?;
+		let benchmark_attr =
+			func.attrs.iter().find(|attr| attr.path().is_ident(keywords::BENCHMARK_TOKEN))?;
 
 		Some((benchmark_attr.clone(), func.clone(), stmt))
 	});
 
 	// parse individual benchmark defs and args
 	for (benchmark_attr, func, stmt) in benchmark_fn_metas {
-		// parse any args provided to #[benchmark]
-		let attr_tokens = benchmark_attr.tokens.to_token_stream().into();
-		let benchmark_args: BenchmarkAttrs = syn::parse(attr_tokens)?;
-
 		// parse benchmark def
-		let benchmark_def =
-			BenchmarkDef::from(&func, benchmark_args.extra, benchmark_args.skip_meta)?;
+		let benchmark_def = BenchmarkDef::from(&func)?;
 
 		// record benchmark name
 		let name = &func.sig.ident;
 		benchmark_names.push(name.clone());
 
-		// record name sets
-		if benchmark_def.extra {
-			extra_benchmark_names.push(name.clone());
-		}
-		if benchmark_def.skip_meta {
-			skip_meta_benchmark_names.push(name.clone())
+		// Check if we need to parse any args
+		if benchmark_attr.meta.require_path_only().is_err() {
+			// parse any args provided to #[benchmark]
+			let benchmark_attrs: BenchmarkAttrs = benchmark_attr.parse_args()?;
+
+			// record name sets
+			if benchmark_attrs.extra {
+				extra_benchmark_names.push(name.clone());
+			} else if benchmark_attrs.skip_meta {
+				skip_meta_benchmark_names.push(name.clone());
+			}
 		}
 
 		// expand benchmark
@@ -787,7 +775,8 @@ fn expand_benchmark(
 			// determine call name (handles `_` and normal call syntax)
 			let expr_span = expr_call.span();
 			let call_err = || {
-				quote_spanned!(expr_span=> "Extrinsic call must be a function call or `_`".to_compile_error()).into()
+				syn::Error::new(expr_span, "Extrinsic call must be a function call or `_`")
+					.to_compile_error()
 			};
 			let call_name = match *expr_call.func {
 				Expr::Path(expr_path) => {
@@ -795,10 +784,9 @@ fn expand_benchmark(
 					let Some(segment) = expr_path.path.segments.last() else { return call_err(); };
 					segment.ident.to_string()
 				},
-				Expr::Verbatim(tokens) => {
+				Expr::Infer(_) => {
 					// `_` style
 					// replace `_` with fn name
-					let Ok(_) = syn::parse::<Token![_]>(tokens.to_token_stream().into()) else { return call_err(); };
 					name.to_string()
 				},
 				_ => return call_err(),
@@ -806,7 +794,7 @@ fn expand_benchmark(
 
 			// modify extrinsic call to be prefixed with "new_call_variant"
 			let call_name = format!("new_call_variant_{}", call_name);
-			let mut punct: Punctuated<PathSegment, Colon2> = Punctuated::new();
+			let mut punct: Punctuated<PathSegment, PathSep> = Punctuated::new();
 			punct.push(PathSegment {
 				arguments: PathArguments::None,
 				ident: Ident::new(call_name.as_str(), Span::call_site()),
@@ -847,11 +835,10 @@ fn expand_benchmark(
 	let vis = benchmark_def.fn_vis;
 
 	// remove #[benchmark] attribute
-	let fn_attrs: Vec<&Attribute> = benchmark_def
+	let fn_attrs = benchmark_def
 		.fn_attrs
 		.iter()
-		.filter(|attr| !syn::parse2::<keywords::benchmark>(attr.path.to_token_stream()).is_ok())
-		.collect();
+		.filter(|attr| !attr.path().is_ident(keywords::BENCHMARK_TOKEN));
 
 	// modify signature generics, ident, and inputs, e.g:
 	// before: `fn bench(u: Linear<1, 100>) -> Result<(), BenchmarkError>`
@@ -874,10 +861,11 @@ fn expand_benchmark(
 		Some(stmt) => quote!(#stmt),
 		None => quote!(Ok(())),
 	};
+	let fn_attrs_clone = fn_attrs.clone();
 
 	let fn_def = quote! {
 		#(
-			#fn_attrs
+			#fn_attrs_clone
 		)*
 		#vis #sig {
 			#(
diff --git a/substrate/frame/support/procedural/src/construct_runtime/mod.rs b/substrate/frame/support/procedural/src/construct_runtime/mod.rs
index c5a48a98063..1af44fc00a0 100644
--- a/substrate/frame/support/procedural/src/construct_runtime/mod.rs
+++ b/substrate/frame/support/procedural/src/construct_runtime/mod.rs
@@ -224,7 +224,7 @@ fn construct_runtime_final_expansion(
 	let system_pallet =
 		pallets.iter().find(|decl| decl.name == SYSTEM_PALLET_NAME).ok_or_else(|| {
 			syn::Error::new(
-				pallets_token.span,
+				pallets_token.span.join(),
 				"`System` pallet declaration is missing. \
 			 Please add this line: `System: frame_system::{Pallet, Call, Storage, Config, Event<T>},`",
 			)
diff --git a/substrate/frame/support/procedural/src/construct_runtime/parse.rs b/substrate/frame/support/procedural/src/construct_runtime/parse.rs
index 5e6979f1d2b..f819a90d1b5 100644
--- a/substrate/frame/support/procedural/src/construct_runtime/parse.rs
+++ b/substrate/frame/support/procedural/src/construct_runtime/parse.rs
@@ -17,6 +17,7 @@
 
 use frame_support_procedural_tools::syn_ext as ext;
 use proc_macro2::{Span, TokenStream};
+use quote::ToTokens;
 use std::collections::{HashMap, HashSet};
 use syn::{
 	ext::IdentExt,
@@ -444,21 +445,21 @@ impl PalletPartKeyword {
 	}
 }
 
-impl Spanned for PalletPartKeyword {
-	fn span(&self) -> Span {
+impl ToTokens for PalletPartKeyword {
+	fn to_tokens(&self, tokens: &mut TokenStream) {
 		match self {
-			Self::Pallet(inner) => inner.span(),
-			Self::Call(inner) => inner.span(),
-			Self::Storage(inner) => inner.span(),
-			Self::Event(inner) => inner.span(),
-			Self::Config(inner) => inner.span(),
-			Self::Origin(inner) => inner.span(),
-			Self::Inherent(inner) => inner.span(),
-			Self::ValidateUnsigned(inner) => inner.span(),
-			Self::FreezeReason(inner) => inner.span(),
-			Self::HoldReason(inner) => inner.span(),
-			Self::LockId(inner) => inner.span(),
-			Self::SlashReason(inner) => inner.span(),
+			Self::Pallet(inner) => inner.to_tokens(tokens),
+			Self::Call(inner) => inner.to_tokens(tokens),
+			Self::Storage(inner) => inner.to_tokens(tokens),
+			Self::Event(inner) => inner.to_tokens(tokens),
+			Self::Config(inner) => inner.to_tokens(tokens),
+			Self::Origin(inner) => inner.to_tokens(tokens),
+			Self::Inherent(inner) => inner.to_tokens(tokens),
+			Self::ValidateUnsigned(inner) => inner.to_tokens(tokens),
+			Self::FreezeReason(inner) => inner.to_tokens(tokens),
+			Self::HoldReason(inner) => inner.to_tokens(tokens),
+			Self::LockId(inner) => inner.to_tokens(tokens),
+			Self::SlashReason(inner) => inner.to_tokens(tokens),
 		}
 	}
 }
@@ -681,7 +682,7 @@ fn convert_pallets(pallets: Vec<PalletDeclaration>) -> syn::Result<PalletsConver
 				.attrs
 				.iter()
 				.map(|attr| {
-					if attr.path.segments.len() != 1 || attr.path.segments[0].ident != "cfg" {
+					if attr.path().segments.first().map_or(false, |s| s.ident != "cfg") {
 						let msg = "Unsupported attribute, only #[cfg] is supported on pallet \
 						declarations in `construct_runtime`";
 						return Err(syn::Error::new(attr.span(), msg))
diff --git a/substrate/frame/support/procedural/src/default_no_bound.rs b/substrate/frame/support/procedural/src/default_no_bound.rs
index 127b490878d..da05f19e0f8 100644
--- a/substrate/frame/support/procedural/src/default_no_bound.rs
+++ b/substrate/frame/support/procedural/src/default_no_bound.rs
@@ -62,7 +62,7 @@ pub fn derive_default_no_bound(input: proc_macro::TokenStream) -> proc_macro::To
 			let default_variants = enum_
 				.variants
 				.into_iter()
-				.filter(|variant| variant.attrs.iter().any(|attr| attr.path.is_ident("default")))
+				.filter(|variant| variant.attrs.iter().any(|attr| attr.path().is_ident("default")))
 				.collect::<Vec<_>>();
 
 			match &*default_variants {
@@ -80,7 +80,7 @@ pub fn derive_default_no_bound(input: proc_macro::TokenStream) -> proc_macro::To
 					let variant_attrs = default_variant
 						.attrs
 						.iter()
-						.filter(|a| a.path.is_ident("default"))
+						.filter(|a| a.path().is_ident("default"))
 						.collect::<Vec<_>>();
 
 					// check that there is only one #[default] attribute on the variant
diff --git a/substrate/frame/support/procedural/src/pallet/expand/call.rs b/substrate/frame/support/procedural/src/pallet/expand/call.rs
index 74075848d9e..aa5af9d5488 100644
--- a/substrate/frame/support/procedural/src/pallet/expand/call.rs
+++ b/substrate/frame/support/procedural/src/pallet/expand/call.rs
@@ -188,7 +188,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
 		.map(|c| &mut def.item.content.as_mut().expect("Checked by def parser").1[c.index])
 	{
 		item_impl.items.iter_mut().for_each(|i| {
-			if let syn::ImplItem::Method(method) = i {
+			if let syn::ImplItem::Fn(method) = i {
 				let block = &method.block;
 				method.block = syn::parse_quote! {{
 					// We execute all dispatchable in a new storage layer, allowing them
@@ -206,13 +206,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
 			method
 				.attrs
 				.iter()
-				.find(|attr| {
-					if let Ok(syn::Meta::List(syn::MetaList { path, .. })) = attr.parse_meta() {
-						path.segments.last().map(|seg| seg.ident == "allow").unwrap_or(false)
-					} else {
-						false
-					}
-				})
+				.find(|attr| attr.path().is_ident("allow"))
 				.map_or(proc_macro2::TokenStream::new(), |attr| attr.to_token_stream())
 		})
 		.collect::<Vec<_>>();
diff --git a/substrate/frame/support/procedural/src/pallet/expand/constants.rs b/substrate/frame/support/procedural/src/pallet/expand/constants.rs
index 21fa492a75b..6e1cd3df627 100644
--- a/substrate/frame/support/procedural/src/pallet/expand/constants.rs
+++ b/substrate/frame/support/procedural/src/pallet/expand/constants.rs
@@ -23,7 +23,7 @@ struct ConstDef {
 	/// The type in Get, e.g. `u32` in `type Foo: Get<u32>;`, but `Self` is replaced by `T`
 	pub type_: syn::Type,
 	/// The doc associated
-	pub doc: Vec<syn::Lit>,
+	pub doc: Vec<syn::Expr>,
 	/// default_byte implementation
 	pub default_byte_impl: proc_macro2::TokenStream,
 	/// Constant name for Metadata (optional)
diff --git a/substrate/frame/support/procedural/src/pallet/expand/documentation.rs b/substrate/frame/support/procedural/src/pallet/expand/documentation.rs
index 1aa46cf5728..4e6347e83bb 100644
--- a/substrate/frame/support/procedural/src/pallet/expand/documentation.rs
+++ b/substrate/frame/support/procedural/src/pallet/expand/documentation.rs
@@ -16,54 +16,24 @@
 // limitations under the License.
 
 use crate::pallet::Def;
-use derive_syn_parse::Parse;
 use proc_macro2::TokenStream;
 use quote::ToTokens;
-use syn::{
-	parse::{self, Parse, ParseStream},
-	spanned::Spanned,
-	Attribute, Lit,
-};
+use syn::{spanned::Spanned, Attribute, Lit, LitStr};
 
 const DOC: &'static str = "doc";
 const PALLET_DOC: &'static str = "pallet_doc";
 
-mod keywords {
-	syn::custom_keyword!(include_str);
-}
-
 /// Get the documentation file path from the `pallet_doc` attribute.
 ///
 /// Supported format:
 /// `#[pallet_doc(PATH)]`: The path of the file from which the documentation is loaded
 fn parse_pallet_doc_value(attr: &Attribute) -> syn::Result<DocMetaValue> {
-	let span = attr.span();
-
-	let meta = attr.parse_meta()?;
-	let syn::Meta::List(metalist) = meta else {
-		let msg = "The `pallet_doc` attribute must receive arguments as a list. Supported format: `pallet_doc(PATH)`";
-		return Err(syn::Error::new(span, msg))
-	};
+	let lit: syn::LitStr = attr.parse_args().map_err(|_| {
+		let msg = "The `pallet_doc` received an unsupported argument. Supported format: `pallet_doc(\"PATH\")`";
+		syn::Error::new(attr.span(), msg)
+	})?;
 
-	let paths: Vec<_> = metalist
-		.nested
-		.into_iter()
-		.map(|nested| {
-			let syn::NestedMeta::Lit(lit) = nested else {
-				let msg = "The `pallet_doc` received an unsupported argument. Supported format: `pallet_doc(PATH)`";
-				return Err(syn::Error::new(span, msg))
-			};
-
-			Ok(lit)
-		})
-		.collect::<syn::Result<_>>()?;
-
-	if paths.len() != 1 {
-		let msg = "The `pallet_doc` attribute must receive only one argument. Supported format: `pallet_doc(PATH)`";
-		return Err(syn::Error::new(span, msg))
-	}
-
-	Ok(DocMetaValue::Path(paths[0].clone()))
+	Ok(DocMetaValue::Path(lit))
 }
 
 /// Get the value from the `doc` comment attribute:
@@ -71,47 +41,22 @@ fn parse_pallet_doc_value(attr: &Attribute) -> syn::Result<DocMetaValue> {
 /// Supported formats:
 /// - `#[doc = "A doc string"]`: Documentation as a string literal
 /// - `#[doc = include_str!(PATH)]`: Documentation obtained from a path
-fn parse_doc_value(attr: &Attribute) -> Option<DocMetaValue> {
-	let Some(ident) = attr.path.get_ident() else {
-		return None
-	};
-	if ident != DOC {
-		return None
+fn parse_doc_value(attr: &Attribute) -> syn::Result<Option<DocMetaValue>> {
+	if !attr.path().is_ident(DOC) {
+		return Ok(None)
 	}
 
-	let parser = |input: ParseStream| DocParser::parse(input);
-	let result = parse::Parser::parse2(parser, attr.tokens.clone()).ok()?;
+	let meta = attr.meta.require_name_value()?;
 
-	if let Some(lit) = result.lit {
-		Some(DocMetaValue::Lit(lit))
-	} else if let Some(include_doc) = result.include_doc {
-		Some(DocMetaValue::Path(include_doc.lit))
-	} else {
-		None
+	match &meta.value {
+		syn::Expr::Lit(lit) => Ok(Some(DocMetaValue::Lit(lit.lit.clone()))),
+		syn::Expr::Macro(mac) if mac.mac.path.is_ident("include_str") =>
+			Ok(Some(DocMetaValue::Path(mac.mac.parse_body()?))),
+		_ =>
+			Err(syn::Error::new(attr.span(), "Expected `= \"docs\"` or `= include_str!(\"PATH\")`")),
 	}
 }
 
-/// Parse the include_str attribute.
-#[derive(Debug, Parse)]
-struct IncludeDocParser {
-	_include_str: keywords::include_str,
-	_eq_token: syn::token::Bang,
-	#[paren]
-	_paren: syn::token::Paren,
-	#[inside(_paren)]
-	lit: Lit,
-}
-
-/// Parse the doc literal.
-#[derive(Debug, Parse)]
-struct DocParser {
-	_eq_token: syn::token::Eq,
-	#[peek(Lit)]
-	lit: Option<Lit>,
-	#[parse_if(lit.is_none())]
-	include_doc: Option<IncludeDocParser>,
-}
-
 /// Supported documentation tokens.
 #[derive(Debug)]
 enum DocMetaValue {
@@ -124,7 +69,7 @@ enum DocMetaValue {
 	/// The string literal represents the file `PATH`.
 	///
 	/// `#[doc = include_str!(PATH)]`
-	Path(Lit),
+	Path(LitStr),
 }
 
 impl ToTokens for DocMetaValue {
@@ -179,33 +124,39 @@ pub fn expand_documentation(def: &mut Def) -> proc_macro2::TokenStream {
 	let mut index = 0;
 	while index < def.item.attrs.len() {
 		let attr = &def.item.attrs[index];
-		if let Some(ident) = attr.path.get_ident() {
-			if ident == PALLET_DOC {
-				let elem = def.item.attrs.remove(index);
-				pallet_docs.push(elem);
-				// Do not increment the index, we have just removed the
-				// element from the attributes.
-				continue
-			}
+		if attr.path().get_ident().map_or(false, |i| *i == PALLET_DOC) {
+			pallet_docs.push(def.item.attrs.remove(index));
+			// Do not increment the index, we have just removed the
+			// element from the attributes.
+			continue
 		}
 
 		index += 1;
 	}
 
 	// Capture the `#[doc = include_str!("../README.md")]` and `#[doc = "Documentation"]`.
-	let mut docs: Vec<_> = def.item.attrs.iter().filter_map(parse_doc_value).collect();
+	let docs = match def
+		.item
+		.attrs
+		.iter()
+		.filter_map(|v| parse_doc_value(v).transpose())
+		.collect::<syn::Result<Vec<_>>>()
+	{
+		Ok(r) => r,
+		Err(err) => return err.into_compile_error(),
+	};
 
 	// Capture the `#[pallet_doc("../README.md")]`.
-	let pallet_docs: Vec<_> = match pallet_docs
+	let pallet_docs = match pallet_docs
 		.into_iter()
 		.map(|attr| parse_pallet_doc_value(&attr))
-		.collect::<syn::Result<_>>()
+		.collect::<syn::Result<Vec<_>>>()
 	{
 		Ok(docs) => docs,
 		Err(err) => return err.into_compile_error(),
 	};
 
-	docs.extend(pallet_docs);
+	let docs = docs.iter().chain(pallet_docs.iter());
 
 	quote::quote!(
 		impl<#type_impl_gen> #pallet_ident<#type_use_gen> #where_clauses{
diff --git a/substrate/frame/support/procedural/src/pallet/expand/storage.rs b/substrate/frame/support/procedural/src/pallet/expand/storage.rs
index efc803033d3..c742ddcd25f 100644
--- a/substrate/frame/support/procedural/src/pallet/expand/storage.rs
+++ b/substrate/frame/support/procedural/src/pallet/expand/storage.rs
@@ -384,10 +384,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
 						QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
 							Option<#value>
 						),
-						QueryKind::ResultQuery(error_path, _) =>
+						QueryKind::ResultQuery(error_path, _) => {
 							quote::quote_spanned!(storage.attr_span =>
 								Result<#value, #error_path>
-							),
+							)
+						},
 						QueryKind::ValueQuery => quote::quote!(#value),
 					};
 					quote::quote_spanned!(storage.attr_span =>
@@ -407,10 +408,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
 						QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
 							Option<#value>
 						),
-						QueryKind::ResultQuery(error_path, _) =>
+						QueryKind::ResultQuery(error_path, _) => {
 							quote::quote_spanned!(storage.attr_span =>
 								Result<#value, #error_path>
-							),
+							)
+						},
 						QueryKind::ValueQuery => quote::quote!(#value),
 					};
 					quote::quote_spanned!(storage.attr_span =>
@@ -432,10 +434,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
 						QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
 							Option<#value>
 						),
-						QueryKind::ResultQuery(error_path, _) =>
+						QueryKind::ResultQuery(error_path, _) => {
 							quote::quote_spanned!(storage.attr_span =>
 								Result<#value, #error_path>
-							),
+							)
+						},
 						QueryKind::ValueQuery => quote::quote!(#value),
 					};
 					quote::quote_spanned!(storage.attr_span =>
@@ -457,10 +460,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
 						QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
 							Option<#value>
 						),
-						QueryKind::ResultQuery(error_path, _) =>
+						QueryKind::ResultQuery(error_path, _) => {
 							quote::quote_spanned!(storage.attr_span =>
 								Result<#value, #error_path>
-							),
+							)
+						},
 						QueryKind::ValueQuery => quote::quote!(#value),
 					};
 					quote::quote_spanned!(storage.attr_span =>
@@ -484,10 +488,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
 						QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
 							Option<#value>
 						),
-						QueryKind::ResultQuery(error_path, _) =>
+						QueryKind::ResultQuery(error_path, _) => {
 							quote::quote_spanned!(storage.attr_span =>
 								Result<#value, #error_path>
-							),
+							)
+						},
 						QueryKind::ValueQuery => quote::quote!(#value),
 					};
 					quote::quote_spanned!(storage.attr_span =>
diff --git a/substrate/frame/support/procedural/src/pallet/parse/call.rs b/substrate/frame/support/procedural/src/pallet/parse/call.rs
index 5b90c2d98b8..ae1c039c9dd 100644
--- a/substrate/frame/support/procedural/src/pallet/parse/call.rs
+++ b/substrate/frame/support/procedural/src/pallet/parse/call.rs
@@ -45,7 +45,7 @@ pub struct CallDef {
 	/// The span of the pallet::call attribute.
 	pub attr_span: proc_macro2::Span,
 	/// Docs, specified on the impl Block.
-	pub docs: Vec<syn::Lit>,
+	pub docs: Vec<syn::Expr>,
 }
 
 /// Definition of dispatchable typically: `#[weight...] fn foo(origin .., param1: ...) -> ..`
@@ -62,7 +62,7 @@ pub struct CallVariantDef {
 	/// Whether an explicit call index was specified.
 	pub explicit_call_index: bool,
 	/// Docs, used for metadata.
-	pub docs: Vec<syn::Lit>,
+	pub docs: Vec<syn::Expr>,
 	/// Attributes annotated at the top of the dispatchable function.
 	pub attrs: Vec<syn::Attribute>,
 }
@@ -173,7 +173,7 @@ impl CallDef {
 		let mut indices = HashMap::new();
 		let mut last_index: Option<u8> = None;
 		for item in &mut item_impl.items {
-			if let syn::ImplItem::Method(method) = item {
+			if let syn::ImplItem::Fn(method) = item {
 				if !matches!(method.vis, syn::Visibility::Public(_)) {
 					let msg = "Invalid pallet::call, dispatchable function must be public: \
 						`pub fn`";
diff --git a/substrate/frame/support/procedural/src/pallet/parse/composite.rs b/substrate/frame/support/procedural/src/pallet/parse/composite.rs
index 2406f10d50a..2bbfcd2e998 100644
--- a/substrate/frame/support/procedural/src/pallet/parse/composite.rs
+++ b/substrate/frame/support/procedural/src/pallet/parse/composite.rs
@@ -32,14 +32,14 @@ pub mod keyword {
 		SlashReason(SlashReason),
 	}
 
-	impl Spanned for CompositeKeyword {
-		fn span(&self) -> proc_macro2::Span {
+	impl ToTokens for CompositeKeyword {
+		fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
 			use CompositeKeyword::*;
 			match self {
-				FreezeReason(inner) => inner.span(),
-				HoldReason(inner) => inner.span(),
-				LockId(inner) => inner.span(),
-				SlashReason(inner) => inner.span(),
+				FreezeReason(inner) => inner.to_tokens(tokens),
+				HoldReason(inner) => inner.to_tokens(tokens),
+				LockId(inner) => inner.to_tokens(tokens),
+				SlashReason(inner) => inner.to_tokens(tokens),
 			}
 		}
 	}
@@ -109,14 +109,11 @@ impl CompositeDef {
 		}
 
 		let has_derive_attr = item.attrs.iter().any(|attr| {
-			attr.parse_meta()
-				.ok()
-				.map(|meta| match meta {
-					syn::Meta::List(syn::MetaList { path, .. }) =>
-						path.get_ident().map(|ident| ident == "derive").unwrap_or(false),
-					_ => false,
-				})
-				.unwrap_or(false)
+			if let syn::Meta::List(syn::MetaList { path, .. }) = &attr.meta {
+				path.get_ident().map(|ident| ident == "derive").unwrap_or(false)
+			} else {
+				false
+			}
 		});
 
 		if !has_derive_attr {
diff --git a/substrate/frame/support/procedural/src/pallet/parse/config.rs b/substrate/frame/support/procedural/src/pallet/parse/config.rs
index 4d22e50ef2b..7b52c1664ba 100644
--- a/substrate/frame/support/procedural/src/pallet/parse/config.rs
+++ b/substrate/frame/support/procedural/src/pallet/parse/config.rs
@@ -61,7 +61,7 @@ pub struct ConstMetadataDef {
 	/// The type in Get, e.g. `u32` in `type Foo: Get<u32>;`, but `Self` is replaced by `T`
 	pub type_: syn::Type,
 	/// The doc associated
-	pub doc: Vec<syn::Lit>,
+	pub doc: Vec<syn::Expr>,
 }
 
 impl TryFrom<&syn::TraitItemType> for ConstMetadataDef {
@@ -124,23 +124,35 @@ impl syn::parse::Parse for DisableFrameSystemSupertraitCheck {
 }
 
 /// Parse for `#[pallet::constant]`
-pub struct TypeAttrConst(proc_macro2::Span);
-
-impl Spanned for TypeAttrConst {
-	fn span(&self) -> proc_macro2::Span {
-		self.0
-	}
+pub struct TypeAttrConst {
+	pound_token: syn::Token![#],
+	bracket_token: syn::token::Bracket,
+	pallet_ident: syn::Ident,
+	path_sep_token: syn::token::PathSep,
+	constant_keyword: keyword::constant,
 }
 
 impl syn::parse::Parse for TypeAttrConst {
 	fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
-		input.parse::<syn::Token![#]>()?;
+		let pound_token = input.parse::<syn::Token![#]>()?;
 		let content;
-		syn::bracketed!(content in input);
-		content.parse::<syn::Ident>()?;
-		content.parse::<syn::Token![::]>()?;
+		let bracket_token = syn::bracketed!(content in input);
+		let pallet_ident = content.parse::<syn::Ident>()?;
+		let path_sep_token = content.parse::<syn::Token![::]>()?;
+		let constant_keyword = content.parse::<keyword::constant>()?;
 
-		Ok(TypeAttrConst(content.parse::<keyword::constant>()?.span()))
+		Ok(Self { pound_token, bracket_token, pallet_ident, path_sep_token, constant_keyword })
+	}
+}
+
+impl ToTokens for TypeAttrConst {
+	fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
+		self.pound_token.to_tokens(tokens);
+		self.bracket_token.surround(tokens, |tokens| {
+			self.pallet_ident.to_tokens(tokens);
+			self.path_sep_token.to_tokens(tokens);
+			self.constant_keyword.to_tokens(tokens);
+		})
 	}
 }
 
diff --git a/substrate/frame/support/procedural/src/pallet/parse/error.rs b/substrate/frame/support/procedural/src/pallet/parse/error.rs
index f344c5d27a8..6f82ce61fc9 100644
--- a/substrate/frame/support/procedural/src/pallet/parse/error.rs
+++ b/substrate/frame/support/procedural/src/pallet/parse/error.rs
@@ -37,7 +37,7 @@ pub struct ErrorDef {
 	/// The index of error item in pallet module.
 	pub index: usize,
 	/// Variants ident, optional field and doc literals (ordered as declaration order)
-	pub variants: Vec<(syn::Ident, Option<VariantField>, Vec<syn::Lit>)>,
+	pub variants: Vec<(syn::Ident, Option<VariantField>, Vec<syn::Expr>)>,
 	/// A set of usage of instance, must be check for consistency with trait.
 	pub instances: Vec<helper::InstanceUsage>,
 	/// The keyword error used (contains span).
diff --git a/substrate/frame/support/procedural/src/pallet/parse/extra_constants.rs b/substrate/frame/support/procedural/src/pallet/parse/extra_constants.rs
index 8e85d2c2622..2ba6c44b7d1 100644
--- a/substrate/frame/support/procedural/src/pallet/parse/extra_constants.rs
+++ b/substrate/frame/support/procedural/src/pallet/parse/extra_constants.rs
@@ -50,7 +50,7 @@ pub struct ExtraConstantDef {
 	/// The type returned by the function
 	pub type_: syn::Type,
 	/// The doc associated
-	pub doc: Vec<syn::Lit>,
+	pub doc: Vec<syn::Expr>,
 	/// Optional MetaData Name
 	pub metadata_name: Option<syn::Ident>,
 }
@@ -100,7 +100,7 @@ impl ExtraConstantsDef {
 
 		let mut extra_constants = vec![];
 		for impl_item in &mut item.items {
-			let method = if let syn::ImplItem::Method(method) = impl_item {
+			let method = if let syn::ImplItem::Fn(method) = impl_item {
 				method
 			} else {
 				let msg = "Invalid pallet::call, only method accepted";
diff --git a/substrate/frame/support/procedural/src/pallet/parse/helper.rs b/substrate/frame/support/procedural/src/pallet/parse/helper.rs
index 4814dce5a3d..3cdbfb1f591 100644
--- a/substrate/frame/support/procedural/src/pallet/parse/helper.rs
+++ b/substrate/frame/support/procedural/src/pallet/parse/helper.rs
@@ -54,7 +54,7 @@ where
 	let attrs = if let Some(attrs) = item.mut_item_attrs() { attrs } else { return Ok(None) };
 
 	if let Some(index) = attrs.iter().position(|attr| {
-		attr.path.segments.first().map_or(false, |segment| segment.ident == "pallet")
+		attr.path().segments.first().map_or(false, |segment| segment.ident == "pallet")
 	}) {
 		let pallet_attr = attrs.remove(index);
 		Ok(Some(syn::parse2(pallet_attr.into_token_stream())?))
@@ -82,7 +82,7 @@ pub fn get_item_cfg_attrs(attrs: &[syn::Attribute]) -> Vec<syn::Attribute> {
 	attrs
 		.iter()
 		.filter_map(|attr| {
-			if attr.path.segments.first().map_or(false, |segment| segment.ident == "cfg") {
+			if attr.path().segments.first().map_or(false, |segment| segment.ident == "cfg") {
 				Some(attr.clone())
 			} else {
 				None
@@ -101,7 +101,6 @@ impl MutItemAttrs for syn::Item {
 			Self::ForeignMod(item) => Some(item.attrs.as_mut()),
 			Self::Impl(item) => Some(item.attrs.as_mut()),
 			Self::Macro(item) => Some(item.attrs.as_mut()),
-			Self::Macro2(item) => Some(item.attrs.as_mut()),
 			Self::Mod(item) => Some(item.attrs.as_mut()),
 			Self::Static(item) => Some(item.attrs.as_mut()),
 			Self::Struct(item) => Some(item.attrs.as_mut()),
@@ -119,7 +118,7 @@ impl MutItemAttrs for syn::TraitItem {
 	fn mut_item_attrs(&mut self) -> Option<&mut Vec<syn::Attribute>> {
 		match self {
 			Self::Const(item) => Some(item.attrs.as_mut()),
-			Self::Method(item) => Some(item.attrs.as_mut()),
+			Self::Fn(item) => Some(item.attrs.as_mut()),
 			Self::Type(item) => Some(item.attrs.as_mut()),
 			Self::Macro(item) => Some(item.attrs.as_mut()),
 			_ => None,
@@ -139,7 +138,7 @@ impl MutItemAttrs for syn::ItemMod {
 	}
 }
 
-impl MutItemAttrs for syn::ImplItemMethod {
+impl MutItemAttrs for syn::ImplItemFn {
 	fn mut_item_attrs(&mut self) -> Option<&mut Vec<syn::Attribute>> {
 		Some(&mut self.attrs)
 	}
diff --git a/substrate/frame/support/procedural/src/pallet/parse/hooks.rs b/substrate/frame/support/procedural/src/pallet/parse/hooks.rs
index f941df5f292..37d7d22f4b6 100644
--- a/substrate/frame/support/procedural/src/pallet/parse/hooks.rs
+++ b/substrate/frame/support/procedural/src/pallet/parse/hooks.rs
@@ -71,7 +71,7 @@ impl HooksDef {
 		}
 
 		let has_runtime_upgrade = item.items.iter().any(|i| match i {
-			syn::ImplItem::Method(method) => method.sig.ident == "on_runtime_upgrade",
+			syn::ImplItem::Fn(method) => method.sig.ident == "on_runtime_upgrade",
 			_ => false,
 		});
 
diff --git a/substrate/frame/support/procedural/src/pallet/parse/storage.rs b/substrate/frame/support/procedural/src/pallet/parse/storage.rs
index 4e90a423f79..16c0851ce7a 100644
--- a/substrate/frame/support/procedural/src/pallet/parse/storage.rs
+++ b/substrate/frame/support/procedural/src/pallet/parse/storage.rs
@@ -159,7 +159,7 @@ pub struct StorageDef {
 	/// The keys and value metadata of the storage.
 	pub metadata: Metadata,
 	/// The doc associated to the storage.
-	pub docs: Vec<syn::Lit>,
+	pub docs: Vec<syn::Expr>,
 	/// A set of usage of instance, must be check for consistency with config.
 	pub instances: Vec<helper::InstanceUsage>,
 	/// Optional getter to generate. If some then query_kind is ensured to be some as well.
@@ -270,7 +270,7 @@ enum StorageKind {
 /// Check the generics in the `map` contains the generics in `gen` may contains generics in
 /// `optional_gen`, and doesn't contains any other.
 fn check_generics(
-	map: &HashMap<String, syn::Binding>,
+	map: &HashMap<String, syn::AssocType>,
 	mandatory_generics: &[&str],
 	optional_generics: &[&str],
 	storage_type_name: &str,
@@ -331,9 +331,9 @@ fn check_generics(
 fn process_named_generics(
 	storage: &StorageKind,
 	args_span: proc_macro2::Span,
-	args: &[syn::Binding],
+	args: &[syn::AssocType],
 ) -> syn::Result<(Option<StorageGenerics>, Metadata, Option<syn::Type>, bool)> {
-	let mut parsed = HashMap::<String, syn::Binding>::new();
+	let mut parsed = HashMap::<String, syn::AssocType>::new();
 
 	// Ensure no duplicate.
 	for arg in args {
@@ -610,12 +610,12 @@ fn process_generics(
 			})
 			.collect::<Vec<_>>();
 		process_unnamed_generics(&storage_kind, args_span, &args, dev_mode)
-	} else if args.args.iter().all(|gen| matches!(gen, syn::GenericArgument::Binding(_))) {
+	} else if args.args.iter().all(|gen| matches!(gen, syn::GenericArgument::AssocType(_))) {
 		let args = args
 			.args
 			.iter()
 			.map(|gen| match gen {
-				syn::GenericArgument::Binding(gen) => gen.clone(),
+				syn::GenericArgument::AssocType(gen) => gen.clone(),
 				_ => unreachable!("It is asserted above that all generics are bindings"),
 			})
 			.collect::<Vec<_>>();
diff --git a/substrate/frame/support/procedural/src/pallet/parse/type_value.rs b/substrate/frame/support/procedural/src/pallet/parse/type_value.rs
index 4b80506889d..4d9db30b3a7 100644
--- a/substrate/frame/support/procedural/src/pallet/parse/type_value.rs
+++ b/substrate/frame/support/procedural/src/pallet/parse/type_value.rs
@@ -39,7 +39,7 @@ pub struct TypeValueDef {
 	/// The span of the pallet::type_value attribute.
 	pub attr_span: proc_macro2::Span,
 	/// Docs on the item.
-	pub docs: Vec<syn::Lit>,
+	pub docs: Vec<syn::Expr>,
 }
 
 impl TypeValueDef {
@@ -57,9 +57,9 @@ impl TypeValueDef {
 
 		let mut docs = vec![];
 		for attr in &item.attrs {
-			if let Ok(syn::Meta::NameValue(meta)) = attr.parse_meta() {
+			if let syn::Meta::NameValue(meta) = &attr.meta {
 				if meta.path.get_ident().map_or(false, |ident| ident == "doc") {
-					docs.push(meta.lit);
+					docs.push(meta.value.clone());
 					continue
 				}
 			}
diff --git a/substrate/frame/support/procedural/src/pallet_error.rs b/substrate/frame/support/procedural/src/pallet_error.rs
index fb0bf52f690..246a5bd4a21 100644
--- a/substrate/frame/support/procedural/src/pallet_error.rs
+++ b/substrate/frame/support/procedural/src/pallet_error.rs
@@ -17,7 +17,6 @@
 
 use frame_support_procedural_tools::generate_crate_access_2018;
 use quote::ToTokens;
-use std::str::FromStr;
 
 // Derive `PalletError`
 pub fn derive_pallet_error(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
@@ -117,38 +116,24 @@ fn generate_field_types(
 	let attrs = &field.attrs;
 
 	for attr in attrs {
-		if attr.path.is_ident("codec") {
-			match attr.parse_meta()? {
-				syn::Meta::List(ref meta_list) if meta_list.nested.len() == 1 => {
-					match meta_list
-						.nested
-						.first()
-						.expect("Just checked that there is one item; qed")
-					{
-						syn::NestedMeta::Meta(syn::Meta::Path(path))
-							if path.get_ident().map_or(false, |i| i == "skip") =>
-							return Ok(None),
-
-						syn::NestedMeta::Meta(syn::Meta::Path(path))
-							if path.get_ident().map_or(false, |i| i == "compact") =>
-						{
-							let field_ty = &field.ty;
-							return Ok(Some(quote::quote!(#scrate::codec::Compact<#field_ty>)))
-						},
-
-						syn::NestedMeta::Meta(syn::Meta::NameValue(syn::MetaNameValue {
-							path,
-							lit: syn::Lit::Str(lit_str),
-							..
-						})) if path.get_ident().map_or(false, |i| i == "encoded_as") => {
-							let ty = proc_macro2::TokenStream::from_str(&lit_str.value())?;
-							return Ok(Some(ty))
-						},
-
-						_ => (),
-					}
-				},
-				_ => (),
+		if attr.path().is_ident("codec") {
+			let mut res = None;
+
+			attr.parse_nested_meta(|meta| {
+				if meta.path.is_ident("skip") {
+					res = Some(None);
+				} else if meta.path.is_ident("compact") {
+					let field_ty = &field.ty;
+					res = Some(Some(quote::quote!(#scrate::codec::Compact<#field_ty>)));
+				} else if meta.path.is_ident("compact") {
+					res = Some(Some(meta.value()?.parse()?));
+				}
+
+				Ok(())
+			})?;
+
+			if let Some(v) = res {
+				return Ok(v)
 			}
 		}
 	}
@@ -163,22 +148,18 @@ fn generate_variant_field_types(
 	let attrs = &variant.attrs;
 
 	for attr in attrs {
-		if attr.path.is_ident("codec") {
-			match attr.parse_meta()? {
-				syn::Meta::List(ref meta_list) if meta_list.nested.len() == 1 => {
-					match meta_list
-						.nested
-						.first()
-						.expect("Just checked that there is one item; qed")
-					{
-						syn::NestedMeta::Meta(syn::Meta::Path(path))
-							if path.get_ident().map_or(false, |i| i == "skip") =>
-							return Ok(None),
-
-						_ => (),
-					}
-				},
-				_ => (),
+		if attr.path().is_ident("codec") {
+			let mut skip = false;
+
+			// We ignore the error intentionally as this isn't `codec(skip)` when
+			// `parse_nested_meta` fails.
+			let _ = attr.parse_nested_meta(|meta| {
+				skip = meta.path.is_ident("skip");
+				Ok(())
+			});
+
+			if skip {
+				return Ok(None)
 			}
 		}
 	}
diff --git a/substrate/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs b/substrate/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs
index 491db59184f..31e9996ee51 100644
--- a/substrate/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs
+++ b/substrate/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs
@@ -133,14 +133,13 @@ impl GenesisConfigDef {
 				.attrs
 				.iter()
 				.map(|attr| {
-					let meta = attr.parse_meta()?;
-					if meta.path().is_ident("cfg") {
+					if attr.meta.path().is_ident("cfg") {
 						return Err(syn::Error::new(
-							meta.span(),
+							attr.meta.span(),
 							"extra genesis config items do not support `cfg` attribute",
 						))
 					}
-					Ok(meta)
+					Ok(attr.meta.clone())
 				})
 				.collect::<syn::Result<_>>()?;
 
diff --git a/substrate/frame/support/procedural/src/storage/mod.rs b/substrate/frame/support/procedural/src/storage/mod.rs
index 3d3b1443d39..c04862256a7 100644
--- a/substrate/frame/support/procedural/src/storage/mod.rs
+++ b/substrate/frame/support/procedural/src/storage/mod.rs
@@ -332,8 +332,8 @@ impl StorageLineDefExt {
 		let doc_attrs = storage_def
 			.attrs
 			.iter()
-			.filter_map(|a| a.parse_meta().ok())
-			.filter(|m| m.path().is_ident("doc"))
+			.filter(|a| a.meta.path().is_ident("doc"))
+			.map(|a| a.meta.clone())
 			.collect();
 
 		Self {
diff --git a/substrate/frame/support/procedural/src/storage/print_pallet_upgrade.rs b/substrate/frame/support/procedural/src/storage/print_pallet_upgrade.rs
index 03f09a7edb4..4e330fd4b85 100644
--- a/substrate/frame/support/procedural/src/storage/print_pallet_upgrade.rs
+++ b/substrate/frame/support/procedural/src/storage/print_pallet_upgrade.rs
@@ -273,14 +273,12 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
 			doc = line.doc_attrs.iter().fold(String::new(), |mut res, attr| {
 				if let syn::Meta::NameValue(name_value) = attr {
 					if name_value.path.is_ident("doc") {
-						if let syn::Lit::Str(string) = &name_value.lit {
-							res = format!(
-								"{}
-	///{}",
-								res,
-								string.value(),
-							);
-						}
+						res = format!(
+							"{}
+							///{}",
+							res,
+							name_value.value.to_token_stream(),
+						);
 					}
 				}
 				res
diff --git a/substrate/frame/support/procedural/tools/Cargo.toml b/substrate/frame/support/procedural/tools/Cargo.toml
index 755483f7db9..bf828b01b6f 100644
--- a/substrate/frame/support/procedural/tools/Cargo.toml
+++ b/substrate/frame/support/procedural/tools/Cargo.toml
@@ -13,7 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
 proc-macro-crate = "1.1.3"
-proc-macro2 = "1.0.37"
-quote = "1.0.10"
-syn = { version = "1.0.98", features = ["full", "visit", "extra-traits"] }
+proc-macro2 = "1.0.56"
+quote = "1.0.26"
+syn = { version = "2.0.14", features = ["full", "visit", "extra-traits"] }
 frame-support-procedural-tools-derive = { version = "3.0.0", path = "./derive" }
diff --git a/substrate/frame/support/procedural/tools/derive/Cargo.toml b/substrate/frame/support/procedural/tools/derive/Cargo.toml
index a688ee13a7d..81b5a848744 100644
--- a/substrate/frame/support/procedural/tools/derive/Cargo.toml
+++ b/substrate/frame/support/procedural/tools/derive/Cargo.toml
@@ -15,6 +15,6 @@ targets = ["x86_64-unknown-linux-gnu"]
 proc-macro = true
 
 [dependencies]
-proc-macro2 = "1.0.37"
-quote = { version = "1.0.10", features = ["proc-macro"] }
-syn = { version = "1.0.98", features = ["proc-macro", "full", "extra-traits", "parsing"] }
+proc-macro2 = "1.0.56"
+quote = { version = "1.0.26", features = ["proc-macro"] }
+syn = { version = "2.0.14", features = ["proc-macro", "full", "extra-traits", "parsing"] }
diff --git a/substrate/frame/support/procedural/tools/src/lib.rs b/substrate/frame/support/procedural/tools/src/lib.rs
index 385b20ad05d..541accc8ab9 100644
--- a/substrate/frame/support/procedural/tools/src/lib.rs
+++ b/substrate/frame/support/procedural/tools/src/lib.rs
@@ -102,16 +102,15 @@ pub fn clean_type_string(input: &str) -> String {
 }
 
 /// Return all doc attributes literals found.
-pub fn get_doc_literals(attrs: &[syn::Attribute]) -> Vec<syn::Lit> {
+pub fn get_doc_literals(attrs: &[syn::Attribute]) -> Vec<syn::Expr> {
 	attrs
 		.iter()
 		.filter_map(|attr| {
-			if let Ok(syn::Meta::NameValue(meta)) = attr.parse_meta() {
-				if meta.path.get_ident().map_or(false, |ident| ident == "doc") {
-					Some(meta.lit)
-				} else {
-					None
-				}
+			if let syn::Meta::NameValue(meta) = &attr.meta {
+				meta.path
+					.get_ident()
+					.filter(|ident| *ident == "doc")
+					.map(|_| meta.value.clone())
 			} else {
 				None
 			}
diff --git a/substrate/frame/support/test/tests/pallet_ui/pallet_doc_arg_non_path.stderr b/substrate/frame/support/test/tests/pallet_ui/pallet_doc_arg_non_path.stderr
index ba60479c072..9a1249dd36f 100644
--- a/substrate/frame/support/test/tests/pallet_ui/pallet_doc_arg_non_path.stderr
+++ b/substrate/frame/support/test/tests/pallet_ui/pallet_doc_arg_non_path.stderr
@@ -1,4 +1,4 @@
-error: The `pallet_doc` received an unsupported argument. Supported format: `pallet_doc(PATH)`
+error: The `pallet_doc` received an unsupported argument. Supported format: `pallet_doc("PATH")`
  --> tests/pallet_ui/pallet_doc_arg_non_path.rs:3:1
   |
 3 | #[pallet_doc(X)]
diff --git a/substrate/frame/support/test/tests/pallet_ui/pallet_doc_empty.stderr b/substrate/frame/support/test/tests/pallet_ui/pallet_doc_empty.stderr
index d6a189d7918..a220cbe9e99 100644
--- a/substrate/frame/support/test/tests/pallet_ui/pallet_doc_empty.stderr
+++ b/substrate/frame/support/test/tests/pallet_ui/pallet_doc_empty.stderr
@@ -1,4 +1,4 @@
-error: The `pallet_doc` attribute must receive arguments as a list. Supported format: `pallet_doc(PATH)`
+error: The `pallet_doc` received an unsupported argument. Supported format: `pallet_doc("PATH")`
  --> tests/pallet_ui/pallet_doc_empty.rs:3:1
   |
 3 | #[pallet_doc]
diff --git a/substrate/frame/support/test/tests/pallet_ui/pallet_doc_invalid_arg.stderr b/substrate/frame/support/test/tests/pallet_ui/pallet_doc_invalid_arg.stderr
index 9dd03978934..bee7c708507 100644
--- a/substrate/frame/support/test/tests/pallet_ui/pallet_doc_invalid_arg.stderr
+++ b/substrate/frame/support/test/tests/pallet_ui/pallet_doc_invalid_arg.stderr
@@ -1,4 +1,4 @@
-error: The `pallet_doc` attribute must receive arguments as a list. Supported format: `pallet_doc(PATH)`
+error: The `pallet_doc` received an unsupported argument. Supported format: `pallet_doc("PATH")`
  --> tests/pallet_ui/pallet_doc_invalid_arg.rs:3:1
   |
 3 | #[pallet_doc = "invalid"]
diff --git a/substrate/frame/support/test/tests/pallet_ui/pallet_doc_multiple_args.stderr b/substrate/frame/support/test/tests/pallet_ui/pallet_doc_multiple_args.stderr
index 58ad75a0a2a..e769555438e 100644
--- a/substrate/frame/support/test/tests/pallet_ui/pallet_doc_multiple_args.stderr
+++ b/substrate/frame/support/test/tests/pallet_ui/pallet_doc_multiple_args.stderr
@@ -1,4 +1,4 @@
-error: The `pallet_doc` attribute must receive only one argument. Supported format: `pallet_doc(PATH)`
+error: The `pallet_doc` received an unsupported argument. Supported format: `pallet_doc("PATH")`
  --> tests/pallet_ui/pallet_doc_multiple_args.rs:3:1
   |
 3 | #[pallet_doc("A", "B")]
diff --git a/substrate/frame/support/test/tests/pallet_ui/storage_result_query_parenthesized_generics.stderr b/substrate/frame/support/test/tests/pallet_ui/storage_result_query_parenthesized_generics.stderr
index caffd846f27..89ddd1599ac 100644
--- a/substrate/frame/support/test/tests/pallet_ui/storage_result_query_parenthesized_generics.stderr
+++ b/substrate/frame/support/test/tests/pallet_ui/storage_result_query_parenthesized_generics.stderr
@@ -1,5 +1,5 @@
-error: Invalid pallet::storage, unexpected generic args for ResultQuery, expected angle-bracketed arguments, found `(NonExistentValue)`
+error: expected `,`
   --> tests/pallet_ui/storage_result_query_parenthesized_generics.rs:18:55
    |
 18 |     type Foo<T: Config> = StorageValue<_, u8, ResultQuery(NonExistentValue)>;
-   |                                                          ^^^^^^^^^^^^^^^^^^
+   |                                                          ^
diff --git a/substrate/primitives/api/proc-macro/Cargo.toml b/substrate/primitives/api/proc-macro/Cargo.toml
index 1ba62cc53d5..594c20e82c9 100644
--- a/substrate/primitives/api/proc-macro/Cargo.toml
+++ b/substrate/primitives/api/proc-macro/Cargo.toml
@@ -16,9 +16,9 @@ targets = ["x86_64-unknown-linux-gnu"]
 proc-macro = true
 
 [dependencies]
-quote = "1.0.10"
-syn = { version = "1.0.98", features = ["full", "fold", "extra-traits", "visit"] }
-proc-macro2 = "1.0.37"
+quote = "1.0.26"
+syn = { version = "2.0.14", features = ["full", "fold", "extra-traits", "visit"] }
+proc-macro2 = "1.0.56"
 blake2 = { version = "0.10.4", default-features = false }
 proc-macro-crate = "1.1.3"
 expander = "1.0.0"
diff --git a/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs
index 43e1e7969c5..cde33c19016 100644
--- a/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs
+++ b/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs
@@ -38,9 +38,10 @@ use syn::{
 	parse::{Error, Parse, ParseStream, Result},
 	parse_macro_input, parse_quote,
 	spanned::Spanned,
+	token::Comma,
 	visit::{self, Visit},
-	Attribute, FnArg, GenericParam, Generics, Ident, ItemTrait, Lit, Meta, NestedMeta, TraitBound,
-	TraitItem, TraitItemMethod,
+	Attribute, FnArg, GenericParam, Generics, Ident, ItemTrait, LitInt, LitStr, TraitBound,
+	TraitItem, TraitItemFn,
 };
 
 use std::collections::{BTreeMap, HashMap};
@@ -76,7 +77,7 @@ fn extend_generics_with_block(generics: &mut Generics) {
 /// attribute body as `TokenStream`.
 fn remove_supported_attributes(attrs: &mut Vec<Attribute>) -> HashMap<&'static str, Attribute> {
 	let mut result = HashMap::new();
-	attrs.retain(|v| match SUPPORTED_ATTRIBUTE_NAMES.iter().find(|a| v.path.is_ident(a)) {
+	attrs.retain(|v| match SUPPORTED_ATTRIBUTE_NAMES.iter().find(|a| v.path().is_ident(a)) {
 		Some(attribute) => {
 			result.insert(*attribute, v.clone());
 			false
@@ -159,7 +160,7 @@ impl Fold for ReplaceBlockWithNodeBlock {
 /// ```
 fn generate_versioned_api_traits(
 	api: ItemTrait,
-	methods: BTreeMap<u64, Vec<TraitItemMethod>>,
+	methods: BTreeMap<u64, Vec<TraitItemFn>>,
 ) -> Vec<ItemTrait> {
 	let mut result = Vec::<ItemTrait>::new();
 	for (version, _) in &methods {
@@ -169,7 +170,7 @@ fn generate_versioned_api_traits(
 		// Add the methods from the current version and all previous one. Versions are sorted so
 		// it's safe to stop early.
 		for (_, m) in methods.iter().take_while(|(v, _)| v <= &version) {
-			versioned_trait.items.extend(m.iter().cloned().map(|m| TraitItem::Method(m)));
+			versioned_trait.items.extend(m.iter().cloned().map(|m| TraitItem::Fn(m)));
 		}
 
 		result.push(versioned_trait);
@@ -180,37 +181,29 @@ fn generate_versioned_api_traits(
 
 /// Try to parse the given `Attribute` as `renamed` attribute.
 fn parse_renamed_attribute(renamed: &Attribute) -> Result<(String, u32)> {
-	let meta = renamed.parse_meta()?;
-
-	let err = Err(Error::new(
-			meta.span(),
+	let err = || {
+		Error::new(
+			renamed.span(),
 			&format!(
-				"Unexpected `{renamed}` attribute. The supported format is `{renamed}(\"old_name\", version_it_was_renamed)`",
-				renamed = RENAMED_ATTRIBUTE,
-			)
+				"Unexpected `{RENAMED_ATTRIBUTE}` attribute. \
+				 The supported format is `{RENAMED_ATTRIBUTE}(\"old_name\", version_it_was_renamed)`",
+			),
 		)
-	);
-
-	match meta {
-		Meta::List(list) =>
-			if list.nested.len() > 2 && list.nested.is_empty() {
-				err
-			} else {
-				let mut itr = list.nested.iter();
-				let old_name = match itr.next() {
-					Some(NestedMeta::Lit(Lit::Str(i))) => i.value(),
-					_ => return err,
-				};
-
-				let version = match itr.next() {
-					Some(NestedMeta::Lit(Lit::Int(i))) => i.base10_parse()?,
-					_ => return err,
-				};
-
-				Ok((old_name, version))
-			},
-		_ => err,
-	}
+	};
+
+	renamed
+		.parse_args_with(|input: ParseStream| {
+			let old_name: LitStr = input.parse()?;
+			let _comma: Comma = input.parse()?;
+			let version: LitInt = input.parse()?;
+
+			if !input.is_empty() {
+				return Err(input.error("No more arguments expected"))
+			}
+
+			Ok((old_name.value(), version.base10_parse()?))
+		})
+		.map_err(|_| err())
 }
 
 /// Generate the declaration of the trait for the runtime.
@@ -230,12 +223,12 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> Result<TokenStream> {
 
 		let trait_api_version = get_api_version(&found_attributes)?;
 
-		let mut methods_by_version: BTreeMap<u64, Vec<TraitItemMethod>> = BTreeMap::new();
+		let mut methods_by_version: BTreeMap<u64, Vec<TraitItemFn>> = BTreeMap::new();
 
 		// Process the items in the declaration. The filter_map function below does a lot of stuff
 		// because the method attributes are stripped at this point
 		decl.items.iter_mut().for_each(|i| match i {
-			TraitItem::Method(ref mut method) => {
+			TraitItem::Fn(ref mut method) => {
 				let method_attrs = remove_supported_attributes(&mut method.attrs);
 				let mut method_version = trait_api_version;
 				// validate the api version for the method (if any) and generate default
@@ -364,9 +357,8 @@ impl<'a> ToClientSideDecl<'a> {
 		let mut result = Vec::new();
 
 		items.into_iter().for_each(|i| match i {
-			TraitItem::Method(method) => {
-				let (fn_decl, fn_decl_ctx) =
-					self.fold_trait_item_method(method, trait_generics_num);
+			TraitItem::Fn(method) => {
+				let (fn_decl, fn_decl_ctx) = self.fold_trait_item_fn(method, trait_generics_num);
 				result.push(fn_decl.into());
 				result.push(fn_decl_ctx.into());
 			},
@@ -376,11 +368,11 @@ impl<'a> ToClientSideDecl<'a> {
 		result
 	}
 
-	fn fold_trait_item_method(
+	fn fold_trait_item_fn(
 		&mut self,
-		method: TraitItemMethod,
+		method: TraitItemFn,
 		trait_generics_num: usize,
-	) -> (TraitItemMethod, TraitItemMethod) {
+	) -> (TraitItemFn, TraitItemFn) {
 		let crate_ = self.crate_;
 		let context = quote!( #crate_::ExecutionContext::OffchainCall(None) );
 		let fn_decl = self.create_method_decl(method.clone(), context, trait_generics_num);
@@ -391,9 +383,9 @@ impl<'a> ToClientSideDecl<'a> {
 
 	fn create_method_decl_with_context(
 		&mut self,
-		method: TraitItemMethod,
+		method: TraitItemFn,
 		trait_generics_num: usize,
-	) -> TraitItemMethod {
+	) -> TraitItemFn {
 		let crate_ = self.crate_;
 		let context_arg: syn::FnArg = parse_quote!( context: #crate_::ExecutionContext );
 		let mut fn_decl_ctx = self.create_method_decl(method, quote!(context), trait_generics_num);
@@ -409,10 +401,10 @@ impl<'a> ToClientSideDecl<'a> {
 	/// the actual call into the runtime.
 	fn create_method_decl(
 		&mut self,
-		mut method: TraitItemMethod,
+		mut method: TraitItemFn,
 		context: TokenStream,
 		trait_generics_num: usize,
-	) -> TraitItemMethod {
+	) -> TraitItemFn {
 		let params = match extract_parameter_names_types_and_borrows(
 			&method.sig,
 			AllowSelfRefInParameters::No,
@@ -661,7 +653,7 @@ impl CheckTraitDecl {
 	/// All errors will be collected in `self.errors`.
 	fn check(&mut self, trait_: &ItemTrait) {
 		self.check_method_declarations(trait_.items.iter().filter_map(|i| match i {
-			TraitItem::Method(method) => Some(method),
+			TraitItem::Fn(method) => Some(method),
 			_ => None,
 		}));
 
@@ -671,10 +663,7 @@ impl CheckTraitDecl {
 	/// Check that the given method declarations are correct.
 	///
 	/// Any error is stored in `self.errors`.
-	fn check_method_declarations<'a>(
-		&mut self,
-		methods: impl Iterator<Item = &'a TraitItemMethod>,
-	) {
+	fn check_method_declarations<'a>(&mut self, methods: impl Iterator<Item = &'a TraitItemFn>) {
 		let mut method_to_signature_changed = HashMap::<Ident, Vec<Option<u64>>>::new();
 
 		methods.into_iter().for_each(|method| {
diff --git a/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs
index c0da8ccf304..b8dcf625df4 100644
--- a/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs
+++ b/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs
@@ -139,7 +139,7 @@ fn generate_impl_calls(
 			.ident;
 
 		for item in &impl_.items {
-			if let ImplItem::Method(method) = item {
+			if let ImplItem::Fn(method) = item {
 				let impl_call =
 					generate_impl_call(&method.sig, &impl_.self_ty, input, &impl_trait)?;
 
@@ -720,7 +720,7 @@ fn impl_runtime_apis_impl_inner(api_impls: &[ItemImpl]) -> Result<TokenStream> {
 
 // Filters all attributes except the cfg ones.
 fn filter_cfg_attrs(attrs: &[Attribute]) -> Vec<Attribute> {
-	attrs.iter().filter(|a| a.path.is_ident("cfg")).cloned().collect()
+	attrs.iter().filter(|a| a.path().is_ident("cfg")).cloned().collect()
 }
 
 // Extracts the value of `API_VERSION_ATTRIBUTE` and handles errors.
@@ -732,7 +732,7 @@ fn extract_api_version(attrs: &Vec<Attribute>, span: Span) -> Result<Option<u64>
 	// First fetch all `API_VERSION_ATTRIBUTE` values (should be only one)
 	let api_ver = attrs
 		.iter()
-		.filter(|a| a.path.is_ident(API_VERSION_ATTRIBUTE))
+		.filter(|a| a.path().is_ident(API_VERSION_ATTRIBUTE))
 		.collect::<Vec<_>>();
 
 	if api_ver.len() > 1 {
diff --git a/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs
index fc0a754e267..be8c8ca0f85 100644
--- a/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs
+++ b/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs
@@ -192,7 +192,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
 fn has_advanced_attribute(attributes: &mut Vec<Attribute>) -> bool {
 	let mut found = false;
 	attributes.retain(|attr| {
-		if attr.path.is_ident(ADVANCED_ATTRIBUTE) {
+		if attr.path().is_ident(ADVANCED_ATTRIBUTE) {
 			found = true;
 			false
 		} else {
@@ -258,7 +258,7 @@ impl<'a> FoldRuntimeApiImpl<'a> {
 		// We also need to overwrite all the `_with_context` methods. To do this,
 		// we clone all methods and add them again with the new name plus one more argument.
 		impl_item.items.extend(impl_item.items.clone().into_iter().filter_map(|i| {
-			if let syn::ImplItem::Method(mut m) = i {
+			if let syn::ImplItem::Fn(mut m) = i {
 				m.sig.ident = quote::format_ident!("{}_with_context", m.sig.ident);
 				m.sig.inputs.insert(2, parse_quote!( _: #crate_::ExecutionContext ));
 
@@ -290,7 +290,7 @@ impl<'a> FoldRuntimeApiImpl<'a> {
 }
 
 impl<'a> Fold for FoldRuntimeApiImpl<'a> {
-	fn fold_impl_item_method(&mut self, mut input: syn::ImplItemMethod) -> syn::ImplItemMethod {
+	fn fold_impl_item_fn(&mut self, mut input: syn::ImplItemFn) -> syn::ImplItemFn {
 		let block = {
 			let crate_ = generate_crate_access();
 			let is_advanced = has_advanced_attribute(&mut input.attrs);
@@ -377,7 +377,7 @@ impl<'a> Fold for FoldRuntimeApiImpl<'a> {
 			)
 		};
 
-		let mut input = fold::fold_impl_item_method(self, input);
+		let mut input = fold::fold_impl_item_fn(self, input);
 		// We need to set the block, after we modified the rest of the ast, otherwise we would
 		// modify our generated block as well.
 		input.block = block;
diff --git a/substrate/primitives/api/proc-macro/src/runtime_metadata.rs b/substrate/primitives/api/proc-macro/src/runtime_metadata.rs
index 02b03baeaee..ae78fb52dbd 100644
--- a/substrate/primitives/api/proc-macro/src/runtime_metadata.rs
+++ b/substrate/primitives/api/proc-macro/src/runtime_metadata.rs
@@ -88,13 +88,13 @@ pub fn generate_decl_runtime_metadata(decl: &ItemTrait) -> TokenStream2 {
 	let mut where_clause = Vec::new();
 	for item in &decl.items {
 		// Collect metadata for methods only.
-		let syn::TraitItem::Method(method) = item else {
+		let syn::TraitItem::Fn(method) = item else {
 			continue
 		};
 
 		// Collect metadata only for the latest methods.
 		let is_changed_in =
-			method.attrs.iter().any(|attr| attr.path.is_ident(CHANGED_IN_ATTRIBUTE));
+			method.attrs.iter().any(|attr| attr.path().is_ident(CHANGED_IN_ATTRIBUTE));
 		if is_changed_in {
 			continue
 		}
diff --git a/substrate/primitives/api/proc-macro/src/utils.rs b/substrate/primitives/api/proc-macro/src/utils.rs
index cffaf317fbb..6716be142fe 100644
--- a/substrate/primitives/api/proc-macro/src/utils.rs
+++ b/substrate/primitives/api/proc-macro/src/utils.rs
@@ -22,7 +22,7 @@ use syn::{
 	ImplItem, ItemImpl, Pat, Path, PathArguments, Result, ReturnType, Signature, Type, TypePath,
 };
 
-use quote::{format_ident, quote};
+use quote::{format_ident, quote, ToTokens};
 
 use proc_macro_crate::{crate_name, FoundCrate};
 
@@ -158,7 +158,7 @@ pub fn extract_all_signature_types(items: &[ImplItem]) -> Vec<Type> {
 	items
 		.iter()
 		.filter_map(|i| match i {
-			ImplItem::Method(method) => Some(&method.sig),
+			ImplItem::Fn(method) => Some(&method.sig),
 			_ => None,
 		})
 		.flat_map(|sig| {
@@ -263,18 +263,20 @@ pub fn get_doc_literals(attrs: &[syn::Attribute]) -> Vec<syn::Lit> {
 	attrs
 		.iter()
 		.filter_map(|attr| {
-			let Ok(syn::Meta::NameValue(meta)) = attr.parse_meta() else {
+			let syn::Meta::NameValue(meta) = &attr.meta else {
 				return None
 			};
-
-			meta.path.get_ident().filter(|ident| *ident == "doc").map(|_| meta.lit)
+			let Ok(lit) = syn::parse2::<syn::Lit>(meta.value.to_token_stream()) else {
+				unreachable!("non-lit doc attribute values do not exist");
+			};
+			meta.path.get_ident().filter(|ident| *ident == "doc").map(|_| lit)
 		})
 		.collect()
 }
 
 /// Filters all attributes except the cfg ones.
 pub fn filter_cfg_attributes(attrs: &[syn::Attribute]) -> Vec<syn::Attribute> {
-	attrs.iter().filter(|a| a.path.is_ident("cfg")).cloned().collect()
+	attrs.iter().filter(|a| a.path().is_ident("cfg")).cloned().collect()
 }
 
 #[cfg(test)]
diff --git a/substrate/primitives/arithmetic/src/per_things.rs b/substrate/primitives/arithmetic/src/per_things.rs
index c4cb5196602..611a4e05e10 100644
--- a/substrate/primitives/arithmetic/src/per_things.rs
+++ b/substrate/primitives/arithmetic/src/per_things.rs
@@ -527,16 +527,18 @@ where
 				rem_mul_div_inner += 1.into();
 			}
 		},
-		Rounding::NearestPrefDown =>
+		Rounding::NearestPrefDown => {
 			if rem_mul_upper % denom_upper > denom_upper / 2.into() {
 				// `rem * numer / denom` is less than `numer`, so this will not overflow.
 				rem_mul_div_inner += 1.into();
-			},
-		Rounding::NearestPrefUp =>
+			}
+		},
+		Rounding::NearestPrefUp => {
 			if rem_mul_upper % denom_upper >= denom_upper / 2.into() + denom_upper % 2.into() {
 				// `rem * numer / denom` is less than `numer`, so this will not overflow.
 				rem_mul_div_inner += 1.into();
-			},
+			}
+		},
 	}
 	rem_mul_div_inner.into()
 }
diff --git a/substrate/primitives/core/hashing/proc-macro/Cargo.toml b/substrate/primitives/core/hashing/proc-macro/Cargo.toml
index 6d9747de871..66e9667c846 100644
--- a/substrate/primitives/core/hashing/proc-macro/Cargo.toml
+++ b/substrate/primitives/core/hashing/proc-macro/Cargo.toml
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
 proc-macro = true
 
 [dependencies]
-proc-macro2 = "1.0.37"
-quote = "1.0.6"
-syn = { version = "1.0.98", features = ["full", "parsing"] }
+proc-macro2 = "1.0.56"
+quote = "1.0.26"
+syn = { version = "2.0.14", features = ["full", "parsing"] }
 sp-core-hashing = { version = "5.0.0", default-features = false, path = "../" }
diff --git a/substrate/primitives/debug-derive/Cargo.toml b/substrate/primitives/debug-derive/Cargo.toml
index a903b704410..183d7bd5a77 100644
--- a/substrate/primitives/debug-derive/Cargo.toml
+++ b/substrate/primitives/debug-derive/Cargo.toml
@@ -17,9 +17,9 @@ targets = ["x86_64-unknown-linux-gnu"]
 proc-macro = true
 
 [dependencies]
-quote = "1.0.10"
-syn = "1.0.98"
-proc-macro2 = "1.0"
+quote = "1.0.26"
+syn = "2.0.14"
+proc-macro2 = "1.0.56"
 
 [features]
 default = [ "std" ]
diff --git a/substrate/primitives/runtime-interface/proc-macro/Cargo.toml b/substrate/primitives/runtime-interface/proc-macro/Cargo.toml
index 9bc7161012c..3a63c1ef55d 100644
--- a/substrate/primitives/runtime-interface/proc-macro/Cargo.toml
+++ b/substrate/primitives/runtime-interface/proc-macro/Cargo.toml
@@ -18,6 +18,6 @@ proc-macro = true
 [dependencies]
 Inflector = "0.11.4"
 proc-macro-crate = "1.1.3"
-proc-macro2 = "1.0.37"
-quote = "1.0.10"
-syn = { version = "1.0.98", features = ["full", "visit", "fold", "extra-traits"] }
+proc-macro2 = "1.0.56"
+quote = "1.0.26"
+syn = { version = "2.0.14", features = ["full", "visit", "fold", "extra-traits"] }
diff --git a/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs b/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs
index 16c1cffb781..77a29bec380 100644
--- a/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs
+++ b/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs
@@ -36,8 +36,7 @@ use crate::utils::{
 };
 
 use syn::{
-	parse_quote, spanned::Spanned, FnArg, Ident, ItemTrait, Result, Signature, Token,
-	TraitItemMethod,
+	parse_quote, spanned::Spanned, FnArg, Ident, ItemTrait, Result, Signature, Token, TraitItemFn,
 };
 
 use proc_macro2::{Span, TokenStream};
@@ -116,7 +115,7 @@ fn function_no_std_impl(
 		quote! {}
 	};
 
-	let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
+	let attrs = method.attrs.iter().filter(|a| !a.path().is_ident("version"));
 
 	let cfg_wasm_only = if is_wasm_only {
 		quote! { #[cfg(target_arch = "wasm32")] }
@@ -139,12 +138,12 @@ fn function_no_std_impl(
 /// Generate call to latest function version for `cfg((feature = "std")`
 ///
 /// This should generate simple `fn func(..) { func_version_<latest_version>(..) }`.
-fn function_std_latest_impl(method: &TraitItemMethod, latest_version: u32) -> Result<TokenStream> {
+fn function_std_latest_impl(method: &TraitItemFn, latest_version: u32) -> Result<TokenStream> {
 	let function_name = &method.sig.ident;
 	let args = get_function_arguments(&method.sig).map(FnArg::Typed);
 	let arg_names = get_function_argument_names(&method.sig).collect::<Vec<_>>();
 	let return_value = &method.sig.output;
-	let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
+	let attrs = method.attrs.iter().filter(|a| !a.path().is_ident("version"));
 	let latest_function_name =
 		create_function_ident_with_version(&method.sig.ident, latest_version);
 
@@ -162,7 +161,7 @@ fn function_std_latest_impl(method: &TraitItemMethod, latest_version: u32) -> Re
 /// Generates the bare function implementation for `cfg(feature = "std")`.
 fn function_std_impl(
 	trait_name: &Ident,
-	method: &TraitItemMethod,
+	method: &TraitItemFn,
 	version: u32,
 	is_wasm_only: bool,
 	tracing: bool,
@@ -185,7 +184,7 @@ fn function_std_impl(
 		.take(1),
 	);
 	let return_value = &method.sig.output;
-	let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
+	let attrs = method.attrs.iter().filter(|a| !a.path().is_ident("version"));
 	// Don't make the function public accessible when this is a wasm only interface.
 	let call_to_trait = generate_call_to_trait(trait_name, method, version, is_wasm_only);
 	let call_to_trait = if !tracing {
@@ -210,7 +209,7 @@ fn function_std_impl(
 /// Generate the call to the interface trait.
 fn generate_call_to_trait(
 	trait_name: &Ident,
-	method: &TraitItemMethod,
+	method: &TraitItemFn,
 	version: u32,
 	is_wasm_only: bool,
 ) -> TokenStream {
diff --git a/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs b/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs
index fb751c69bc8..f3cdcf7fd54 100644
--- a/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs
+++ b/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs
@@ -30,7 +30,7 @@ use crate::utils::{
 };
 
 use syn::{
-	spanned::Spanned, Error, Ident, ItemTrait, Pat, Result, ReturnType, Signature, TraitItemMethod,
+	spanned::Spanned, Error, Ident, ItemTrait, Pat, Result, ReturnType, Signature, TraitItemFn,
 };
 
 use proc_macro2::{Span, TokenStream};
@@ -78,7 +78,7 @@ pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream
 
 /// Generate the extern host function for the given method.
 fn generate_extern_host_function(
-	method: &TraitItemMethod,
+	method: &TraitItemFn,
 	version: u32,
 	trait_name: &Ident,
 ) -> Result<TokenStream> {
@@ -136,7 +136,7 @@ fn generate_extern_host_function(
 }
 
 /// Generate the host exchangeable function for the given method.
-fn generate_exchangeable_host_function(method: &TraitItemMethod) -> Result<TokenStream> {
+fn generate_exchangeable_host_function(method: &TraitItemFn) -> Result<TokenStream> {
 	let crate_ = generate_crate_access();
 	let arg_types = get_function_argument_types(&method.sig);
 	let function = &method.sig.ident;
diff --git a/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs b/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs
index 4a3a688e5c3..540e930b0c1 100644
--- a/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs
+++ b/substrate/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs
@@ -26,7 +26,7 @@ use crate::utils::{
 use syn::{
 	fold::{self, Fold},
 	spanned::Spanned,
-	Error, Generics, ItemTrait, Receiver, Result, TraitItemMethod, Type, Visibility,
+	Error, Generics, ItemTrait, Receiver, Result, TraitItemFn, Type, Visibility,
 };
 
 use proc_macro2::TokenStream;
@@ -51,7 +51,7 @@ pub fn process(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream>
 struct ToEssentialTraitDef {
 	/// All errors found while doing the conversion.
 	errors: Vec<Error>,
-	methods: Vec<TraitItemMethod>,
+	methods: Vec<TraitItemFn>,
 }
 
 impl ToEssentialTraitDef {
@@ -59,7 +59,7 @@ impl ToEssentialTraitDef {
 		ToEssentialTraitDef { errors: vec![], methods: vec![] }
 	}
 
-	fn into_methods(self) -> Result<Vec<TraitItemMethod>> {
+	fn into_methods(self) -> Result<Vec<TraitItemFn>> {
 		let mut errors = self.errors;
 		let methods = self.methods;
 		if let Some(first_error) = errors.pop() {
@@ -72,8 +72,8 @@ impl ToEssentialTraitDef {
 		}
 	}
 
-	fn process(&mut self, method: &TraitItemMethod, version: u32) {
-		let mut folded = self.fold_trait_item_method(method.clone());
+	fn process(&mut self, method: &TraitItemFn, version: u32) {
+		let mut folded = self.fold_trait_item_fn(method.clone());
 		folded.sig.ident = create_function_ident_with_version(&folded.sig.ident, version);
 		self.methods.push(folded);
 	}
@@ -90,7 +90,7 @@ impl ToEssentialTraitDef {
 }
 
 impl Fold for ToEssentialTraitDef {
-	fn fold_trait_item_method(&mut self, mut method: TraitItemMethod) -> TraitItemMethod {
+	fn fold_trait_item_fn(&mut self, mut method: TraitItemFn) -> TraitItemFn {
 		if method.default.take().is_none() {
 			self.push_error(&method, "Methods need to have an implementation.");
 		}
@@ -105,9 +105,9 @@ impl Fold for ToEssentialTraitDef {
 
 		self.error_on_generic_parameters(&method.sig.generics);
 
-		method.attrs.retain(|a| !a.path.is_ident("version"));
+		method.attrs.retain(|a| !a.path().is_ident("version"));
 
-		fold::fold_trait_item_method(self, method)
+		fold::fold_trait_item_fn(self, method)
 	}
 
 	fn fold_item_trait(&mut self, mut trait_def: ItemTrait) -> ItemTrait {
@@ -154,7 +154,7 @@ fn impl_trait_for_externalities(trait_def: &ItemTrait, is_wasm_only: bool) -> Re
 	let interface = get_runtime_interface(trait_def)?;
 	let methods = interface.all_versions().map(|(version, method)| {
 		let mut cloned = (*method).clone();
-		cloned.attrs.retain(|a| !a.path.is_ident("version"));
+		cloned.attrs.retain(|a| !a.path().is_ident("version"));
 		cloned.sig.ident = create_function_ident_with_version(&cloned.sig.ident, version);
 		cloned
 	});
diff --git a/substrate/primitives/runtime-interface/proc-macro/src/utils.rs b/substrate/primitives/runtime-interface/proc-macro/src/utils.rs
index 07f9b5ce098..9818fd6842a 100644
--- a/substrate/primitives/runtime-interface/proc-macro/src/utils.rs
+++ b/substrate/primitives/runtime-interface/proc-macro/src/utils.rs
@@ -21,7 +21,7 @@ use proc_macro2::{Span, TokenStream};
 
 use syn::{
 	parse::Parse, parse_quote, spanned::Spanned, token, Error, FnArg, Ident, ItemTrait, LitInt,
-	Pat, PatType, Result, Signature, TraitItem, TraitItemMethod, Type,
+	Pat, PatType, Result, Signature, TraitItem, TraitItemFn, Type,
 };
 
 use proc_macro_crate::{crate_name, FoundCrate};
@@ -41,23 +41,23 @@ mod attributes {
 
 /// A concrete, specific version of a runtime interface function.
 pub struct RuntimeInterfaceFunction {
-	item: TraitItemMethod,
+	item: TraitItemFn,
 	should_trap_on_return: bool,
 }
 
 impl std::ops::Deref for RuntimeInterfaceFunction {
-	type Target = TraitItemMethod;
+	type Target = TraitItemFn;
 	fn deref(&self) -> &Self::Target {
 		&self.item
 	}
 }
 
 impl RuntimeInterfaceFunction {
-	fn new(item: &TraitItemMethod) -> Result<Self> {
+	fn new(item: &TraitItemFn) -> Result<Self> {
 		let mut item = item.clone();
 		let mut should_trap_on_return = false;
 		item.attrs.retain(|attr| {
-			if attr.path.is_ident("trap_on_return") {
+			if attr.path().is_ident("trap_on_return") {
 				should_trap_on_return = true;
 				false
 			} else {
@@ -87,7 +87,7 @@ struct RuntimeInterfaceFunctionSet {
 }
 
 impl RuntimeInterfaceFunctionSet {
-	fn new(version: VersionAttribute, trait_item: &TraitItemMethod) -> Result<Self> {
+	fn new(version: VersionAttribute, trait_item: &TraitItemFn) -> Result<Self> {
 		Ok(Self {
 			latest_version_to_call: version.is_callable().then(|| version.version),
 			versions: BTreeMap::from([(
@@ -115,11 +115,7 @@ impl RuntimeInterfaceFunctionSet {
 	}
 
 	/// Add a different version of the function.
-	fn add_version(
-		&mut self,
-		version: VersionAttribute,
-		trait_item: &TraitItemMethod,
-	) -> Result<()> {
+	fn add_version(&mut self, version: VersionAttribute, trait_item: &TraitItemFn) -> Result<()> {
 		if let Some(existing_item) = self.versions.get(&version.version) {
 			let mut err = Error::new(trait_item.span(), "Duplicated version attribute");
 			err.combine(Error::new(
@@ -275,9 +271,9 @@ pub fn get_function_argument_types_ref_and_mut(
 }
 
 /// Returns an iterator over all trait methods for the given trait definition.
-fn get_trait_methods(trait_def: &ItemTrait) -> impl Iterator<Item = &TraitItemMethod> {
+fn get_trait_methods(trait_def: &ItemTrait) -> impl Iterator<Item = &TraitItemFn> {
 	trait_def.items.iter().filter_map(|i| match i {
-		TraitItem::Method(ref method) => Some(method),
+		TraitItem::Fn(ref method) => Some(method),
 		_ => None,
 	})
 }
@@ -326,10 +322,10 @@ impl Parse for VersionAttribute {
 }
 
 /// Return [`VersionAttribute`], if present.
-fn get_item_version(item: &TraitItemMethod) -> Result<Option<VersionAttribute>> {
+fn get_item_version(item: &TraitItemFn) -> Result<Option<VersionAttribute>> {
 	item.attrs
 		.iter()
-		.find(|attr| attr.path.is_ident("version"))
+		.find(|attr| attr.path().is_ident("version"))
 		.map(|attr| attr.parse_args())
 		.transpose()
 }
diff --git a/substrate/primitives/version/proc-macro/Cargo.toml b/substrate/primitives/version/proc-macro/Cargo.toml
index abe9e579a20..aac41dd43dd 100644
--- a/substrate/primitives/version/proc-macro/Cargo.toml
+++ b/substrate/primitives/version/proc-macro/Cargo.toml
@@ -17,9 +17,9 @@ proc-macro = true
 
 [dependencies]
 codec = { package = "parity-scale-codec", version = "3.2.2", features = [ "derive" ] }
-proc-macro2 = "1.0.37"
-quote = "1.0.10"
-syn = { version = "1.0.98", features = ["full", "fold", "extra-traits", "visit"] }
+proc-macro2 = "1.0.56"
+quote = "1.0.26"
+syn = { version = "2.0.14", features = ["full", "fold", "extra-traits", "visit"] }
 
 [dev-dependencies]
 sp-version = { version = "5.0.0", path = ".." }
diff --git a/substrate/test-utils/derive/Cargo.toml b/substrate/test-utils/derive/Cargo.toml
index b55ace822ce..f3e38ada2b3 100644
--- a/substrate/test-utils/derive/Cargo.toml
+++ b/substrate/test-utils/derive/Cargo.toml
@@ -11,9 +11,9 @@ publish = false
 
 [dependencies]
 proc-macro-crate = "1.1.3"
-proc-macro2 = "1.0.37"
-quote = "1.0.10"
-syn = { version = "1.0.98", features = ["full"] }
+proc-macro2 = "1.0.56"
+quote = "1.0.26"
+syn = { version = "2.0.14", features = ["full"] }
 
 [lib]
 proc-macro = true
-- 
GitLab