derive_deftly_macros/
compat_syn_2.rs

1//! Definitions for compatibility with syn 2
2//!
3//! This, along with `compat_syn_1.rs` and
4//! [`compat_syn_common`](super::compat_syn_common)
5//! exists to minimise the delta in the commit which switches to syn 2.
6//!
7//! This approach would also allow us to support *both* syn 1 and syn 2,
8//! and correspondingly reduce our MSRV back to 1.54,
9//! eg via cargo features,
10//! if that turns out to be desirable.
11
12// TODO we're committed to syn 2 now, we could maybe remove some of this
13
14use super::prelude::*;
15
16pub use proc_macro2::extra::DelimSpan;
17
18//---------- Spanned ----------
19
20/// Local version of `Spanned`
21///
22/// Works around `Spanned` being sealed in syn 2.
23/// <https://github.com/dtolnay/syn/pull/1524>.
24/// (Not needed with syn 1, but would be harmless there.)
25pub trait Spanned {
26    fn span(&self) -> Span;
27}
28
29impl<T: syn::spanned::Spanned> Spanned for T {
30    fn span(&self) -> Span {
31        syn::spanned::Spanned::span(self)
32    }
33}
34
35//---------- Attribute methods ----------
36
37impl AttributeExt12 for syn::Attribute {
38    fn call_in_parens<T, F>(&self, f: F) -> syn::Result<T>
39    where
40        F: FnOnce(ParseStream<'_>) -> syn::Result<T>,
41    {
42        let list = self.meta.require_list()?;
43        let _paren: syn::token::Paren = match list.delimiter {
44            syn::MacroDelimiter::Paren(p) => p,
45            _ => return Err(list.error("expected parenthesised attributes")),
46        };
47        f.parse2(list.tokens.clone())
48    }
49}