mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 21:19:35 +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.
|
- Unstable ESP32-C3 support.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Upgraded from syn 1.x to syn 2.x
|
||||||
|
|
||||||
## [v2.0.1] - 2023-07-25
|
## [v2.0.1] - 2023-07-25
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -46,7 +46,7 @@ indexmap = "2.0.0"
|
||||||
proc-macro2 = "1.0.49"
|
proc-macro2 = "1.0.49"
|
||||||
proc-macro-error = "1.0.4"
|
proc-macro-error = "1.0.4"
|
||||||
quote = "1.0.23"
|
quote = "1.0.23"
|
||||||
syn = { version = "1.0.107", features = ["extra-traits", "full"] }
|
syn = { version = "2.0.48", features = ["extra-traits", "full"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
trybuild = "1.0.73"
|
trybuild = "1.0.73"
|
||||||
|
|
|
@ -19,7 +19,10 @@ pub fn codegen(app: &App, _analysis: &Analysis) -> TokenStream2 {
|
||||||
|
|
||||||
// late resources in `util::link_section_uninit`
|
// late resources in `util::link_section_uninit`
|
||||||
// unless user specifies custom link section
|
// 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
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(util::link_section_uninit())
|
Some(util::link_section_uninit())
|
||||||
|
|
|
@ -19,7 +19,10 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
|
||||||
|
|
||||||
// late resources in `util::link_section_uninit`
|
// late resources in `util::link_section_uninit`
|
||||||
// unless user specifies custom link section
|
// 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
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(util::link_section_uninit())
|
Some(util::link_section_uninit())
|
||||||
|
|
|
@ -8,7 +8,7 @@ mod util;
|
||||||
|
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
use syn::{
|
use syn::{
|
||||||
braced, parenthesized,
|
braced,
|
||||||
parse::{self, Parse, ParseStream, Parser},
|
parse::{self, Parse, ParseStream, Parser},
|
||||||
token::Brace,
|
token::Brace,
|
||||||
Ident, Item, LitInt, Token,
|
Ident, Item, LitInt, Token,
|
||||||
|
@ -70,15 +70,12 @@ fn init_args(tokens: TokenStream2) -> parse::Result<InitArgs> {
|
||||||
|
|
||||||
let mut local_resources = None;
|
let mut local_resources = None;
|
||||||
|
|
||||||
let content;
|
if !input.is_empty() {
|
||||||
parenthesized!(content in input);
|
|
||||||
|
|
||||||
if !content.is_empty() {
|
|
||||||
loop {
|
loop {
|
||||||
// Parse identifier name
|
// Parse identifier name
|
||||||
let ident: Ident = content.parse()?;
|
let ident: Ident = input.parse()?;
|
||||||
// Handle equal sign
|
// Handle equal sign
|
||||||
let _: Token![=] = content.parse()?;
|
let _: Token![=] = input.parse()?;
|
||||||
|
|
||||||
match &*ident.to_string() {
|
match &*ident.to_string() {
|
||||||
"local" => {
|
"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"));
|
return Err(parse::Error::new(ident.span(), "unexpected argument"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if content.is_empty() {
|
if input.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Handle comma: ,
|
// 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 shared_resources = None;
|
||||||
let mut local_resources = None;
|
let mut local_resources = None;
|
||||||
|
|
||||||
let content;
|
if !input.is_empty() {
|
||||||
parenthesized!(content in input);
|
|
||||||
if !content.is_empty() {
|
|
||||||
loop {
|
loop {
|
||||||
// Parse identifier name
|
// Parse identifier name
|
||||||
let ident: Ident = content.parse()?;
|
let ident: Ident = input.parse()?;
|
||||||
// Handle equal sign
|
// Handle equal sign
|
||||||
let _: Token![=] = content.parse()?;
|
let _: Token![=] = input.parse()?;
|
||||||
|
|
||||||
match &*ident.to_string() {
|
match &*ident.to_string() {
|
||||||
"shared" => {
|
"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" => {
|
"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"));
|
return Err(parse::Error::new(ident.span(), "unexpected argument"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if content.is_empty() {
|
if input.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle comma: ,
|
// 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 local_resources = None;
|
||||||
let mut prio_span = None;
|
let mut prio_span = None;
|
||||||
|
|
||||||
let content;
|
|
||||||
parenthesized!(content in input);
|
|
||||||
loop {
|
loop {
|
||||||
if content.is_empty() {
|
if input.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse identifier name
|
// Parse identifier name
|
||||||
let ident: Ident = content.parse()?;
|
let ident: Ident = input.parse()?;
|
||||||
let ident_s = ident.to_string();
|
let ident_s = ident.to_string();
|
||||||
|
|
||||||
// Handle equal sign
|
// Handle equal sign
|
||||||
let _: Token![=] = content.parse()?;
|
let _: Token![=] = input.parse()?;
|
||||||
|
|
||||||
match &*ident_s {
|
match &*ident_s {
|
||||||
"binds" => {
|
"binds" => {
|
||||||
|
@ -220,7 +213,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse identifier name
|
// Parse identifier name
|
||||||
let ident = content.parse()?;
|
let ident = input.parse()?;
|
||||||
|
|
||||||
binds = Some(ident);
|
binds = Some(ident);
|
||||||
}
|
}
|
||||||
|
@ -234,7 +227,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
||||||
}
|
}
|
||||||
|
|
||||||
// #lit
|
// #lit
|
||||||
let lit: LitInt = content.parse()?;
|
let lit: LitInt = input.parse()?;
|
||||||
|
|
||||||
if !lit.suffix().is_empty() {
|
if !lit.suffix().is_empty() {
|
||||||
return Err(parse::Error::new(
|
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" => {
|
"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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle comma: ,
|
// Handle comma: ,
|
||||||
let _: Token![,] = content.parse()?;
|
let _: Token![,] = input.parse()?;
|
||||||
}
|
}
|
||||||
let shared_resources = shared_resources.unwrap_or_default();
|
let shared_resources = shared_resources.unwrap_or_default();
|
||||||
let local_resources = local_resources.unwrap_or_default();
|
let local_resources = local_resources.unwrap_or_default();
|
||||||
|
|
|
@ -198,7 +198,9 @@ impl App {
|
||||||
.iter()
|
.iter()
|
||||||
.position(|attr| util::attr_eq(attr, "init"))
|
.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 an init function already exists, error
|
||||||
if init.is_some() {
|
if init.is_some() {
|
||||||
|
@ -216,7 +218,9 @@ impl App {
|
||||||
.iter()
|
.iter()
|
||||||
.position(|attr| util::attr_eq(attr, "idle"))
|
.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 an idle function already exists, error
|
||||||
if idle.is_some() {
|
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) => {
|
Either::Left(args) => {
|
||||||
check_binding(&args.binds)?;
|
check_binding(&args.binds)?;
|
||||||
check_ident(&item.sig.ident)?;
|
check_ident(&item.sig.ident)?;
|
||||||
|
@ -369,8 +375,9 @@ impl App {
|
||||||
.iter()
|
.iter()
|
||||||
.position(|attr| util::attr_eq(attr, "init"))
|
.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 an init function already exists, error
|
||||||
if init.is_some() {
|
if init.is_some() {
|
||||||
return Err(parse::Error::new(
|
return Err(parse::Error::new(
|
||||||
|
@ -387,7 +394,9 @@ impl App {
|
||||||
.iter()
|
.iter()
|
||||||
.position(|attr| util::attr_eq(attr, "idle"))
|
.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 an idle function already exists, error
|
||||||
if idle.is_some() {
|
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) => {
|
Either::Left(args) => {
|
||||||
check_binding(&args.binds)?;
|
check_binding(&args.binds)?;
|
||||||
check_ident(&item.sig.ident)?;
|
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 syn::{parse, ForeignItemFn, ItemFn, Stmt};
|
||||||
|
|
||||||
use crate::syntax::{
|
use crate::syntax::{
|
||||||
|
|
|
@ -3,8 +3,8 @@ use syn::{
|
||||||
parse::{self, ParseStream},
|
parse::{self, ParseStream},
|
||||||
punctuated::Punctuated,
|
punctuated::Punctuated,
|
||||||
spanned::Spanned,
|
spanned::Spanned,
|
||||||
Abi, AttrStyle, Attribute, Expr, FnArg, ForeignItemFn, Ident, ItemFn, Pat, PatType, Path,
|
Abi, AttrStyle, Attribute, Expr, ExprPath, FnArg, ForeignItemFn, Ident, ItemFn, Pat, PatType,
|
||||||
PathArguments, ReturnType, Token, Type, Visibility,
|
Path, PathArguments, ReturnType, Token, Type, Visibility,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::syntax::{
|
use crate::syntax::{
|
||||||
|
@ -20,8 +20,8 @@ pub fn abi_is_rust(abi: &Abi) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attr_eq(attr: &Attribute, name: &str) -> bool {
|
pub fn attr_eq(attr: &Attribute, name: &str) -> bool {
|
||||||
attr.style == AttrStyle::Outer && attr.path.segments.len() == 1 && {
|
attr.style == AttrStyle::Outer && attr.path().segments.len() == 1 && {
|
||||||
let segment = attr.path.segments.first().unwrap();
|
let segment = attr.path().segments.first().unwrap();
|
||||||
segment.arguments == PathArguments::None && *segment.ident.to_string() == *name
|
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> {
|
pub fn parse_local_resources(content: ParseStream<'_>) -> parse::Result<LocalResources> {
|
||||||
let inner;
|
let input;
|
||||||
bracketed!(inner in content);
|
bracketed!(input in content);
|
||||||
|
|
||||||
let mut resources = Map::new();
|
let mut resources = Map::new();
|
||||||
|
|
||||||
for e in inner.call(Punctuated::<Expr, Token![,]>::parse_terminated)? {
|
let error_msg_no_local_resources =
|
||||||
let err = Err(parse::Error::new(
|
"malformed, expected 'local = [EXPRPATH: TYPE = EXPR]', or 'local = [EXPRPATH, ...]'";
|
||||||
e.span(),
|
|
||||||
"identifier appears more than once in list",
|
|
||||||
));
|
|
||||||
|
|
||||||
let (name, local) = match e {
|
loop {
|
||||||
// local = [IDENT],
|
if input.is_empty() {
|
||||||
Expr::Path(path) => {
|
break;
|
||||||
if !path.attrs.is_empty() {
|
}
|
||||||
return Err(parse::Error::new(
|
// Type ascription is de-RFCd from Rust in
|
||||||
path.span(),
|
// https://github.com/rust-lang/rfcs/pull/3307
|
||||||
"attributes are not supported here",
|
// Manually pull out the tokens
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let ident = extract_resource_name_ident(path.path)?;
|
// Two acceptable variants:
|
||||||
// let (cfgs, attrs) = extract_cfgs(path.attrs);
|
//
|
||||||
|
// 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]
|
let name = extract_resource_name_ident(exprpath.path)?;
|
||||||
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);
|
|
||||||
|
|
||||||
(name, cfgs, attrs)
|
// Extract attributes
|
||||||
}
|
let ExprPath { attrs, .. } = exprpath;
|
||||||
_ => return err,
|
let (cfgs, attrs) = {
|
||||||
};
|
let FilterAttrs { cfgs, attrs, .. } = filter_attributes(attrs);
|
||||||
|
(cfgs, attrs)
|
||||||
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'",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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);
|
resources.insert(name, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resources.is_empty() {
|
||||||
|
return Err(parse::Error::new(
|
||||||
|
input.span(),
|
||||||
|
error_msg_no_local_resources,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(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
|
--> ui/local-malformed-1.rs:11:23
|
||||||
|
|
|
|
||||||
11 | #[task(local = [a:])]
|
11 | #[task(local = [a:])]
|
||||||
|
|
|
@ -2,4 +2,4 @@ error: malformed, expected 'IDENT: TYPE = EXPR'
|
||||||
--> ui/local-malformed-2.rs:11:21
|
--> ui/local-malformed-2.rs:11:21
|
||||||
|
|
|
|
||||||
11 | #[task(local = [a: u32])]
|
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
|
--> ui/local-malformed-3.rs:11:29
|
||||||
|
|
|
|
||||||
11 | #[task(local = [a: u32 =])]
|
11 | #[task(local = [a: u32 =])]
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
error: attributes are not supported here
|
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