Skip to content

Commit 778950b

Browse files
committed
Make types check more flexible
1 parent 2669a19 commit 778950b

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

riscv-rt/macros/src/lib.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ extern crate syn;
1111
use proc_macro2::Span;
1212
use syn::{
1313
parse::{self, Parse},
14+
punctuated::Punctuated,
1415
spanned::Spanned,
15-
FnArg, ItemFn, LitInt, LitStr, PatType, PathArguments, ReturnType, Type, Visibility,
16+
FnArg, ItemFn, LitInt, LitStr, PatType, ReturnType, Type, Visibility,
1617
};
1718

1819
use proc_macro::TokenStream;
@@ -67,10 +68,10 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
6768
.into();
6869
}
6970

70-
fn check_simple_type(argument: &PatType, ty: &str) -> Option<TokenStream> {
71+
fn check_correct_type(argument: &PatType, ty: &str) -> Option<TokenStream> {
7172
let inv_type_message = format!("argument type must be {}", ty);
7273

73-
if !is_simple_type(&argument.ty, ty) {
74+
if !is_correct_type(&argument.ty, ty) {
7475
let error = parse::Error::new(argument.ty.span(), inv_type_message);
7576

7677
Some(error.to_compile_error().into())
@@ -83,7 +84,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
8384
let argument_error = argument_error.to_compile_error().into();
8485

8586
match argument {
86-
FnArg::Typed(argument) => check_simple_type(argument, ty),
87+
FnArg::Typed(argument) => check_correct_type(argument, ty),
8788
FnArg::Receiver(_) => Some(argument_error),
8889
}
8990
}
@@ -101,7 +102,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
101102
}
102103
#[cfg(feature = "u-boot")]
103104
if let Some(argument) = f.sig.inputs.get(1) {
104-
if let Some(message) = check_argument_type(argument, "usize") {
105+
if let Some(message) = check_argument_type(argument, "*const *const c_char") {
105106
return message;
106107
}
107108
}
@@ -151,17 +152,32 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
151152
.into()
152153
}
153154

154-
#[allow(unused)]
155-
fn is_simple_type(ty: &Type, name: &str) -> bool {
156-
if let Type::Path(p) = ty {
157-
if p.qself.is_none() && p.path.leading_colon.is_none() && p.path.segments.len() == 1 {
158-
let segment = p.path.segments.first().unwrap();
159-
if segment.ident == name && segment.arguments == PathArguments::None {
160-
return true;
161-
}
155+
fn strip_type_path(ty: &Type) -> Option<Type> {
156+
match ty {
157+
Type::Ptr(ty) => {
158+
let mut ty = ty.clone();
159+
ty.elem = Box::new(strip_type_path(&ty.elem)?);
160+
Some(Type::Ptr(ty))
162161
}
162+
Type::Path(ty) => {
163+
let mut ty = ty.clone();
164+
let last_segment = ty.path.segments.last().unwrap().clone();
165+
ty.path.segments = Punctuated::new();
166+
ty.path.segments.push_value(last_segment);
167+
Some(Type::Path(ty))
168+
}
169+
_ => None,
170+
}
171+
}
172+
173+
#[allow(unused)]
174+
fn is_correct_type(ty: &Type, name: &str) -> bool {
175+
let correct: Type = syn::parse_str(name).unwrap();
176+
if let Some(ty) = strip_type_path(ty) {
177+
ty == correct
178+
} else {
179+
false
163180
}
164-
false
165181
}
166182

167183
/// Attribute to mark which function will be called at the beginning of the reset handler.

0 commit comments

Comments
 (0)