From a614e697d0ab8f45c59e136ad5015cfdedac50c3 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 8 Mar 2023 01:59:06 +0100 Subject: [PATCH] macros: better validation of function signatures. Fixes #1266 --- embassy-macros/src/macros/main.rs | 21 +++++++++++++++++++++ embassy-macros/src/macros/task.rs | 23 ++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/embassy-macros/src/macros/main.rs b/embassy-macros/src/macros/main.rs index 18f7c36c..7af4ef83 100644 --- a/embassy-macros/src/macros/main.rs +++ b/embassy-macros/src/macros/main.rs @@ -1,6 +1,7 @@ use darling::FromMeta; use proc_macro2::TokenStream; use quote::quote; +use syn::{ReturnType, Type}; use crate::util::ctxt::Ctxt; @@ -76,6 +77,26 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn, main: TokenStream) -> Resul if !f.sig.generics.params.is_empty() { ctxt.error_spanned_by(&f.sig, "main function must not be generic"); } + if !f.sig.generics.where_clause.is_none() { + ctxt.error_spanned_by(&f.sig, "main function must not have `where` clauses"); + } + if !f.sig.abi.is_none() { + ctxt.error_spanned_by(&f.sig, "main function must not have an ABI qualifier"); + } + if !f.sig.variadic.is_none() { + ctxt.error_spanned_by(&f.sig, "main function must not be variadic"); + } + match &f.sig.output { + ReturnType::Default => {} + ReturnType::Type(_, ty) => match &**ty { + Type::Tuple(tuple) if tuple.elems.is_empty() => {} + Type::Never(_) => {} + _ => ctxt.error_spanned_by( + &f.sig, + "main function must either not return a value, return `()` or return `!`", + ), + }, + } if fargs.len() != 1 { 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 90d2cd89..9f30cf43 100644 --- a/embassy-macros/src/macros/task.rs +++ b/embassy-macros/src/macros/task.rs @@ -1,7 +1,7 @@ use darling::FromMeta; use proc_macro2::TokenStream; use quote::{format_ident, quote}; -use syn::{parse_quote, ItemFn}; +use syn::{parse_quote, ItemFn, ReturnType, Type}; use crate::util::ctxt::Ctxt; @@ -24,6 +24,27 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result {} + ReturnType::Type(_, ty) => match &**ty { + Type::Tuple(tuple) if tuple.elems.is_empty() => {} + Type::Never(_) => {} + _ => ctxt.error_spanned_by( + &f.sig, + "task functions must either not return a value, return `()` or return `!`", + ), + }, + } + if pool_size < 1 { ctxt.error_spanned_by(&f.sig, "pool_size must be 1 or greater"); }