mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-23 12:12:50 +01:00
Update syn requirement from 1.0.107 to 2.0.48 (#881)
* Update syn requirement from 1.0.107 to 2.0.48 Updates the requirements on [syn](https://github.com/dtolnay/syn) to permit the latest version. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.107...2.0.48) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> * rtic-macros: attr.path -> attr.path() * rtic-macros: tokens -> parse_args() Fix parsing of InitArgs, IdleArgs, *Args Including HardwareTaskArgs, SoftwareTaskArgs * rtic-macros: Rename content to input As syn2 removes the surrounding parenthesis as part of parse_args() the distinction between input and content is redundant * rtic-macros: Handle removal of Expr::Type Manually parse local_resources With type ascription de-RFCd syn2 dropped Expr::Type * rtic-macros: Syn upgrade CHANGELOG * rtic-macro: Retain most old errors as they were Spans are not equal, but good enough * rtic-macros: syn2 changed some error messages Additionally some spans were not retained with the manual parsing workaround * rtic-macros: clippy fixes --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Henrik Tjäder <henrik@tjaders.com>
This commit is contained in:
parent
c630657009
commit
f74f38a4f7
12 changed files with 186 additions and 125 deletions
|
@ -11,6 +11,10 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
|
|||
|
||||
- Unstable ESP32-C3 support.
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgraded from syn 1.x to syn 2.x
|
||||
|
||||
## [v2.0.1] - 2023-07-25
|
||||
|
||||
### Added
|
||||
|
|
|
@ -46,7 +46,7 @@ indexmap = "2.0.0"
|
|||
proc-macro2 = "1.0.49"
|
||||
proc-macro-error = "1.0.4"
|
||||
quote = "1.0.23"
|
||||
syn = { version = "1.0.107", features = ["extra-traits", "full"] }
|
||||
syn = { version = "2.0.48", features = ["extra-traits", "full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
trybuild = "1.0.73"
|
||||
|
|
|
@ -19,7 +19,10 @@ pub fn codegen(app: &App, _analysis: &Analysis) -> TokenStream2 {
|
|||
|
||||
// late resources in `util::link_section_uninit`
|
||||
// unless user specifies custom link section
|
||||
let section = if attrs.iter().any(|attr| attr.path.is_ident("link_section")) {
|
||||
let section = if attrs
|
||||
.iter()
|
||||
.any(|attr| attr.path().is_ident("link_section"))
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(util::link_section_uninit())
|
||||
|
|
|
@ -19,7 +19,10 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
|
|||
|
||||
// late resources in `util::link_section_uninit`
|
||||
// unless user specifies custom link section
|
||||
let section = if attrs.iter().any(|attr| attr.path.is_ident("link_section")) {
|
||||
let section = if attrs
|
||||
.iter()
|
||||
.any(|attr| attr.path().is_ident("link_section"))
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(util::link_section_uninit())
|
||||
|
|
|
@ -8,7 +8,7 @@ mod util;
|
|||
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use syn::{
|
||||
braced, parenthesized,
|
||||
braced,
|
||||
parse::{self, Parse, ParseStream, Parser},
|
||||
token::Brace,
|
||||
Ident, Item, LitInt, Token,
|
||||
|
@ -70,15 +70,12 @@ fn init_args(tokens: TokenStream2) -> parse::Result<InitArgs> {
|
|||
|
||||
let mut local_resources = None;
|
||||
|
||||
let content;
|
||||
parenthesized!(content in input);
|
||||
|
||||
if !content.is_empty() {
|
||||
if !input.is_empty() {
|
||||
loop {
|
||||
// Parse identifier name
|
||||
let ident: Ident = content.parse()?;
|
||||
let ident: Ident = input.parse()?;
|
||||
// Handle equal sign
|
||||
let _: Token![=] = content.parse()?;
|
||||
let _: Token![=] = input.parse()?;
|
||||
|
||||
match &*ident.to_string() {
|
||||
"local" => {
|
||||
|
@ -89,18 +86,18 @@ fn init_args(tokens: TokenStream2) -> parse::Result<InitArgs> {
|
|||
));
|
||||
}
|
||||
|
||||
local_resources = Some(util::parse_local_resources(&content)?);
|
||||
local_resources = Some(util::parse_local_resources(input)?);
|
||||
}
|
||||
_ => {
|
||||
return Err(parse::Error::new(ident.span(), "unexpected argument"));
|
||||
}
|
||||
}
|
||||
|
||||
if content.is_empty() {
|
||||
if input.is_empty() {
|
||||
break;
|
||||
}
|
||||
// Handle comma: ,
|
||||
let _: Token![,] = content.parse()?;
|
||||
let _: Token![,] = input.parse()?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,14 +128,12 @@ fn idle_args(tokens: TokenStream2) -> parse::Result<IdleArgs> {
|
|||
let mut shared_resources = None;
|
||||
let mut local_resources = None;
|
||||
|
||||
let content;
|
||||
parenthesized!(content in input);
|
||||
if !content.is_empty() {
|
||||
if !input.is_empty() {
|
||||
loop {
|
||||
// Parse identifier name
|
||||
let ident: Ident = content.parse()?;
|
||||
let ident: Ident = input.parse()?;
|
||||
// Handle equal sign
|
||||
let _: Token![=] = content.parse()?;
|
||||
let _: Token![=] = input.parse()?;
|
||||
|
||||
match &*ident.to_string() {
|
||||
"shared" => {
|
||||
|
@ -149,7 +144,7 @@ fn idle_args(tokens: TokenStream2) -> parse::Result<IdleArgs> {
|
|||
));
|
||||
}
|
||||
|
||||
shared_resources = Some(util::parse_shared_resources(&content)?);
|
||||
shared_resources = Some(util::parse_shared_resources(input)?);
|
||||
}
|
||||
|
||||
"local" => {
|
||||
|
@ -160,19 +155,19 @@ fn idle_args(tokens: TokenStream2) -> parse::Result<IdleArgs> {
|
|||
));
|
||||
}
|
||||
|
||||
local_resources = Some(util::parse_local_resources(&content)?);
|
||||
local_resources = Some(util::parse_local_resources(input)?);
|
||||
}
|
||||
|
||||
_ => {
|
||||
return Err(parse::Error::new(ident.span(), "unexpected argument"));
|
||||
}
|
||||
}
|
||||
if content.is_empty() {
|
||||
if input.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle comma: ,
|
||||
let _: Token![,] = content.parse()?;
|
||||
let _: Token![,] = input.parse()?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,19 +191,17 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
|||
let mut local_resources = None;
|
||||
let mut prio_span = None;
|
||||
|
||||
let content;
|
||||
parenthesized!(content in input);
|
||||
loop {
|
||||
if content.is_empty() {
|
||||
if input.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
// Parse identifier name
|
||||
let ident: Ident = content.parse()?;
|
||||
let ident: Ident = input.parse()?;
|
||||
let ident_s = ident.to_string();
|
||||
|
||||
// Handle equal sign
|
||||
let _: Token![=] = content.parse()?;
|
||||
let _: Token![=] = input.parse()?;
|
||||
|
||||
match &*ident_s {
|
||||
"binds" => {
|
||||
|
@ -220,7 +213,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
|||
}
|
||||
|
||||
// Parse identifier name
|
||||
let ident = content.parse()?;
|
||||
let ident = input.parse()?;
|
||||
|
||||
binds = Some(ident);
|
||||
}
|
||||
|
@ -234,7 +227,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
|||
}
|
||||
|
||||
// #lit
|
||||
let lit: LitInt = content.parse()?;
|
||||
let lit: LitInt = input.parse()?;
|
||||
|
||||
if !lit.suffix().is_empty() {
|
||||
return Err(parse::Error::new(
|
||||
|
@ -263,7 +256,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
|||
));
|
||||
}
|
||||
|
||||
shared_resources = Some(util::parse_shared_resources(&content)?);
|
||||
shared_resources = Some(util::parse_shared_resources(input)?);
|
||||
}
|
||||
|
||||
"local" => {
|
||||
|
@ -274,7 +267,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
|||
));
|
||||
}
|
||||
|
||||
local_resources = Some(util::parse_local_resources(&content)?);
|
||||
local_resources = Some(util::parse_local_resources(input)?);
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
@ -282,12 +275,12 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
|||
}
|
||||
}
|
||||
|
||||
if content.is_empty() {
|
||||
if input.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle comma: ,
|
||||
let _: Token![,] = content.parse()?;
|
||||
let _: Token![,] = input.parse()?;
|
||||
}
|
||||
let shared_resources = shared_resources.unwrap_or_default();
|
||||
let local_resources = local_resources.unwrap_or_default();
|
||||
|
|
|
@ -198,7 +198,9 @@ impl App {
|
|||
.iter()
|
||||
.position(|attr| util::attr_eq(attr, "init"))
|
||||
{
|
||||
let args = InitArgs::parse(item.attrs.remove(pos).tokens)?;
|
||||
let args = InitArgs::parse(
|
||||
item.attrs.remove(pos).parse_args().unwrap_or_default(),
|
||||
)?;
|
||||
|
||||
// If an init function already exists, error
|
||||
if init.is_some() {
|
||||
|
@ -216,7 +218,9 @@ impl App {
|
|||
.iter()
|
||||
.position(|attr| util::attr_eq(attr, "idle"))
|
||||
{
|
||||
let args = IdleArgs::parse(item.attrs.remove(pos).tokens)?;
|
||||
let args = IdleArgs::parse(
|
||||
item.attrs.remove(pos).parse_args().unwrap_or_default(),
|
||||
)?;
|
||||
|
||||
// If an idle function already exists, error
|
||||
if idle.is_some() {
|
||||
|
@ -243,7 +247,9 @@ impl App {
|
|||
));
|
||||
}
|
||||
|
||||
match syntax_parse::task_args(item.attrs.remove(pos).tokens)? {
|
||||
match syntax_parse::task_args(
|
||||
item.attrs.remove(pos).parse_args().unwrap_or_default(),
|
||||
)? {
|
||||
Either::Left(args) => {
|
||||
check_binding(&args.binds)?;
|
||||
check_ident(&item.sig.ident)?;
|
||||
|
@ -369,8 +375,9 @@ impl App {
|
|||
.iter()
|
||||
.position(|attr| util::attr_eq(attr, "init"))
|
||||
{
|
||||
let args = InitArgs::parse(item.attrs.remove(pos).tokens)?;
|
||||
|
||||
let args = InitArgs::parse(
|
||||
item.attrs.remove(pos).parse_args().unwrap_or_default(),
|
||||
)?;
|
||||
// If an init function already exists, error
|
||||
if init.is_some() {
|
||||
return Err(parse::Error::new(
|
||||
|
@ -387,7 +394,9 @@ impl App {
|
|||
.iter()
|
||||
.position(|attr| util::attr_eq(attr, "idle"))
|
||||
{
|
||||
let args = IdleArgs::parse(item.attrs.remove(pos).tokens)?;
|
||||
let args = IdleArgs::parse(
|
||||
item.attrs.remove(pos).parse_args().unwrap_or_default(),
|
||||
)?;
|
||||
|
||||
// If an idle function already exists, error
|
||||
if idle.is_some() {
|
||||
|
@ -421,7 +430,9 @@ impl App {
|
|||
));
|
||||
}
|
||||
|
||||
match syntax_parse::task_args(item.attrs.remove(pos).tokens)? {
|
||||
match syntax_parse::task_args(
|
||||
item.attrs.remove(pos).parse_args().unwrap_or_default(),
|
||||
)? {
|
||||
Either::Left(args) => {
|
||||
check_binding(&args.binds)?;
|
||||
check_ident(&item.sig.ident)?;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use proc_macro2::TokenStream as TokenStream2;
|
||||
|
||||
use crate::syntax::TokenStream2;
|
||||
use syn::{parse, ForeignItemFn, ItemFn, Stmt};
|
||||
|
||||
use crate::syntax::{
|
||||
|
|
|
@ -3,8 +3,8 @@ use syn::{
|
|||
parse::{self, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
Abi, AttrStyle, Attribute, Expr, FnArg, ForeignItemFn, Ident, ItemFn, Pat, PatType, Path,
|
||||
PathArguments, ReturnType, Token, Type, Visibility,
|
||||
Abi, AttrStyle, Attribute, Expr, ExprPath, FnArg, ForeignItemFn, Ident, ItemFn, Pat, PatType,
|
||||
Path, PathArguments, ReturnType, Token, Type, Visibility,
|
||||
};
|
||||
|
||||
use crate::syntax::{
|
||||
|
@ -20,8 +20,8 @@ pub fn abi_is_rust(abi: &Abi) -> bool {
|
|||
}
|
||||
|
||||
pub fn attr_eq(attr: &Attribute, name: &str) -> bool {
|
||||
attr.style == AttrStyle::Outer && attr.path.segments.len() == 1 && {
|
||||
let segment = attr.path.segments.first().unwrap();
|
||||
attr.style == AttrStyle::Outer && attr.path().segments.len() == 1 && {
|
||||
let segment = attr.path().segments.first().unwrap();
|
||||
segment.arguments == PathArguments::None && *segment.ident.to_string() == *name
|
||||
}
|
||||
}
|
||||
|
@ -143,91 +143,140 @@ fn extract_resource_name_ident(path: Path) -> parse::Result<Ident> {
|
|||
}
|
||||
|
||||
pub fn parse_local_resources(content: ParseStream<'_>) -> parse::Result<LocalResources> {
|
||||
let inner;
|
||||
bracketed!(inner in content);
|
||||
let input;
|
||||
bracketed!(input in content);
|
||||
|
||||
let mut resources = Map::new();
|
||||
|
||||
for e in inner.call(Punctuated::<Expr, Token![,]>::parse_terminated)? {
|
||||
let err = Err(parse::Error::new(
|
||||
e.span(),
|
||||
"identifier appears more than once in list",
|
||||
));
|
||||
let error_msg_no_local_resources =
|
||||
"malformed, expected 'local = [EXPRPATH: TYPE = EXPR]', or 'local = [EXPRPATH, ...]'";
|
||||
|
||||
let (name, local) = match e {
|
||||
// local = [IDENT],
|
||||
Expr::Path(path) => {
|
||||
if !path.attrs.is_empty() {
|
||||
return Err(parse::Error::new(
|
||||
path.span(),
|
||||
"attributes are not supported here",
|
||||
));
|
||||
}
|
||||
loop {
|
||||
if input.is_empty() {
|
||||
break;
|
||||
}
|
||||
// Type ascription is de-RFCd from Rust in
|
||||
// https://github.com/rust-lang/rfcs/pull/3307
|
||||
// Manually pull out the tokens
|
||||
|
||||
let ident = extract_resource_name_ident(path.path)?;
|
||||
// let (cfgs, attrs) = extract_cfgs(path.attrs);
|
||||
// Two acceptable variants:
|
||||
//
|
||||
// Task local and declared (initialized in place)
|
||||
// local = [EXPRPATH: TYPE = EXPR, ...]
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
// or
|
||||
// Task local but not initialized
|
||||
// local = [EXPRPATH, ...],
|
||||
// ~~~~~~~~~
|
||||
|
||||
(ident, TaskLocal::External)
|
||||
}
|
||||
// Common: grab first identifier EXPRPATH
|
||||
// local = [EXPRPATH: TYPE = EXPR, ...]
|
||||
// ~~~~~~~~
|
||||
let exprpath: ExprPath = input.parse()?;
|
||||
|
||||
// local = [IDENT: TYPE = EXPR]
|
||||
Expr::Assign(e) => {
|
||||
let (name, ty, cfgs, attrs) = match *e.left {
|
||||
Expr::Type(t) => {
|
||||
// Extract name and attributes
|
||||
let (name, cfgs, attrs) = match *t.expr {
|
||||
Expr::Path(path) => {
|
||||
let name = extract_resource_name_ident(path.path)?;
|
||||
let FilterAttrs { cfgs, attrs, .. } = filter_attributes(path.attrs);
|
||||
let name = extract_resource_name_ident(exprpath.path)?;
|
||||
|
||||
(name, cfgs, attrs)
|
||||
}
|
||||
_ => return err,
|
||||
};
|
||||
|
||||
let ty = t.ty;
|
||||
|
||||
// Error check
|
||||
match &*ty {
|
||||
Type::Array(_) => {}
|
||||
Type::Path(_) => {}
|
||||
Type::Ptr(_) => {}
|
||||
Type::Tuple(_) => {}
|
||||
_ => return Err(parse::Error::new(
|
||||
ty.span(),
|
||||
"unsupported type, must be an array, tuple, pointer or type path",
|
||||
)),
|
||||
};
|
||||
|
||||
(name, ty, cfgs, attrs)
|
||||
}
|
||||
e => return Err(parse::Error::new(e.span(), "malformed, expected a type")),
|
||||
};
|
||||
|
||||
let expr = e.right; // Expr
|
||||
|
||||
(
|
||||
name,
|
||||
TaskLocal::Declared(Local {
|
||||
attrs,
|
||||
cfgs,
|
||||
ty,
|
||||
expr,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
expr => {
|
||||
return Err(parse::Error::new(
|
||||
expr.span(),
|
||||
"malformed, expected 'IDENT: TYPE = EXPR'",
|
||||
))
|
||||
}
|
||||
// Extract attributes
|
||||
let ExprPath { attrs, .. } = exprpath;
|
||||
let (cfgs, attrs) = {
|
||||
let FilterAttrs { cfgs, attrs, .. } = filter_attributes(attrs);
|
||||
(cfgs, attrs)
|
||||
};
|
||||
|
||||
let local;
|
||||
|
||||
// Declared requries type ascription
|
||||
if input.peek(Token![:]) {
|
||||
// Handle colon
|
||||
let _: Token![:] = input.parse()?;
|
||||
|
||||
// Extract the type
|
||||
let ty: Box<Type> = input.parse()?;
|
||||
|
||||
if input.peek(Token![=]) {
|
||||
// Handle equal sign
|
||||
let _: Token![=] = input.parse()?;
|
||||
} else {
|
||||
return Err(parse::Error::new(
|
||||
name.span(),
|
||||
"malformed, expected 'IDENT: TYPE = EXPR'",
|
||||
));
|
||||
}
|
||||
|
||||
// Grab the final expression right of equal
|
||||
let expr: Box<Expr> = input.parse()?;
|
||||
|
||||
// We got a trailing colon, remove it
|
||||
if input.peek(Token![,]) {
|
||||
let _: Token![,] = input.parse()?;
|
||||
}
|
||||
|
||||
// Error check
|
||||
match &*ty {
|
||||
Type::Array(_) => {}
|
||||
Type::Path(_) => {}
|
||||
Type::Ptr(_) => {}
|
||||
Type::Tuple(_) => {}
|
||||
_ => {
|
||||
return Err(parse::Error::new(
|
||||
ty.span(),
|
||||
"unsupported type, must be an array, tuple, pointer or type path",
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
local = TaskLocal::Declared(Local {
|
||||
attrs,
|
||||
cfgs,
|
||||
ty,
|
||||
expr,
|
||||
});
|
||||
} else if input.peek(Token![=]) {
|
||||
// Missing type ascription is not valid
|
||||
return Err(parse::Error::new(name.span(), "malformed, expected a type"));
|
||||
} else if input.peek(Token![,]) {
|
||||
// Attributes not supported on non-initialized local resources!
|
||||
|
||||
if !attrs.is_empty() {
|
||||
return Err(parse::Error::new(
|
||||
name.span(),
|
||||
"attributes are not supported here",
|
||||
));
|
||||
}
|
||||
|
||||
// Remove comma
|
||||
let _: Token![,] = input.parse()?;
|
||||
|
||||
// Expected when multiple local resources
|
||||
local = TaskLocal::External;
|
||||
} else if input.is_empty() {
|
||||
// There was only one single local resource
|
||||
// Task local but not initialized
|
||||
// local = [EXPRPATH],
|
||||
// ~~~~~~~~
|
||||
local = TaskLocal::External;
|
||||
} else {
|
||||
// Specifying local without any resources is invalid
|
||||
return Err(parse::Error::new(name.span(), error_msg_no_local_resources));
|
||||
};
|
||||
|
||||
if resources.contains_key(&name) {
|
||||
return Err(parse::Error::new(
|
||||
name.span(),
|
||||
"resource appears more than once in list",
|
||||
));
|
||||
}
|
||||
|
||||
resources.insert(name, local);
|
||||
}
|
||||
|
||||
if resources.is_empty() {
|
||||
return Err(parse::Error::new(
|
||||
input.span(),
|
||||
error_msg_no_local_resources,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(resources)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: unexpected end of input, expected one of: `for`, parentheses, `fn`, `unsafe`, `extern`, identifier, `::`, `<`, square brackets, `*`, `&`, `!`, `impl`, `_`, lifetime
|
||||
error: unexpected end of input, expected one of: `for`, parentheses, `fn`, `unsafe`, `extern`, identifier, `::`, `<`, `dyn`, square brackets, `*`, `&`, `!`, `impl`, `_`, lifetime
|
||||
--> ui/local-malformed-1.rs:11:23
|
||||
|
|
||||
11 | #[task(local = [a:])]
|
||||
|
|
|
@ -2,4 +2,4 @@ error: malformed, expected 'IDENT: TYPE = EXPR'
|
|||
--> ui/local-malformed-2.rs:11:21
|
||||
|
|
||||
11 | #[task(local = [a: u32])]
|
||||
| ^^^^^^
|
||||
| ^
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: unexpected end of input, expected expression
|
||||
error: unexpected end of input, expected an expression
|
||||
--> ui/local-malformed-3.rs:11:29
|
||||
|
|
||||
11 | #[task(local = [a: u32 =])]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
error: attributes are not supported here
|
||||
--> ui/local-shared-attribute.rs:17:9
|
||||
--> ui/local-shared-attribute.rs:18:9
|
||||
|
|
||||
17 | / #[test]
|
||||
18 | | b, // Error
|
||||
| |_________^
|
||||
18 | b, // Error
|
||||
| ^
|
||||
|
|
Loading…
Reference in a new issue