aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-03-08 01:59:06 +0100
committerDario Nieuwenhuis <[email protected]>2023-03-08 01:59:06 +0100
commita614e697d0ab8f45c59e136ad5015cfdedac50c3 (patch)
tree4b23008751c72cafe82e551ddd68a8d271878049
parentbd4c4209af3738e3b2d6b059670f9ed76e2f32ff (diff)
macros: better validation of function signatures.
Fixes #1266
-rw-r--r--embassy-macros/src/macros/main.rs21
-rw-r--r--embassy-macros/src/macros/task.rs23
2 files changed, 43 insertions, 1 deletions
diff --git a/embassy-macros/src/macros/main.rs b/embassy-macros/src/macros/main.rs
index 18f7c36c4..7af4ef836 100644
--- a/embassy-macros/src/macros/main.rs
+++ b/embassy-macros/src/macros/main.rs
@@ -1,6 +1,7 @@
1use darling::FromMeta; 1use darling::FromMeta;
2use proc_macro2::TokenStream; 2use proc_macro2::TokenStream;
3use quote::quote; 3use quote::quote;
4use syn::{ReturnType, Type};
4 5
5use crate::util::ctxt::Ctxt; 6use crate::util::ctxt::Ctxt;
6 7
@@ -76,6 +77,26 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn, main: TokenStream) -> Resul
76 if !f.sig.generics.params.is_empty() { 77 if !f.sig.generics.params.is_empty() {
77 ctxt.error_spanned_by(&f.sig, "main function must not be generic"); 78 ctxt.error_spanned_by(&f.sig, "main function must not be generic");
78 } 79 }
80 if !f.sig.generics.where_clause.is_none() {
81 ctxt.error_spanned_by(&f.sig, "main function must not have `where` clauses");
82 }
83 if !f.sig.abi.is_none() {
84 ctxt.error_spanned_by(&f.sig, "main function must not have an ABI qualifier");
85 }
86 if !f.sig.variadic.is_none() {
87 ctxt.error_spanned_by(&f.sig, "main function must not be variadic");
88 }
89 match &f.sig.output {
90 ReturnType::Default => {}
91 ReturnType::Type(_, ty) => match &**ty {
92 Type::Tuple(tuple) if tuple.elems.is_empty() => {}
93 Type::Never(_) => {}
94 _ => ctxt.error_spanned_by(
95 &f.sig,
96 "main function must either not return a value, return `()` or return `!`",
97 ),
98 },
99 }
79 100
80 if fargs.len() != 1 { 101 if fargs.len() != 1 {
81 ctxt.error_spanned_by(&f.sig, "main function must have 1 argument: the spawner."); 102 ctxt.error_spanned_by(&f.sig, "main function must have 1 argument: the spawner.");
diff --git a/embassy-macros/src/macros/task.rs b/embassy-macros/src/macros/task.rs
index 90d2cd893..9f30cf43e 100644
--- a/embassy-macros/src/macros/task.rs
+++ b/embassy-macros/src/macros/task.rs
@@ -1,7 +1,7 @@
1use darling::FromMeta; 1use darling::FromMeta;
2use proc_macro2::TokenStream; 2use proc_macro2::TokenStream;
3use quote::{format_ident, quote}; 3use quote::{format_ident, quote};
4use syn::{parse_quote, ItemFn}; 4use syn::{parse_quote, ItemFn, ReturnType, Type};
5 5
6use crate::util::ctxt::Ctxt; 6use crate::util::ctxt::Ctxt;
7 7
@@ -24,6 +24,27 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result<TokenStream, Toke
24 if !f.sig.generics.params.is_empty() { 24 if !f.sig.generics.params.is_empty() {
25 ctxt.error_spanned_by(&f.sig, "task functions must not be generic"); 25 ctxt.error_spanned_by(&f.sig, "task functions must not be generic");
26 } 26 }
27 if !f.sig.generics.where_clause.is_none() {
28 ctxt.error_spanned_by(&f.sig, "task functions must not have `where` clauses");
29 }
30 if !f.sig.abi.is_none() {
31 ctxt.error_spanned_by(&f.sig, "task functions must not have an ABI qualifier");
32 }
33 if !f.sig.variadic.is_none() {
34 ctxt.error_spanned_by(&f.sig, "task functions must not be variadic");
35 }
36 match &f.sig.output {
37 ReturnType::Default => {}
38 ReturnType::Type(_, ty) => match &**ty {
39 Type::Tuple(tuple) if tuple.elems.is_empty() => {}
40 Type::Never(_) => {}
41 _ => ctxt.error_spanned_by(
42 &f.sig,
43 "task functions must either not return a value, return `()` or return `!`",
44 ),
45 },
46 }
47
27 if pool_size < 1 { 48 if pool_size < 1 {
28 ctxt.error_spanned_by(&f.sig, "pool_size must be 1 or greater"); 49 ctxt.error_spanned_by(&f.sig, "pool_size must be 1 or greater");
29 } 50 }